@agent-compose/sdk 0.8.4 → 0.8.6
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 +213 -189
- package/dist/agent/agent-context.d.ts +9 -1
- package/dist/agent/agent-loop.d.ts +14 -6
- package/dist/agent/perf-sampler.d.ts +27 -2
- package/dist/agent/run-agent.d.ts +1 -1
- package/dist/client.d.ts +250 -59
- package/dist/directives.d.ts +14 -0
- package/dist/display.d.ts +7 -0
- package/dist/errors.d.ts +1 -1
- package/dist/generated/agentc-commands.d.ts +34 -0
- package/dist/index.d.ts +13 -11
- package/dist/index.js +1692 -194
- package/dist/request-context/request-context.d.ts +1 -1
- package/dist/runtimes/_cli-agent.d.ts +278 -58
- package/dist/runtimes/claude-code.d.ts +90 -1
- package/dist/runtimes/claude.d.ts +1 -1
- package/dist/runtimes/codex.d.ts +94 -6
- package/dist/runtimes/codex.mid-turn-hook.test.d.ts +10 -0
- package/dist/runtimes/openai-desktop.d.ts +50 -0
- package/dist/runtimes/openai-desktop.js +1689 -211
- package/dist/runtimes/openai-desktop.test.d.ts +20 -0
- package/dist/runtimes/opencode.d.ts +48 -11
- package/dist/runtimes/opencode.test.d.ts +14 -0
- package/dist/runtimes/tool-pulse.test.d.ts +17 -0
- package/dist/sandbox/baked-clis.d.ts +75 -0
- package/dist/sandbox/devbox.d.ts +5 -5
- package/dist/sandbox/exec-stream.d.ts +1 -2
- package/dist/sandbox/network-policy.d.ts +23 -5
- package/dist/sandbox/registry.d.ts +12 -0
- package/dist/sandbox/sizes.d.ts +11 -5
- package/dist/sandbox.d.ts +5 -3
- package/dist/step-invocation/protocol.d.ts +3 -4
- package/dist/step-invocation/server.d.ts +2 -2
- package/dist/step-invocation/types.d.ts +2 -2
- package/dist/types/api-conversations.d.ts +513 -27
- package/dist/types/api-factory.d.ts +183 -3
- package/dist/types/api-projects.d.ts +480 -0
- package/dist/types/api-runs.d.ts +8 -0
- package/dist/types/api-scopes.d.ts +32 -3
- package/dist/types/conversation-stream.d.ts +27 -1
- package/dist/types/execution-context.d.ts +1 -1
- package/dist/types/protocol.d.ts +182 -2
- package/dist/types/runtime.d.ts +80 -2
- package/dist/types/workflow-metadata.d.ts +2 -4
- package/dist/types/workflow-plan.d.ts +1 -3
- package/dist/utils/bundler.d.ts +23 -0
- package/dist/workflow-steps/observability.d.ts +2 -3
- package/dist/workflow-steps/runner.d.ts +5 -8
- package/dist/workflow-steps/types.d.ts +8 -10
- package/dist/workflow-steps/workflow.d.ts +2 -1
- package/dist/workflows/engine.d.ts +3 -5
- package/dist/workflows/invoke-child.d.ts +2 -2
- package/package.json +2 -2
- package/src/agent/agent-context.ts +193 -116
- package/src/agent/agent-loop.ts +16 -9
- package/src/agent/desktop-open.ts +13 -1
- package/src/agent/perf-sampler.ts +54 -3
- package/src/agent/run-agent.ts +1 -1
- package/src/client.ts +418 -80
- package/src/directives.ts +21 -1
- package/src/display.ts +12 -0
- package/src/errors.ts +1 -0
- package/src/generated/agentc-commands.ts +571 -0
- package/src/index.ts +65 -18
- package/src/pause/pause-core.ts +2 -1
- package/src/request-context/request-context.ts +1 -1
- package/src/runtimes/_cli-agent.ts +607 -132
- package/src/runtimes/claude-code.ts +427 -20
- package/src/runtimes/claude.ts +1 -1
- package/src/runtimes/codex.ts +188 -19
- package/src/runtimes/openai-desktop.ts +82 -19
- package/src/runtimes/opencode.ts +195 -26
- package/src/sandbox/baked-clis.ts +86 -0
- package/src/sandbox/devbox.ts +5 -5
- package/src/sandbox/exec-stream.ts +1 -2
- package/src/sandbox/network-policy.ts +51 -7
- package/src/sandbox/providers/e2b.ts +63 -19
- package/src/sandbox/providers/vercel.ts +6 -6
- package/src/sandbox/registry.ts +19 -1
- package/src/sandbox/sizes.ts +11 -5
- package/src/sandbox.ts +9 -2
- package/src/step-invocation/invoker.ts +2 -6
- package/src/step-invocation/protocol.ts +3 -4
- package/src/step-invocation/server.ts +2 -2
- package/src/types/api-conversations.ts +424 -29
- package/src/types/api-factory.ts +189 -3
- package/src/types/api-projects.ts +443 -0
- package/src/types/api-runs.ts +5 -0
- package/src/types/api-scopes.ts +32 -3
- package/src/types/conversation-stream.ts +29 -1
- package/src/types/execution-context.ts +1 -1
- package/src/types/protocol.ts +180 -2
- package/src/types/runtime.ts +71 -2
- package/src/types/sandbox-environment.ts +1 -2
- package/src/types/workflow-metadata.ts +2 -4
- package/src/types/workflow-plan.ts +1 -3
- package/src/utils/bundler.ts +88 -19
- package/src/workflow-steps/observability.ts +2 -3
- package/src/workflow-steps/runner.ts +5 -8
- package/src/workflow-steps/types.ts +8 -10
- package/src/workflow-steps/workflow.ts +2 -1
- package/src/workflows/engine.ts +3 -5
- package/src/workflows/invoke-child.ts +2 -2
- package/dist/pause/__tests__/errors.test.d.ts +0 -1
- package/dist/pause/__tests__/wrappers.test.d.ts +0 -1
- package/dist/step-invocation/__tests__/protocol.test.d.ts +0 -1
|
@@ -392,12 +392,24 @@ export function browserBackfillCmd(): string {
|
|
|
392
392
|
// browser without flags is a failed heal, reported as one.
|
|
393
393
|
// installChromiumDefaultsCmd() is quote-free by construction, so it embeds
|
|
394
394
|
// verbatim in this single-quoted payload.
|
|
395
|
+
//
|
|
396
|
+
// `chromium x11-utils luit-` mirrors — and heals — the luit/x11-utils
|
|
397
|
+
// conflict the bake fixed in 8ba2d96b but this line never got: bookworm's
|
|
398
|
+
// xterm Recommends `luit | x11-utils (<< 7.7+6~)`, so grandfathered images
|
|
399
|
+
// (baked before 2026-08-16) carry standalone `luit`, which
|
|
400
|
+
// `Breaks: x11-utils (<< 7.7+6)` — and chromium hard-Depends on x11-utils
|
|
401
|
+
// via chromium-common. Bare `apt-get install chromium` into that state is
|
|
402
|
+
// pkgProblemResolver exit 100, on EVERY fresh boot, forever (the exact
|
|
403
|
+
// `backfill-install=failed` storm of 2026-08-30). Naming x11-utils is not
|
|
404
|
+
// enough here — luit is already INSTALLED — so the trailing `luit-` tells
|
|
405
|
+
// apt to remove it in the same transaction (a no-op where it's absent,
|
|
406
|
+
// e.g. post-8ba2d96b images where chromium is present anyway).
|
|
395
407
|
return (
|
|
396
408
|
`mkdir -p ${AC_OPEN_STATE_DIR} && ` +
|
|
397
409
|
`if command -v chromium >/dev/null 2>&1; then echo backfill=present; ` +
|
|
398
410
|
`elif [ -f ${pid} ] && kill -0 "$(cat ${pid} 2>/dev/null)" 2>/dev/null; then echo backfill=in-progress; ` +
|
|
399
411
|
`else rm -f ${BROWSER_BACKFILL_FAILED}; ` +
|
|
400
|
-
`setsid sh -c 'if apt-get update -q && DEBIAN_FRONTEND=noninteractive apt-get install -y -q chromium && command -v chromium >/dev/null 2>&1 && ${installChromiumDefaultsCmd()}; then echo backfill-install=ok; else echo backfill-install=failed; touch ${BROWSER_BACKFILL_FAILED}; fi; rm -f ${pid}' </dev/null >>${BROWSER_BACKFILL_LOG} 2>&1 & ` +
|
|
412
|
+
`setsid sh -c 'if apt-get update -q && DEBIAN_FRONTEND=noninteractive apt-get install -y -q chromium x11-utils luit- && command -v chromium >/dev/null 2>&1 && ${installChromiumDefaultsCmd()}; then echo backfill-install=ok; else echo backfill-install=failed; touch ${BROWSER_BACKFILL_FAILED}; fi; rm -f ${pid}' </dev/null >>${BROWSER_BACKFILL_LOG} 2>&1 & ` +
|
|
401
413
|
`echo $! > ${pid}; echo backfill=started; fi`
|
|
402
414
|
);
|
|
403
415
|
}
|
|
@@ -47,8 +47,32 @@ export const PERF_PROBE_WINDOW_SECONDS = 2;
|
|
|
47
47
|
/** The standalone probe's output line leads with this prefix. */
|
|
48
48
|
export const PERF_PROBE_LINE_PREFIX = "perf ";
|
|
49
49
|
|
|
50
|
-
/** Longest token the parsers accept — anything bigger is garbage.
|
|
51
|
-
|
|
50
|
+
/** Longest token the parsers accept — anything bigger is garbage. The
|
|
51
|
+
* `top` field (three process names of up to 20 chars with their RSS) is
|
|
52
|
+
* what moved this up from 200. */
|
|
53
|
+
export const PERF_TOKEN_MAX_CHARS = 320;
|
|
54
|
+
|
|
55
|
+
/** THE TOP PROCESSES BY RESIDENT MEMORY ("why was it at 99%?", the
|
|
56
|
+
* 2026-10-03 flight incident: a 4 vCPU / 8 GB machine sat at 99% memory
|
|
57
|
+
* for twelve minutes and nothing recorded what held it): at most this many
|
|
58
|
+
* entries ride the token, name and resident MB each. A machine fact, read
|
|
59
|
+
* by the same /proc burst; never a judgment. */
|
|
60
|
+
export const PERF_TOP_PROCESSES = 3;
|
|
61
|
+
/** A process name as the token carries it: `comm`, sanitized on the guest
|
|
62
|
+
* to this alphabet and length, so it can ride a comma-separated token. */
|
|
63
|
+
export const PERF_TOP_NAME_MAX = 20;
|
|
64
|
+
const TOP_NAME_RE = /^[A-Za-z0-9._-]{1,20}$/;
|
|
65
|
+
/** A process resident set the clamp believes, in MB (a 64 GB machine is
|
|
66
|
+
* past every sandbox we run). */
|
|
67
|
+
const TOP_RSS_MAX_MB = 65_536;
|
|
68
|
+
|
|
69
|
+
/** One process by resident memory. */
|
|
70
|
+
export interface GuestTopProcess {
|
|
71
|
+
/** Its `comm` (the executable's short name), sanitized. */
|
|
72
|
+
name: string;
|
|
73
|
+
/** Resident set in MB, whole. */
|
|
74
|
+
rssMb: number;
|
|
75
|
+
}
|
|
52
76
|
|
|
53
77
|
/** One clamped guest perf sample. Null fields = unreadable/absent on the
|
|
54
78
|
* guest — never zero-filled (a zero is a claim; null is honesty). */
|
|
@@ -67,6 +91,9 @@ export interface GuestPerfSample {
|
|
|
67
91
|
ramMb: number | null;
|
|
68
92
|
/** Guest clock at sample time, epoch seconds. Dedupe only. */
|
|
69
93
|
sampledAtS: number | null;
|
|
94
|
+
/** The processes holding the most memory, biggest first (`top`); null
|
|
95
|
+
* when the guest did not report them (an older image, no `ps`). */
|
|
96
|
+
topProcesses: GuestTopProcess[] | null;
|
|
70
97
|
}
|
|
71
98
|
|
|
72
99
|
export interface PerfSamplerPaths {
|
|
@@ -113,7 +140,13 @@ function perfReadFunctionFragment(procRoot: string, diskPath: string): string {
|
|
|
113
140
|
+ `if [ "\${ac_pmt:-0}" -gt 0 ] && [ -n "\${ac_pma:-}" ]; then ac_pmem=$(( 100 * (ac_pmt - ac_pma) / ac_pmt )); fi; `
|
|
114
141
|
+ `[ "$ac_pmem" -gt 100 ] && ac_pmem=100; [ "$ac_pmem" -lt -1 ] && ac_pmem=-1; `
|
|
115
142
|
+ `ac_pdsk=$(df -kP ${disk} 2>/dev/null | awk 'NR==2 && $2>0 {print int(100*$3/$2)}'); `
|
|
116
|
-
|
|
143
|
+
// The top processes by resident memory (the "why 99%?" fact): three
|
|
144
|
+
// `comm` names with their RSS in MB, each name sanitized to the token's
|
|
145
|
+
// alphabet, `;`-joined so the field stays one comma-free word. A guest
|
|
146
|
+
// whose `ps` lacks `--sort` (not procps) prints nothing and the field is
|
|
147
|
+
// absent — the parser reads that as "not reported", never as zero.
|
|
148
|
+
+ `ac_ptop=$(ps -eo rss=,comm= --sort=-rss 2>/dev/null | head -${PERF_TOP_PROCESSES} | awk '{ n=$2; gsub(/[^A-Za-z0-9._-]/, "_", n); if (length(n) > ${PERF_TOP_NAME_MAX}) n=substr(n, 1, ${PERF_TOP_NAME_MAX}); if (n == "") n="_"; printf "%s%s:%d", (NR > 1 ? ";" : ""), n, int($1 / 1024) }' 2>/dev/null); `
|
|
149
|
+
+ `ac_tok="v=1,cpu=$ac_pcpu,l1=\${ac_pl1:--1},mem=$ac_pmem,dsk=\${ac_pdsk:--1},vc=\${ac_pvc:-0},ram=$(( \${ac_pmt:-0} / 1024 )),ts=$(date +%s)\${ac_ptop:+,top=$ac_ptop}"; `
|
|
117
150
|
+ `}; `;
|
|
118
151
|
}
|
|
119
152
|
|
|
@@ -184,12 +217,30 @@ export function parsePerfToken(token: string): GuestPerfSample | null {
|
|
|
184
217
|
ramMb: bounded("ram", 1, 16 * 1024 * 1024),
|
|
185
218
|
// Bounded to [2020, 2100) in epoch seconds — dedupe-grade only.
|
|
186
219
|
sampledAtS: bounded("ts", 1_577_836_800, 4_102_444_800),
|
|
220
|
+
topProcesses: parseTopProcesses(kv.get("top")),
|
|
187
221
|
};
|
|
188
222
|
if (sample.cpuBusyPct === null && sample.load1 === null
|
|
189
223
|
&& sample.memUsedPct === null && sample.diskUsedPct === null) return null;
|
|
190
224
|
return sample;
|
|
191
225
|
}
|
|
192
226
|
|
|
227
|
+
/** The `top` field, clamped entry by entry: a name outside the alphabet or
|
|
228
|
+
* an RSS outside [0, 64 GB] drops THAT entry; more than the cap is cut;
|
|
229
|
+
* an absent or empty field is null (not reported). */
|
|
230
|
+
export function parseTopProcesses(raw: string | undefined): GuestTopProcess[] | null {
|
|
231
|
+
if (raw === undefined || raw.length === 0) return null;
|
|
232
|
+
const out: GuestTopProcess[] = [];
|
|
233
|
+
for (const entry of raw.split(";").slice(0, PERF_TOP_PROCESSES)) {
|
|
234
|
+
const i = entry.lastIndexOf(":");
|
|
235
|
+
if (i <= 0) continue;
|
|
236
|
+
const name = entry.slice(0, i);
|
|
237
|
+
const rssMb = Number(entry.slice(i + 1));
|
|
238
|
+
if (!TOP_NAME_RE.test(name) || !Number.isInteger(rssMb) || rssMb < 0 || rssMb > TOP_RSS_MAX_MB) continue;
|
|
239
|
+
out.push({ name, rssMb });
|
|
240
|
+
}
|
|
241
|
+
return out.length > 0 ? out : null;
|
|
242
|
+
}
|
|
243
|
+
|
|
193
244
|
/** Parse the standalone probe's stdout (the LAST `perf ` line wins — envd
|
|
194
245
|
* occasionally prepends shell noise). */
|
|
195
246
|
export function parsePerfProbeOutput(stdout: string): GuestPerfSample | null {
|
package/src/agent/run-agent.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* agent — canonical entry point for embedding an LLM agent inside a
|
|
3
|
-
* workflow.
|
|
3
|
+
* workflow. A step's `run()` body calls it; the loop executes
|
|
4
4
|
* against the runner's own VM.
|
|
5
5
|
*
|
|
6
6
|
* Glue packaged so workflows don't duplicate it:
|