@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.
Files changed (106) hide show
  1. package/README.md +213 -189
  2. package/dist/agent/agent-context.d.ts +9 -1
  3. package/dist/agent/agent-loop.d.ts +14 -6
  4. package/dist/agent/perf-sampler.d.ts +27 -2
  5. package/dist/agent/run-agent.d.ts +1 -1
  6. package/dist/client.d.ts +250 -59
  7. package/dist/directives.d.ts +14 -0
  8. package/dist/display.d.ts +7 -0
  9. package/dist/errors.d.ts +1 -1
  10. package/dist/generated/agentc-commands.d.ts +34 -0
  11. package/dist/index.d.ts +13 -11
  12. package/dist/index.js +1692 -194
  13. package/dist/request-context/request-context.d.ts +1 -1
  14. package/dist/runtimes/_cli-agent.d.ts +278 -58
  15. package/dist/runtimes/claude-code.d.ts +90 -1
  16. package/dist/runtimes/claude.d.ts +1 -1
  17. package/dist/runtimes/codex.d.ts +94 -6
  18. package/dist/runtimes/codex.mid-turn-hook.test.d.ts +10 -0
  19. package/dist/runtimes/openai-desktop.d.ts +50 -0
  20. package/dist/runtimes/openai-desktop.js +1689 -211
  21. package/dist/runtimes/openai-desktop.test.d.ts +20 -0
  22. package/dist/runtimes/opencode.d.ts +48 -11
  23. package/dist/runtimes/opencode.test.d.ts +14 -0
  24. package/dist/runtimes/tool-pulse.test.d.ts +17 -0
  25. package/dist/sandbox/baked-clis.d.ts +75 -0
  26. package/dist/sandbox/devbox.d.ts +5 -5
  27. package/dist/sandbox/exec-stream.d.ts +1 -2
  28. package/dist/sandbox/network-policy.d.ts +23 -5
  29. package/dist/sandbox/registry.d.ts +12 -0
  30. package/dist/sandbox/sizes.d.ts +11 -5
  31. package/dist/sandbox.d.ts +5 -3
  32. package/dist/step-invocation/protocol.d.ts +3 -4
  33. package/dist/step-invocation/server.d.ts +2 -2
  34. package/dist/step-invocation/types.d.ts +2 -2
  35. package/dist/types/api-conversations.d.ts +513 -27
  36. package/dist/types/api-factory.d.ts +183 -3
  37. package/dist/types/api-projects.d.ts +480 -0
  38. package/dist/types/api-runs.d.ts +8 -0
  39. package/dist/types/api-scopes.d.ts +32 -3
  40. package/dist/types/conversation-stream.d.ts +27 -1
  41. package/dist/types/execution-context.d.ts +1 -1
  42. package/dist/types/protocol.d.ts +182 -2
  43. package/dist/types/runtime.d.ts +80 -2
  44. package/dist/types/workflow-metadata.d.ts +2 -4
  45. package/dist/types/workflow-plan.d.ts +1 -3
  46. package/dist/utils/bundler.d.ts +23 -0
  47. package/dist/workflow-steps/observability.d.ts +2 -3
  48. package/dist/workflow-steps/runner.d.ts +5 -8
  49. package/dist/workflow-steps/types.d.ts +8 -10
  50. package/dist/workflow-steps/workflow.d.ts +2 -1
  51. package/dist/workflows/engine.d.ts +3 -5
  52. package/dist/workflows/invoke-child.d.ts +2 -2
  53. package/package.json +2 -2
  54. package/src/agent/agent-context.ts +193 -116
  55. package/src/agent/agent-loop.ts +16 -9
  56. package/src/agent/desktop-open.ts +13 -1
  57. package/src/agent/perf-sampler.ts +54 -3
  58. package/src/agent/run-agent.ts +1 -1
  59. package/src/client.ts +418 -80
  60. package/src/directives.ts +21 -1
  61. package/src/display.ts +12 -0
  62. package/src/errors.ts +1 -0
  63. package/src/generated/agentc-commands.ts +571 -0
  64. package/src/index.ts +65 -18
  65. package/src/pause/pause-core.ts +2 -1
  66. package/src/request-context/request-context.ts +1 -1
  67. package/src/runtimes/_cli-agent.ts +607 -132
  68. package/src/runtimes/claude-code.ts +427 -20
  69. package/src/runtimes/claude.ts +1 -1
  70. package/src/runtimes/codex.ts +188 -19
  71. package/src/runtimes/openai-desktop.ts +82 -19
  72. package/src/runtimes/opencode.ts +195 -26
  73. package/src/sandbox/baked-clis.ts +86 -0
  74. package/src/sandbox/devbox.ts +5 -5
  75. package/src/sandbox/exec-stream.ts +1 -2
  76. package/src/sandbox/network-policy.ts +51 -7
  77. package/src/sandbox/providers/e2b.ts +63 -19
  78. package/src/sandbox/providers/vercel.ts +6 -6
  79. package/src/sandbox/registry.ts +19 -1
  80. package/src/sandbox/sizes.ts +11 -5
  81. package/src/sandbox.ts +9 -2
  82. package/src/step-invocation/invoker.ts +2 -6
  83. package/src/step-invocation/protocol.ts +3 -4
  84. package/src/step-invocation/server.ts +2 -2
  85. package/src/types/api-conversations.ts +424 -29
  86. package/src/types/api-factory.ts +189 -3
  87. package/src/types/api-projects.ts +443 -0
  88. package/src/types/api-runs.ts +5 -0
  89. package/src/types/api-scopes.ts +32 -3
  90. package/src/types/conversation-stream.ts +29 -1
  91. package/src/types/execution-context.ts +1 -1
  92. package/src/types/protocol.ts +180 -2
  93. package/src/types/runtime.ts +71 -2
  94. package/src/types/sandbox-environment.ts +1 -2
  95. package/src/types/workflow-metadata.ts +2 -4
  96. package/src/types/workflow-plan.ts +1 -3
  97. package/src/utils/bundler.ts +88 -19
  98. package/src/workflow-steps/observability.ts +2 -3
  99. package/src/workflow-steps/runner.ts +5 -8
  100. package/src/workflow-steps/types.ts +8 -10
  101. package/src/workflow-steps/workflow.ts +2 -1
  102. package/src/workflows/engine.ts +3 -5
  103. package/src/workflows/invoke-child.ts +2 -2
  104. package/dist/pause/__tests__/errors.test.d.ts +0 -1
  105. package/dist/pause/__tests__/wrappers.test.d.ts +0 -1
  106. 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
- export const PERF_TOKEN_MAX_CHARS = 200;
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
- + `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)"; `
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 {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * agent — canonical entry point for embedding an LLM agent inside a
3
- * workflow. The workflow's `run()` body calls it; the loop executes
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: