@agent-compose/sdk 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -39
- package/dist/agent/__tests__/runtime-json-schema.test.d.ts +10 -0
- package/dist/agent/agent-context.d.ts +21 -1
- package/dist/agent/agent-loop.d.ts +24 -1
- package/dist/client.d.ts +338 -534
- package/dist/directives.d.ts +112 -0
- package/dist/display.d.ts +242 -0
- package/dist/errors.d.ts +24 -1
- package/dist/index.d.ts +34 -13
- package/dist/index.js +2984 -861
- package/dist/pause/wrappers.d.ts +31 -9
- package/dist/processors/ask-human.d.ts +30 -0
- package/dist/processors/ask-human.test.d.ts +1 -0
- package/dist/processors/index.d.ts +1 -0
- package/dist/runtimes/_acp-client.d.ts +46 -1
- package/dist/runtimes/_cli-agent.d.ts +58 -4
- package/dist/runtimes/_jsonl-guard.d.ts +103 -0
- package/dist/runtimes/amp.d.ts +2 -2
- package/dist/runtimes/claude-code.d.ts +59 -0
- package/dist/runtimes/claude-code.test.d.ts +14 -0
- package/dist/runtimes/claude.d.ts +16 -0
- package/dist/runtimes/claude.test.d.ts +8 -0
- package/dist/runtimes/codex.d.ts +9 -3
- package/dist/runtimes/cursor.d.ts +9 -0
- package/dist/runtimes/droid.d.ts +9 -0
- package/dist/runtimes/jsonl-guard.test.d.ts +19 -0
- package/dist/runtimes/openai-desktop.js +2922 -861
- package/dist/runtimes/opencode.d.ts +25 -0
- package/dist/runtimes/vercel.js +22 -1
- package/dist/sandbox/devbox.d.ts +42 -0
- package/dist/sandbox/exec-stream.d.ts +14 -0
- package/dist/sandbox/network-policy.d.ts +100 -0
- package/dist/sandbox/provider-def.d.ts +79 -0
- package/dist/sandbox/providers/desktop.d.ts +10 -0
- package/dist/sandbox/providers/e2b.d.ts +17 -0
- package/dist/sandbox/providers/local.d.ts +11 -0
- package/dist/sandbox/providers/vercel.d.ts +18 -0
- package/dist/sandbox/registry.d.ts +45 -0
- package/dist/sandbox/sizes.d.ts +68 -0
- package/dist/sandbox.d.ts +24 -299
- package/dist/step-invocation/__tests__/foreground-recovery.test.d.ts +1 -0
- package/dist/step-invocation/invoker.d.ts +24 -1
- package/dist/step-invocation/protocol.d.ts +13 -0
- package/dist/types/api-compliance.d.ts +71 -0
- package/dist/types/api-conversations.d.ts +492 -0
- package/dist/types/api-factory.d.ts +309 -0
- package/dist/types/api-projects.d.ts +131 -0
- package/dist/types/api-runs.d.ts +377 -0
- package/dist/types/api-scopes.d.ts +102 -0
- package/dist/types/conversation-stream.d.ts +191 -0
- package/dist/types/execution-context.d.ts +12 -2
- package/dist/types/protocol.d.ts +30 -1
- package/dist/types/sandbox-environment.d.ts +8 -5
- package/dist/types/sandbox.d.ts +79 -0
- package/dist/types/workflow-metadata.d.ts +33 -8
- package/dist/types/workflow-plan.d.ts +10 -0
- package/dist/types/workflow.d.ts +18 -193
- package/dist/utils/bundler.d.ts +12 -1
- package/dist/utils/errors.d.ts +9 -1
- package/dist/workflow-steps/index.d.ts +1 -1
- package/dist/workflow-steps/observability.d.ts +8 -1
- package/dist/workflow-steps/runner.d.ts +3 -3
- package/dist/workflow-steps/step.d.ts +15 -1
- package/dist/workflow-steps/types.d.ts +19 -5
- package/dist/workflow-steps/workflow.d.ts +22 -1
- package/dist/workflows/engine.d.ts +3 -2
- package/dist/workflows/invoke-child.d.ts +2 -2
- package/package.json +1 -1
- package/src/agent/agent-context.ts +206 -16
- package/src/agent/agent-loop.ts +40 -4
- package/src/agent/run-agent.ts +9 -1
- package/src/client.ts +909 -621
- package/src/directives.ts +184 -0
- package/src/display.ts +788 -0
- package/src/errors.ts +39 -0
- package/src/index.ts +117 -10
- package/src/pause/wrappers.ts +44 -9
- package/src/processors/ask-human.ts +136 -0
- package/src/processors/index.ts +5 -0
- package/src/runtimes/_acp-client.ts +72 -3
- package/src/runtimes/_cli-agent.ts +171 -38
- package/src/runtimes/_jsonl-guard.ts +219 -0
- package/src/runtimes/claude-code.ts +246 -0
- package/src/runtimes/claude.ts +32 -2
- package/src/runtimes/codex.ts +55 -3
- package/src/runtimes/cursor.ts +59 -0
- package/src/runtimes/droid.ts +63 -0
- package/src/runtimes/openai-desktop.ts +59 -14
- package/src/runtimes/opencode.ts +61 -0
- package/src/sandbox/devbox.ts +48 -0
- package/src/sandbox/exec-stream.ts +48 -0
- package/src/sandbox/network-policy.ts +181 -0
- package/src/sandbox/provider-def.ts +94 -0
- package/src/sandbox/providers/desktop.ts +57 -0
- package/src/sandbox/providers/e2b.ts +354 -0
- package/src/sandbox/providers/local.ts +106 -0
- package/src/sandbox/providers/vercel.ts +331 -0
- package/src/sandbox/registry.ts +198 -0
- package/src/sandbox/sizes.ts +95 -0
- package/src/sandbox.ts +59 -1263
- package/src/step-invocation/invoker.ts +319 -34
- package/src/step-invocation/protocol.ts +19 -0
- package/src/types/api-compliance.ts +79 -0
- package/src/types/api-conversations.ts +522 -0
- package/src/types/api-factory.ts +336 -0
- package/src/types/api-projects.ts +140 -0
- package/src/types/api-runs.ts +412 -0
- package/src/types/api-scopes.ts +102 -0
- package/src/types/conversation-stream.ts +231 -0
- package/src/types/execution-context.ts +10 -2
- package/src/types/protocol.ts +33 -0
- package/src/types/sandbox-environment.ts +28 -9
- package/src/types/sandbox.ts +78 -0
- package/src/types/workflow-metadata.ts +35 -8
- package/src/types/workflow-plan.ts +11 -0
- package/src/types/workflow.ts +25 -280
- package/src/utils/bundler.ts +32 -5
- package/src/utils/errors.ts +34 -2
- package/src/workflow-steps/index.ts +1 -0
- package/src/workflow-steps/observability.ts +19 -8
- package/src/workflow-steps/runner.ts +4 -4
- package/src/workflow-steps/step.ts +49 -1
- package/src/workflow-steps/types.ts +20 -5
- package/src/workflow-steps/workflow.ts +22 -1
- package/src/workflows/engine.ts +3 -2
- package/src/workflows/invoke-child.ts +2 -2
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloud-session UI directives — the typed marker contract between the
|
|
3
|
+
* `agentc` CLI running INSIDE a cloud session's sandbox and the server's
|
|
4
|
+
* cloud executor.
|
|
5
|
+
*
|
|
6
|
+
* A converged cloud session drives a coding CLI whose only platform surface
|
|
7
|
+
* is `agentc` invoked over Bash — it has no typed platform tools, so it
|
|
8
|
+
* could never produce the transcript parts the dashboard renders as rich
|
|
9
|
+
* cards (`get_run_changes` → the inline diff reviewer) or acts on
|
|
10
|
+
* (`navigate_dashboard` → armed-tab navigation). The bridge:
|
|
11
|
+
*
|
|
12
|
+
* 1. `agentc navigate|display …` PRINTS one marker line to stdout —
|
|
13
|
+
* `[[ac:directive:v1 {"kind":…}]]` — and nothing else happens locally.
|
|
14
|
+
* 2. The marker rides back to the server inside the streamed tool_result
|
|
15
|
+
* (the coding CLI echoes the command's output).
|
|
16
|
+
* 3. The cloud executor scans TOOL RESULTS (never model text) for
|
|
17
|
+
* markers, executes each directive server-side through the SAME
|
|
18
|
+
* platform tool executors a platform turn uses (validation, factory
|
|
19
|
+
* gating, result shapes all identical), and persists the resulting
|
|
20
|
+
* tool_call + tool_result pair into the transcript.
|
|
21
|
+
* 4. Existing consumers act unchanged: the dashboard's diff-card /
|
|
22
|
+
* run-card renderers key on tool names, and navigation stays gated by
|
|
23
|
+
* the requesting tab's armed window + client-side URL re-validation.
|
|
24
|
+
*
|
|
25
|
+
* The kind set is CLOSED, but no longer purely read-only. `ask` is the ONE
|
|
26
|
+
* write-bearing directive: it inserts a bounded mentions row as the session
|
|
27
|
+
* owner (who could ping the same member from the dashboard anyway) and
|
|
28
|
+
* persists an ask card. Everything else stays read-scope — run lookups,
|
|
29
|
+
* change-set listing, server-gated file reads (preview / table_file /
|
|
30
|
+
* file_diff), or the navigate directive (validated URL, acted on
|
|
31
|
+
* client-side, cannot submit anything). Markers are data in untrusted
|
|
32
|
+
* output — the parser is hostile-input safe and hard-capped.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
/** Marker frame. v1 is part of the prefix: unknown future versions parse
|
|
36
|
+
* as no-match (fail closed) rather than as a v1 directive. */
|
|
37
|
+
export const DIRECTIVE_MARKER_PREFIX = "[[ac:directive:v1 ";
|
|
38
|
+
export const DIRECTIVE_MARKER_SUFFIX = "]]";
|
|
39
|
+
|
|
40
|
+
/** Max directives honoured per tool result — one command emits one marker;
|
|
41
|
+
* anything past this in a single output is echo/noise, not intent. */
|
|
42
|
+
export const MAX_DIRECTIVES_PER_OUTPUT = 4;
|
|
43
|
+
|
|
44
|
+
export type CloudDirective =
|
|
45
|
+
/** Take the requesting user's dashboard tab to a relative page. */
|
|
46
|
+
| { kind: "navigate"; url: string }
|
|
47
|
+
/** Render one run's detail into the transcript (`get_run` shape). */
|
|
48
|
+
| { kind: "run"; runId: string; workflow?: string }
|
|
49
|
+
/** Render one run's change-set — the dashboard's inline diff reviewer
|
|
50
|
+
* (`get_run_changes` shape). */
|
|
51
|
+
| { kind: "run_changes"; runId: string; workflow?: string }
|
|
52
|
+
/** Sandboxed inline HTML preview of a drive file, frozen (and size-capped)
|
|
53
|
+
* server-side at display time (`display_preview` shape). */
|
|
54
|
+
| { kind: "preview"; path: string }
|
|
55
|
+
/** Sortable table card sourced from a drive .csv/.json file, read and
|
|
56
|
+
* capped server-side (`display_table` shape). */
|
|
57
|
+
| { kind: "table_file"; path: string }
|
|
58
|
+
/** File-level revision diff card; selectors resolve against
|
|
59
|
+
* `factory_file_revisions` server-side (`display_diff` shape). */
|
|
60
|
+
| { kind: "file_diff"; path: string; from: string; to: string }
|
|
61
|
+
/** Interactive question card gated on a named approver — resolution and
|
|
62
|
+
* the mentions ping are server-authoritative (`display_ask` shape). The
|
|
63
|
+
* one write-bearing directive (see the module header). */
|
|
64
|
+
| { kind: "ask"; prompt: string; approver: string; options?: Array<{ id: string; label: string }> };
|
|
65
|
+
|
|
66
|
+
/** `runId` values the run directives accept: a UUID, or the literal
|
|
67
|
+
* `latest` (resolved server-side against the session's factory, optionally
|
|
68
|
+
* narrowed by `workflow`). */
|
|
69
|
+
const RUN_ID_RE = /^(latest|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/i;
|
|
70
|
+
|
|
71
|
+
/** Revision selectors the `file_diff` directive accepts: a literal
|
|
72
|
+
* `factory_file_revisions.id`, `head`, `prev`, or `head~N` (N ≤ 999).
|
|
73
|
+
* Exported so the CLI validates with the same rule it emits under. */
|
|
74
|
+
export const REVISION_SELECTOR_RE = /^(\d{1,12}|head|prev|head~[1-9]\d{0,2})$/;
|
|
75
|
+
|
|
76
|
+
/** Drive-path bound shared by the path-bearing directive kinds. */
|
|
77
|
+
const DIRECTIVE_PATH_MAX = 512;
|
|
78
|
+
|
|
79
|
+
/** Ask directive bounds — tighter than the promoter-path ask marker, sized
|
|
80
|
+
* to fit the 1024-char directive body. */
|
|
81
|
+
export const ASK_DIRECTIVE_PROMPT_MAX = 500;
|
|
82
|
+
export const ASK_DIRECTIVE_MAX_OPTIONS = 6;
|
|
83
|
+
export const ASK_DIRECTIVE_OPTION_ID_MAX = 50;
|
|
84
|
+
export const ASK_DIRECTIVE_OPTION_LABEL_MAX = 60;
|
|
85
|
+
export const ASK_APPROVER_MIN = 3;
|
|
86
|
+
export const ASK_APPROVER_MAX = 320;
|
|
87
|
+
|
|
88
|
+
function validDirectivePath(v: unknown): string | null {
|
|
89
|
+
return typeof v === "string" && v.length >= 1 && v.length <= DIRECTIVE_PATH_MAX ? v : null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** One marker line for `agentc` to print. */
|
|
93
|
+
export function renderDirectiveMarker(directive: CloudDirective): string {
|
|
94
|
+
return `${DIRECTIVE_MARKER_PREFIX}${JSON.stringify(directive)}${DIRECTIVE_MARKER_SUFFIX}`;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function validDirective(value: unknown): CloudDirective | null {
|
|
98
|
+
if (typeof value !== "object" || value === null) return null;
|
|
99
|
+
const d = value as Record<string, unknown>;
|
|
100
|
+
if (d.kind === "navigate") {
|
|
101
|
+
const url = d.url;
|
|
102
|
+
if (typeof url !== "string" || url.length === 0 || url.length > 400) return null;
|
|
103
|
+
// Relative-only at the contract layer; the navigate tool re-validates
|
|
104
|
+
// against the site map and the dashboard validates a third time.
|
|
105
|
+
if (!url.startsWith("/") || url.startsWith("//")) return null;
|
|
106
|
+
return { kind: "navigate", url };
|
|
107
|
+
}
|
|
108
|
+
if (d.kind === "run" || d.kind === "run_changes") {
|
|
109
|
+
const runId = d.runId;
|
|
110
|
+
if (typeof runId !== "string" || !RUN_ID_RE.test(runId)) return null;
|
|
111
|
+
const workflow = d.workflow;
|
|
112
|
+
if (workflow !== undefined && (typeof workflow !== "string" || workflow.length === 0 || workflow.length > 255)) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
return { kind: d.kind, runId, ...(workflow !== undefined ? { workflow } : {}) };
|
|
116
|
+
}
|
|
117
|
+
if (d.kind === "preview" || d.kind === "table_file") {
|
|
118
|
+
const path = validDirectivePath(d.path);
|
|
119
|
+
if (!path) return null;
|
|
120
|
+
if (d.kind === "table_file" && !/\.(csv|json)$/i.test(path)) return null;
|
|
121
|
+
return { kind: d.kind, path };
|
|
122
|
+
}
|
|
123
|
+
if (d.kind === "file_diff") {
|
|
124
|
+
const path = validDirectivePath(d.path);
|
|
125
|
+
if (!path) return null;
|
|
126
|
+
const { from, to } = d;
|
|
127
|
+
if (typeof from !== "string" || !REVISION_SELECTOR_RE.test(from)) return null;
|
|
128
|
+
if (typeof to !== "string" || !REVISION_SELECTOR_RE.test(to)) return null;
|
|
129
|
+
return { kind: "file_diff", path, from, to };
|
|
130
|
+
}
|
|
131
|
+
if (d.kind === "ask") {
|
|
132
|
+
const { prompt, approver } = d;
|
|
133
|
+
if (typeof prompt !== "string" || prompt.length < 1 || prompt.length > ASK_DIRECTIVE_PROMPT_MAX) return null;
|
|
134
|
+
if (typeof approver !== "string" || approver.length < ASK_APPROVER_MIN || approver.length > ASK_APPROVER_MAX) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
let options: Array<{ id: string; label: string }> | undefined;
|
|
138
|
+
if (d.options !== undefined) {
|
|
139
|
+
if (!Array.isArray(d.options) || d.options.length === 0 || d.options.length > ASK_DIRECTIVE_MAX_OPTIONS) {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
options = [];
|
|
143
|
+
for (const raw of d.options) {
|
|
144
|
+
if (typeof raw !== "object" || raw === null) return null;
|
|
145
|
+
const { id, label } = raw as { id?: unknown; label?: unknown };
|
|
146
|
+
if (typeof id !== "string" || id.length < 1 || id.length > ASK_DIRECTIVE_OPTION_ID_MAX) return null;
|
|
147
|
+
if (typeof label !== "string" || label.length < 1 || label.length > ASK_DIRECTIVE_OPTION_LABEL_MAX) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
options.push({ id, label });
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return { kind: "ask", prompt, approver, ...(options !== undefined ? { options } : {}) };
|
|
154
|
+
}
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Extract every valid v1 directive from one command output. Hostile-input
|
|
160
|
+
* safe: malformed JSON, unknown kinds, oversized fields, and unterminated
|
|
161
|
+
* markers are skipped silently; at most MAX_DIRECTIVES_PER_OUTPUT come
|
|
162
|
+
* back. Never throws.
|
|
163
|
+
*/
|
|
164
|
+
export function parseDirectiveMarkers(text: string): CloudDirective[] {
|
|
165
|
+
const out: CloudDirective[] = [];
|
|
166
|
+
let from = 0;
|
|
167
|
+
while (out.length < MAX_DIRECTIVES_PER_OUTPUT) {
|
|
168
|
+
const start = text.indexOf(DIRECTIVE_MARKER_PREFIX, from);
|
|
169
|
+
if (start < 0) break;
|
|
170
|
+
const bodyStart = start + DIRECTIVE_MARKER_PREFIX.length;
|
|
171
|
+
const end = text.indexOf(DIRECTIVE_MARKER_SUFFIX, bodyStart);
|
|
172
|
+
if (end < 0) break;
|
|
173
|
+
from = end + DIRECTIVE_MARKER_SUFFIX.length;
|
|
174
|
+
const body = text.slice(bodyStart, end);
|
|
175
|
+
if (body.length > 1_024) continue;
|
|
176
|
+
try {
|
|
177
|
+
const directive = validDirective(JSON.parse(body));
|
|
178
|
+
if (directive) out.push(directive);
|
|
179
|
+
} catch {
|
|
180
|
+
// malformed JSON in a marker frame — echo/noise, skip
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return out;
|
|
184
|
+
}
|