> For the complete documentation index, see [llms.txt](https://docs.talus.network/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.talus.network/talus-docs-v2.1.0/faq/03-authoring.md).

# Authoring Tools and Workflows

{% hint style="info" %}
**Audience:** Nexus adopters and integrators.

**Goal:** Answer practical Tool and workflow authoring questions so you can choose the right contract, registration path, and safe next step.
{% endhint %}

This page is for tool providers and agent developers building the pieces a skill runs. Answers are grounded in the documented contracts; command snippets are illustrative (they show what a command looks like, not a prescriptive procedure).

#### Building a tool

**What kinds of tool can I build?**

Two: an **off-chain tool** and an **on-chain tool**.

* An **off-chain tool** is an HTTP service. The leader invokes it over the network. Use this for anything that reaches outside the chain — calling an API, running a model, doing arbitrary computation.
* An **on-chain tool** is a Move module published on Sui. The leader invokes it by making a Move call. Use this when the step must read or mutate on-chain state atomically as part of the workflow.

Both are named by a fully qualified name (FQN) and registered on-chain before a DAG can call them.

**What is an FQN?**

A fully qualified name identifies a tool. It has three parts — domain, name, and version — written `{domain}.{name}@{version}`, for example:

```
com.example.add@1
```

The registration process validates this structure. A DAG vertex names the tool it calls by FQN.

**What HTTP endpoints must an off-chain tool expose?**

Three, all under the tool's base URL:

```
GET  /health   → 200 only when the tool is ready to be invoked
GET  /meta     → returns the tool's definition JSON
POST /invoke   → runs the tool: accepts input in the tool's input schema,
                 returns output in the tool's output schema
```

The definition returned by `/meta` (and stored on-chain at registration) carries the FQN, the type (`offchain` or `onchain`), the URL, a description, and JSON Schema (draft 2020-12) definitions for the input and the output. The output schema's top-level `oneOf` enforces the exclusive output variants the DAG expects — every output is one tagged variant (for example `ok` or `err`), each with its own fields.

**How does an on-chain tool's `execute` function have to look?**

An on-chain tool is a Move module that provides a public, non-entry `execute` function. It receives owned UID requirements and a result object, does its work, builds a tagged output, and finalizes that output into the result — the function returns nothing. A minimal shape, matching the LTS scaffold:

```
public fun execute(
    requirements: UIDRequirements,
    result: OnchainToolResult,
    state: &mut ToolState,
    count: u64,
    ctx: &mut TxContext,
) {
    let mut requirements = requirements;
    satisfy_tool_requirement(&mut requirements, state);

    let output = tagged_output::new(b"ok")
        .with_named_payload(b"count", data::inline_data_value(count.to_string().into_bytes()));

    onchain_tool_result::finalize_and_share(result, requirements, output, ctx);
}
```

Three requirements make it valid:

1. **Satisfy requirements.** The tool satisfies `UIDRequirements` with its registered witness before finalizing the result.
2. **Build a `TaggedOutput`.** Construct the result with `tagged_output::new(tag)` and attach `NexusValue` payloads with `with_named_payload`. Use `data::inline_data_value` with canonical JSON bytes: numbers are unquoted and strings or addresses are quoted. The tag names the output variant (`ok`, `err`, or a custom one such as `timeout`).
3. **Finalize, don't return.** Call `onchain_tool_result::finalize_and_share(result, requirements, output, ctx)` — this consumes the result object and shares it so the leader can pick it up. The function must not return a value.

A custody-touching on-chain tool (one that spends or moves an agent's or user's assets) additionally needs an on-chain authorization grant tying the call to the right agent and vertex — that mechanism is explained on the [authorization page](/talus-docs-v2.1.0/faq/05-authorization.md).

**How do I register a tool?**

Registration puts the tool's definition on-chain so DAGs can reference it. The CLI drives it, dispatching by tool type:

```
nexus tool register offchain --url https://my-tool.example.com ...
nexus tool register onchain  ...
nexus tool validate offchain --url https://my-tool.example.com
```

`nexus tool validate onchain --ident <fqn>` validates a registered on-chain Tool's live `execute` and `Output` schemas against its stored `MetaSchema`, and checks whether its Standard or WorkflowAuthorization mode matches the live signature. It returns the Tool state (or `{valid:true,fqn,tool}` with `--json`). It does not prove lineage, UpgradeCap custody, dependency linkage, witness ownership, or business invariants; use the [on-chain Tool candidate-verification checklist](/talus-docs-v2.1.0/guides/tool-development/build-onchain-tool-vertex-and-upgrade.md#verify-the-candidate) for those separate checks.

You can scaffold a new tool from a template (`nexus tool new`), inspect a Tool by its known FQN (`nexus tool inspect --tool-fqn <FQN>`), set a per-invocation cost (`nexus tool set-invocation-cost`), unregister (`nexus tool unregister`), and later claim back the collateral a registration locks (`nexus tool claim-collateral --tool-fqn <FQN> --owner-cap <OVER_TOOL_CAP_ID>`). Registering a Tool locks Talus `US` from `Coin<US>`; owner collateral claims wait until that Tool's `unregistered_at_ms` plus its registration or re-registration `lock_duration_ms` snapshot, while an authorized admin slash is immediate and retires an active Tool when remaining collateral falls below the configured registry requirement. SUI is separate transaction gas and execution-payment funding; the [verification page](/talus-docs-v2.1.0/faq/06-verification.md) covers why collateral exists.

**Building a workflow**

**What is a DAG, and how do I get from a DAG to a runnable skill?**

A DAG is the graph of tool-call steps a skill runs: vertices are tool calls (each naming a tool FQN and being on-chain or off-chain), edges carry one vertex's output port into another vertex's input port, and entry ports are the inputs you supply to start a run. You author the DAG as a JSON file, validate and publish it, then bind it to an agent's skill:

```
nexus dag validate --path ./my-dag.json
nexus dag publish --path ./my-dag.json
nexus tap default-agent show --json
nexus task schedule --dag-id <object-id> --input-json '{ ... }' --prepay-amount-mist <mist> --occurrence-budget-mist <mist> --now
```

The default-DAG schedule requires an operator-provisioned default Agent and executor. If the preflight reports `AgentRegistry missing default agent` or `EDefaultDagExecutorMissing`, stop and hand the deployment to its operator; do not infer that missing dispatch is a permanent rejection or bootstrap the shared executor from this FAQ.

For package-backed agents, the `nexus tap` flow scaffolds a user-created package and a DAG-backed skill config, publishes them together, and registers the skill on an agent:

```
Conceptual Talus Agent Package (TAP) sequence: scaffold a package, validate a skill config, publish an artifact, create an Agent, then register the artifact with that Agent. Use the [TAP CLI reference](../reference/cli/tap.md) for required `--config`, `--artifact`, `--agent-id`, and transaction flags.
nexus task schedule --agent-id <object-id> --skill-id <u64> --prepay-amount-mist <mist> --occurrence-budget-mist <mist> --now
```

Once a skill is bound to a published DAG, scheduling an occurrence dispatches an Execution that walks the DAG. Observe it with `nexus task occurrence inspect` and `nexus execution inspect`.

**What edge kinds can a DAG use?**

Edges carry data between vertices, and their kind controls loop and fan-out behavior. There are six:

* **Normal** — a plain edge: one vertex's output feeds the next vertex's input.
* **ForEach** — fans out over each element of a multi-valued output, running the downstream vertex once per element.
* **Collect** — the inverse of ForEach: gathers multiple same-typed values back into a single multi-valued input.
* **DoWhile** — creates a pseudo-loop in the DAG, letting a section repeat.
* **Break** — exits a DoWhile loop.
* **Static** — feeds a value from outside a loop into a looped vertex (for example, a constant that every iteration reads).

**What happens when a step fails?**

An ordinary selected output variant with no matching outgoing edge is a successful terminal end state and emits `EndStateReachedEvent`. `_err_eval`, or terminal failure evidence with no routed continuation, follows the configured post-failure action. There are two actions, settable DAG-wide and overridable per vertex:

* **Terminate** — stop the whole execution; the remaining work is useless without this step.
* **TransientContinue** — keep executing the other walks, which may still complete independently.

A vertex can also legitimately produce an *error variant* (an output tagged `err`) instead of aborting — that is a normal, typed output that flows down an edge to the next vertex, distinct from a resolution failure. Design tools to return an `err` variant when the downstream graph should react to the error, and reserve aborting for truly unrecoverable states.

***

**Where do I go next?**

* [Concepts](/talus-docs-v2.1.0/faq/02-concepts.md) — the agent / skill / tool / workflow / task vocabulary these steps assume.
* [Authorization](/talus-docs-v2.1.0/faq/05-authorization.md) — the on-chain grant a custody-touching tool needs, and signed HTTP for off-chain tools.
* [Payments](/talus-docs-v2.1.0/faq/04-payments.md) — how each step's cost is budgeted and settled.
* Build guides — [an off-chain tool](/talus-docs-v2.1.0/guides/tool-development/build-offchain-tool.md), [an on-chain tool](/talus-docs-v2.1.0/guides/tool-development/build-onchain-tool.md), [an agent package](/talus-docs-v2.1.0/guides/agent-usage/build-agent-package.md), and [registering a skill package](/talus-docs-v2.1.0/guides/agent-usage/register-skill-package.md).
* Reference — the [`dag`](/talus-docs-v2.1.0/reference/move/nexus_interface/dag.md) and [`graph`](/talus-docs-v2.1.0/reference/move/nexus_interface/graph.md) Move pages for exact edge and vertex types, the [`tagged_output`](/talus-docs-v2.1.0/reference/move/nexus_primitives/tagged_output.md) page for the on-chain output shape, and the [`tool`](/talus-docs-v2.1.0/reference/cli/tool.md) and [`dag`](/talus-docs-v2.1.0/reference/cli/dag.md) CLI pages for command flags.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.talus.network/talus-docs-v2.1.0/faq/03-authoring.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `build a script that syncs our docs to a CMS` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
