DAG Orchestration Client Specification
Scope
Thin operational HTTP client and response contracts for Robota DAG orchestration endpoints.
This package is consumed by command-line and MCP clients that call a DAG orchestration HTTP server (e.g. @robota-sdk/dag-runtime-server).
Boundaries
- Does not own DAG domain contracts. Those belong to
@robota-sdk/dag-coreand endpoint-specific domain packages such as@robota-sdk/dag-cost. - Does not own API controller composition. That belongs to
@robota-sdk/dag-api. - Does not own server route implementations. Those belong to the server application (e.g.
@robota-sdk/dag-runtime-server). - Does not render UI or own CLI/MCP command behavior.
Design Decisions
- The client is intentionally thin: it forwards server response payloads without converting them into CLI or MCP-specific output. Consumers own their own command, tool, and output formatting layers.
- Only the general orchestration port is transport-shaped; every other capability has its own
domain owner: cost metadata (
dag-cost), pipeline building (dag-builder), catalog-aware validation, the registered-node catalog, definition reads and lifecycle, and run drafts (dag-core), and run lifecycle (in-process callers). The cost-metadata and run-draft clients validate HTTP payloads and map successes/problems to typed domain results; build, validation, catalog and definition requests stay transport-facing HTTP responses. The general port never requires an HTTP-shaped result from the domain, and in-process frameworks do not implement it or construct HTTP response envelopes. - Remote run cancellation uses the same encoded run identity and server-owned success/problem envelope as creation, start, and reads. A transport success is not inferred from aborting a client-side watcher.
- Asset upload, metadata, and content-download URL methods belong to a transport-specific asset port, not the general orchestration port. In-process consumers use
IAssetStorefromdag-coreinstead. - Binary asset content is intentionally not fetched or buffered by this client. Consumers locate the streaming endpoint via the client and own their transport-specific byte handling and output formatting.
- The fetch implementation is injectable, so tests, CLIs, MCP servers, and alternate runtimes can supply their own fetch-compatible implementation.
- Endpoint coverage is intentionally limited to routes whose operational request/response contracts are already package-owned. CLI and MCP packages may add a command or tool only after an endpoint group's contracts are owned this way. A run-progress WebSocket endpoint is deliberately not wrapped yet — it needs bridge contract tests first. Admin bootstrap and the runtime asset proxy are intentionally out of scope for operational clients.
Error Taxonomy
Server-originated errors are represented structurally; the canonical server-side problem-details mapping remains owned by @robota-sdk/dag-api, and this package keeps only the structural client-facing payload shape needed by operational clients.
Cost metadata responses are decoded at the HTTP boundary. Malformed success data returns
DAG_COST_META_INVALID_RESPONSE; recognized DAG_COST_META_* and CEL_* problem codes are
preserved, and missing/invalid/unsupported HTTP statuses map to domain codes when the problem
has no recognized code. An unsupported capability is non-retryable.
Run-draft responses are decoded at the HTTP boundary. Malformed successful drafts return
DAG_RUN_DRAFT_INVALID_RESPONSE; known run-draft problem codes are preserved, missing drafts
return DAG_RUN_DRAFT_NOT_FOUND, and transport failures return a typed retryable error.