@demicodes/agent 0.19.1 → 0.19.3
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/dist/client-entry.d.mts +2 -2
- package/dist/index.d.mts +47 -6
- package/dist/index.mjs +323 -79
- package/dist/stdio-transport.d.mts +1 -1
- package/dist/{transport-BRqZoaeo.d.mts → transport-CHrPzcrU.d.mts} +2 -0
- package/dist/{websocket-transport-C6Y5CeLG.d.mts → websocket-transport-NZ5Btmb4.d.mts} +1 -1
- package/package.json +5 -5
package/dist/client-entry.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { f as TranscriptPatch, l as ServerFrame, n as AgentServerTransport, o as ClientFrame, r as AgentTransport, s as ClientSessionEvent, t as AgentClientTransport, u as ShellCommandStatusLike, x as AgentMetadata } from "./transport-
|
|
2
|
-
import { a as AgentClient, i as AgentActionOptions, n as createWebSocketClientTransport, o as AgentClientListener, r as createWebSocketServerTransport, t as JsonWebSocket } from "./websocket-transport-
|
|
1
|
+
import { f as TranscriptPatch, l as ServerFrame, n as AgentServerTransport, o as ClientFrame, r as AgentTransport, s as ClientSessionEvent, t as AgentClientTransport, u as ShellCommandStatusLike, x as AgentMetadata } from "./transport-CHrPzcrU.mjs";
|
|
2
|
+
import { a as AgentClient, i as AgentActionOptions, n as createWebSocketClientTransport, o as AgentClientListener, r as createWebSocketServerTransport, t as JsonWebSocket } from "./websocket-transport-NZ5Btmb4.mjs";
|
|
3
3
|
import { ProviderSelection } from "@demicodes/provider";
|
|
4
4
|
export { type AgentActionOptions, AgentClient, type AgentClientListener, type AgentClientTransport, type AgentMetadata, type AgentServerTransport, type AgentTransport, type ClientFrame, type ClientSessionEvent, type JsonWebSocket, type ProviderSelection, type ServerFrame, type ShellCommandStatusLike, type TranscriptPatch, createWebSocketClientTransport, createWebSocketServerTransport };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { A as AgentSystemPromptContext, B as CompactionWindow, C as AgentReferenceResolveContext, D as AgentSessionParams, E as AgentSessionOptions, F as ExternalMutationReservation, G as DEFAULT_TURN_RETRY_POLICY, H as TranscriptLog, I as ModelSwitchApply, J as resolveRetryPolicy, K as TurnRetryPolicy, L as SessionEvent, M as AgentToolContext, N as AgentToolInvokeContext, O as AgentSessionRestoreParams, P as AgentToolInvokeResult, R as SessionEventListener, S as AgentPromptContext, T as AgentSessionCloneParams, U as TranscriptOptions, V as DrainedTranscriptPatches, W as estimateTranscriptBlockTokens, Y as retryDelayMs, _ as AgentHarnessContext, a as createInProcessTransportPair, b as AgentLifecycleEvent, c as ConversationSummary, d as SubagentJob, f as TranscriptPatch, g as AgentHarness, h as AgentDisposeContext, i as InProcessTransportPair, j as AgentTool, k as AgentSessionStore, l as ServerFrame, m as AbortTarget, n as AgentServerTransport, o as ClientFrame, p as AbortResult, q as isRetryableCode, r as AgentTransport, s as ClientSessionEvent, t as AgentClientTransport, u as ShellCommandStatusLike, v as AgentHarnessRuntime, w as AgentSessionCheckpoint, x as AgentMetadata, y as AgentHostContext, z as SubagentProfile } from "./transport-
|
|
2
|
-
import { a as AgentClient, i as AgentActionOptions, n as createWebSocketClientTransport, o as AgentClientListener, r as createWebSocketServerTransport, t as JsonWebSocket } from "./websocket-transport-
|
|
3
|
-
import { BashAuditEvent, BashEnvironment, BashEnvironmentOptions, Command, CommandMetadataRecord, Host, ShellCommandStatus, ShellOutputChunk } from "@demicodes/shell";
|
|
1
|
+
import { A as AgentSystemPromptContext, B as CompactionWindow, C as AgentReferenceResolveContext, D as AgentSessionParams, E as AgentSessionOptions, F as ExternalMutationReservation, G as DEFAULT_TURN_RETRY_POLICY, H as TranscriptLog, I as ModelSwitchApply, J as resolveRetryPolicy, K as TurnRetryPolicy, L as SessionEvent, M as AgentToolContext, N as AgentToolInvokeContext, O as AgentSessionRestoreParams, P as AgentToolInvokeResult, R as SessionEventListener, S as AgentPromptContext, T as AgentSessionCloneParams, U as TranscriptOptions, V as DrainedTranscriptPatches, W as estimateTranscriptBlockTokens, Y as retryDelayMs, _ as AgentHarnessContext, a as createInProcessTransportPair, b as AgentLifecycleEvent, c as ConversationSummary, d as SubagentJob, f as TranscriptPatch, g as AgentHarness, h as AgentDisposeContext, i as InProcessTransportPair, j as AgentTool, k as AgentSessionStore, l as ServerFrame, m as AbortTarget, n as AgentServerTransport, o as ClientFrame, p as AbortResult, q as isRetryableCode, r as AgentTransport, s as ClientSessionEvent, t as AgentClientTransport, u as ShellCommandStatusLike, v as AgentHarnessRuntime, w as AgentSessionCheckpoint, x as AgentMetadata, y as AgentHostContext, z as SubagentProfile } from "./transport-CHrPzcrU.mjs";
|
|
2
|
+
import { a as AgentClient, i as AgentActionOptions, n as createWebSocketClientTransport, o as AgentClientListener, r as createWebSocketServerTransport, t as JsonWebSocket } from "./websocket-transport-NZ5Btmb4.mjs";
|
|
3
|
+
import { BashAuditEvent, BashEnvironment, BashEnvironmentOptions, Command, CommandMetadataRecord, Host, HostStore, ShellCommandStatus, ShellOutputChunk } from "@demicodes/shell";
|
|
4
4
|
import { AgentProvider, Provider } from "@demicodes/provider";
|
|
5
5
|
import { Block, Model, ModelMediaKind, ModelSelection, ProviderErrorDiagnostics, QueuedMessage, SessionPhase, UserContentBlock } from "@demicodes/core";
|
|
6
6
|
//#region src/recovery.d.ts
|
|
@@ -339,6 +339,7 @@ declare class AgentServer {
|
|
|
339
339
|
//#endregion
|
|
340
340
|
//#region src/subagent.d.ts
|
|
341
341
|
declare const MAX_LIVE_SUBAGENTS = 8;
|
|
342
|
+
declare const MAX_ARCHIVED_SUBAGENTS = 16;
|
|
342
343
|
declare const SUBAGENT_RESULT_MAX_BYTES: number;
|
|
343
344
|
type SubagentExecution = 'idle' | 'provider_streaming' | 'tool_executing' | 'compacting' | 'finalizing' | 'pending_yield';
|
|
344
345
|
interface ChildSupervisorOptions<State> {
|
|
@@ -353,14 +354,19 @@ interface ChildSupervisorOptions<State> {
|
|
|
353
354
|
sessionOptions: AgentServerSessionOptions;
|
|
354
355
|
/** When false, a child closing never wakes an idle parent; the host app orchestrates the wakeup from the `subagent closed` frame. */
|
|
355
356
|
notifyParentOnIdle: boolean;
|
|
357
|
+
/** Backing store for child checkpoints and job metadata, keyed under the parent's session directory. */
|
|
358
|
+
store: HostStore;
|
|
356
359
|
emit(frame: ServerFrame): void;
|
|
357
360
|
}
|
|
358
361
|
/**
|
|
359
362
|
* Per-parent subagent supervisor. Owns every child `AgentSession` this parent
|
|
360
363
|
* spawns: lifecycle (spawn / steer / abort / natural end), the `demi agent`
|
|
361
364
|
* command tree, child shell environments, and the `subagent*` protocol frames
|
|
362
|
-
* on the parent connection. Children
|
|
363
|
-
* checkpoint
|
|
365
|
+
* on the parent connection. Children persist exactly like the parent: each
|
|
366
|
+
* live child keeps a checkpoint and job record under the parent's session
|
|
367
|
+
* directory, and reopening the parent restores and resumes them (`restore`).
|
|
368
|
+
* A closed child moves to the archive: its transcript checkpoint stays on
|
|
369
|
+
* store and `demi agent resume` revives it with a new user message.
|
|
364
370
|
*/
|
|
365
371
|
declare class ChildSupervisor<State = unknown> {
|
|
366
372
|
private readonly options;
|
|
@@ -380,9 +386,43 @@ declare class ChildSupervisor<State = unknown> {
|
|
|
380
386
|
} | null;
|
|
381
387
|
/** Re-emits `subagent started` + transcript reset for every running child (transcript resync). */
|
|
382
388
|
replay(): void;
|
|
389
|
+
/**
|
|
390
|
+
* Detaches every live child on connection teardown: aborts in-flight turns,
|
|
391
|
+
* flushes checkpoints, and keeps the persisted job so the next open of this
|
|
392
|
+
* parent restores it — the same dispose semantics as the parent session.
|
|
393
|
+
* No `closed` frame is emitted: the children are not done, just paused.
|
|
394
|
+
*/
|
|
383
395
|
dispose(): Promise<void>;
|
|
396
|
+
/**
|
|
397
|
+
* Rebuilds every persisted live child of this parent and finishes what it was
|
|
398
|
+
* doing: an interrupted turn resumes from its resume point; an already
|
|
399
|
+
* quiescent child closes with its result. Children share the parent's
|
|
400
|
+
* persistence lifecycle — a parent restore is a child restore.
|
|
401
|
+
*/
|
|
402
|
+
restore(): Promise<void>;
|
|
403
|
+
private restoreJob;
|
|
404
|
+
/** Shared by restore and resume: rebuild a persisted child's job and session from its checkpoint. */
|
|
405
|
+
private reassembleJob;
|
|
406
|
+
/**
|
|
407
|
+
* Revives an archived child: its job record turns live again (this round's
|
|
408
|
+
* metadata, a fresh spawnedAt), the session rebuilds from the preserved
|
|
409
|
+
* checkpoint, and the message opens its next turn on top of the old
|
|
410
|
+
* transcript.
|
|
411
|
+
*/
|
|
412
|
+
private resumeArchived;
|
|
413
|
+
/** Every archived (finished, revivable) child of this parent, newest first. */
|
|
414
|
+
private listArchivedJobs;
|
|
415
|
+
private pruneArchive;
|
|
384
416
|
abortSubtree(id: string): Promise<void>;
|
|
385
417
|
private spawn;
|
|
418
|
+
/** Everything spawn and restore share: the command tree, the harness runtime, and the job record (session attached separately). */
|
|
419
|
+
private assembleJob;
|
|
420
|
+
private attachSession;
|
|
421
|
+
private childStoreKey;
|
|
422
|
+
private childSessionStore;
|
|
423
|
+
private deletePersistedJob;
|
|
424
|
+
/** Shared spawn/resume foreground behaviour: announce the id, wire abort and stdin steers, wait for close, report the outcome. */
|
|
425
|
+
private attendChild;
|
|
386
426
|
/** Delivers one steer to a child: mid-turn as a steer, idle as a new user turn. */
|
|
387
427
|
private steerChild;
|
|
388
428
|
private pumpStdinSteers;
|
|
@@ -392,6 +432,7 @@ declare class ChildSupervisor<State = unknown> {
|
|
|
392
432
|
/** Resolves when the child is idle with no pending yield wakeups (or the job closed). */
|
|
393
433
|
private waitForQuiescence;
|
|
394
434
|
private closeJob;
|
|
435
|
+
private disposeJobShells;
|
|
395
436
|
/** Wakes an idle parent with a user send; a parent blocked in the spawn gets the tool result instead. */
|
|
396
437
|
private notifyIdleParent;
|
|
397
438
|
private createChildAgentNode;
|
|
@@ -491,4 +532,4 @@ interface ShellToolView {
|
|
|
491
532
|
declare function finishShellToolResult<State>(environment: BashEnvironment, result: ShellCommandStatus, ctx: AgentToolInvokeContext<State>): Promise<AgentToolInvokeResult>;
|
|
492
533
|
declare function shellCommandHandleRequired(result: ShellCommandStatus, budgetTokens: number): boolean;
|
|
493
534
|
//#endregion
|
|
494
|
-
export { AbortResult, AbortTarget, ActiveTurnPhase, AgentActionOptions, AgentClient, AgentClientListener, AgentClientTransport, AgentDisposeContext, AgentHarness, AgentHarnessContext, AgentHarnessRuntime, AgentHostContext, AgentLifecycleEvent, AgentMetadata, AgentPromptContext, AgentReferenceResolveContext, AgentServer, AgentServerOptions, AgentServerSessionOptions, AgentServerTransport, AgentSession, AgentSessionCheckpoint, AgentSessionCloneParams, AgentSessionOptions, AgentSessionParams, AgentSessionRestoreParams, AgentSessionStore, AgentSystemPromptContext, AgentTool, AgentToolContext, AgentToolInvokeContext, AgentToolInvokeResult, AgentTransport, AgentTransportBinding, ChildSupervisor, ChildSupervisorOptions, ClientFrame, ClientSessionEvent, CompactionWindow, ConversationSummary, DEFAULT_MAX_MEDIA_BYTES, DEFAULT_TURN_RETRY_POLICY, DrainedTranscriptPatches, ExternalMutationReservation, InProcessTransportPair, JsonWebSocket, MAX_LIVE_SUBAGENTS, ModelSwitchApply, PrepareShell, PrepareShellContext, ProviderStreamError, ResumePoint, RunCommandLineCommandNotRegisteredError, RunCommandLineOptions, RunCommandLineResult, RunCommandLineShellNotFoundError, RunCommandLineTimeoutError, SHELL_VIEW_MAX_CHARS, SUBAGENT_RESULT_MAX_BYTES, ServerFrame, SessionEvent, SessionEventListener, ShellCommandStatusLike, ShellToolResultOptions, ShellToolView, StandardAgentToolOptions, SubagentExecution, SubagentJob, SubagentProfile, TranscriptLog, TranscriptOptions, TranscriptPatch, TurnRetryPolicy, applyTranscriptPatches, cloneBlocks, createInProcessTransportPair, createReadonlyHost, createStandardAgentTools, createWebSocketClientTransport, createWebSocketServerTransport, estimateTranscriptBlockTokens, findResumePoint, finishShellToolResult, injectSubagentCommand, isContextLengthExceeded, isRetryableCode, resolveRetryPolicy, retryDelayMs, shellCommandHandleRequired, shellPreviewBudgetTokens, toShellToolResult };
|
|
535
|
+
export { AbortResult, AbortTarget, ActiveTurnPhase, AgentActionOptions, AgentClient, AgentClientListener, AgentClientTransport, AgentDisposeContext, AgentHarness, AgentHarnessContext, AgentHarnessRuntime, AgentHostContext, AgentLifecycleEvent, AgentMetadata, AgentPromptContext, AgentReferenceResolveContext, AgentServer, AgentServerOptions, AgentServerSessionOptions, AgentServerTransport, AgentSession, AgentSessionCheckpoint, AgentSessionCloneParams, AgentSessionOptions, AgentSessionParams, AgentSessionRestoreParams, AgentSessionStore, AgentSystemPromptContext, AgentTool, AgentToolContext, AgentToolInvokeContext, AgentToolInvokeResult, AgentTransport, AgentTransportBinding, ChildSupervisor, ChildSupervisorOptions, ClientFrame, ClientSessionEvent, CompactionWindow, ConversationSummary, DEFAULT_MAX_MEDIA_BYTES, DEFAULT_TURN_RETRY_POLICY, DrainedTranscriptPatches, ExternalMutationReservation, InProcessTransportPair, JsonWebSocket, MAX_ARCHIVED_SUBAGENTS, MAX_LIVE_SUBAGENTS, ModelSwitchApply, PrepareShell, PrepareShellContext, ProviderStreamError, ResumePoint, RunCommandLineCommandNotRegisteredError, RunCommandLineOptions, RunCommandLineResult, RunCommandLineShellNotFoundError, RunCommandLineTimeoutError, SHELL_VIEW_MAX_CHARS, SUBAGENT_RESULT_MAX_BYTES, ServerFrame, SessionEvent, SessionEventListener, ShellCommandStatusLike, ShellToolResultOptions, ShellToolView, StandardAgentToolOptions, SubagentExecution, SubagentJob, SubagentProfile, TranscriptLog, TranscriptOptions, TranscriptPatch, TurnRetryPolicy, applyTranscriptPatches, cloneBlocks, createInProcessTransportPair, createReadonlyHost, createStandardAgentTools, createWebSocketClientTransport, createWebSocketServerTransport, estimateTranscriptBlockTokens, findResumePoint, finishShellToolResult, injectSubagentCommand, isContextLengthExceeded, isRetryableCode, resolveRetryPolicy, retryDelayMs, shellCommandHandleRequired, shellPreviewBudgetTokens, toShellToolResult };
|
package/dist/index.mjs
CHANGED
|
@@ -2653,6 +2653,7 @@ function shellCommandHandleRequired(result, budgetTokens) {
|
|
|
2653
2653
|
//#endregion
|
|
2654
2654
|
//#region src/subagent.ts
|
|
2655
2655
|
const MAX_LIVE_SUBAGENTS = 8;
|
|
2656
|
+
const MAX_ARCHIVED_SUBAGENTS = 16;
|
|
2656
2657
|
const SUBAGENT_RESULT_MAX_BYTES = 32768;
|
|
2657
2658
|
const SHOW_RECENT_TOOLS = 8;
|
|
2658
2659
|
const SPAWN_PROMPT_DESCRIPTION = "The child's first user message and only task brief. The child starts with an empty transcript and cannot see this conversation: do not refer to prior turns, and do not paste this conversation or the product user's message unchanged. Include the goal for this child, applicable decisions and constraints, whether to edit or only report, how to verify, and every concrete identifier it needs (paths, ids, error text, commands already tried and their key results). State the exact shape of the last assistant text it should return.";
|
|
@@ -2660,8 +2661,11 @@ const SPAWN_PROMPT_DESCRIPTION = "The child's first user message and only task b
|
|
|
2660
2661
|
* Per-parent subagent supervisor. Owns every child `AgentSession` this parent
|
|
2661
2662
|
* spawns: lifecycle (spawn / steer / abort / natural end), the `demi agent`
|
|
2662
2663
|
* command tree, child shell environments, and the `subagent*` protocol frames
|
|
2663
|
-
* on the parent connection. Children
|
|
2664
|
-
* checkpoint
|
|
2664
|
+
* on the parent connection. Children persist exactly like the parent: each
|
|
2665
|
+
* live child keeps a checkpoint and job record under the parent's session
|
|
2666
|
+
* directory, and reopening the parent restores and resumes them (`restore`).
|
|
2667
|
+
* A closed child moves to the archive: its transcript checkpoint stays on
|
|
2668
|
+
* store and `demi agent resume` revives it with a new user message.
|
|
2665
2669
|
*/
|
|
2666
2670
|
var ChildSupervisor = class {
|
|
2667
2671
|
options;
|
|
@@ -2710,30 +2714,12 @@ var ChildSupervisor = class {
|
|
|
2710
2714
|
await io.stderr(`demi agent: ${errorMessage(error)}\n`);
|
|
2711
2715
|
return { exitCode: 1 };
|
|
2712
2716
|
}
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
this.pumpStdinSteers(job.id, stdinStream);
|
|
2720
|
-
const close = await job.closed;
|
|
2721
|
-
signal.removeEventListener("abort", onAbort);
|
|
2722
|
-
if (close.phase === "completed") {
|
|
2723
|
-
const text = close.result ?? "";
|
|
2724
|
-
if (parsed.json) await io.stdout(`${JSON.stringify({
|
|
2725
|
-
subagentId: job.id,
|
|
2726
|
-
text
|
|
2727
|
-
})}\n`);
|
|
2728
|
-
else if (text.length > 0) await io.stdout(text.endsWith("\n") ? text : `${text}\n`);
|
|
2729
|
-
return { exitCode: 0 };
|
|
2730
|
-
}
|
|
2731
|
-
if (close.phase === "aborted") {
|
|
2732
|
-
await io.stderr(`demi agent: subagent ${job.id} aborted\n`);
|
|
2733
|
-
return { exitCode: 130 };
|
|
2734
|
-
}
|
|
2735
|
-
await io.stderr(`demi agent: subagent ${job.id} failed: ${close.failure ?? "unknown error"}\n`);
|
|
2736
|
-
return { exitCode: 1 };
|
|
2717
|
+
return this.attendChild(job, {
|
|
2718
|
+
io,
|
|
2719
|
+
isJson: parsed.json === true,
|
|
2720
|
+
signal,
|
|
2721
|
+
stdinStream
|
|
2722
|
+
});
|
|
2737
2723
|
},
|
|
2738
2724
|
subcommands: [
|
|
2739
2725
|
{
|
|
@@ -2792,21 +2778,73 @@ var ChildSupervisor = class {
|
|
|
2792
2778
|
return { exitCode: 0 };
|
|
2793
2779
|
}
|
|
2794
2780
|
},
|
|
2781
|
+
{
|
|
2782
|
+
name: "resume",
|
|
2783
|
+
summary: "Revive an archived (finished) child with a new user message on top of its preserved transcript. Behaves like the spawn command afterwards: stays running until the child ends again, stdout is its new last assistant text, shell_write steers, shell_abort aborts. Archived ids are in `demi agent list`.",
|
|
2784
|
+
input: {
|
|
2785
|
+
id: z.string().describe("subagentId of an archived child"),
|
|
2786
|
+
message: z.string().optional().describe("The reviving user message; positional, or stdin/heredoc when omitted.")
|
|
2787
|
+
},
|
|
2788
|
+
positionals: ["id", "message"],
|
|
2789
|
+
stdinField: "message",
|
|
2790
|
+
output: { json: z.object({
|
|
2791
|
+
subagentId: z.string(),
|
|
2792
|
+
text: z.string()
|
|
2793
|
+
}) },
|
|
2794
|
+
run: async ({ parsed, io, signal, stdinStream }) => {
|
|
2795
|
+
const id = String(parsed.values.id);
|
|
2796
|
+
const message = String(parsed.values.message ?? "").trim();
|
|
2797
|
+
if (!message) {
|
|
2798
|
+
await io.stderr("demi agent resume: message must not be empty\n");
|
|
2799
|
+
return { exitCode: 1 };
|
|
2800
|
+
}
|
|
2801
|
+
let job;
|
|
2802
|
+
try {
|
|
2803
|
+
job = await this.resumeArchived(id, message);
|
|
2804
|
+
} catch (error) {
|
|
2805
|
+
await io.stderr(`demi agent resume: ${errorMessage(error)}\n`);
|
|
2806
|
+
return { exitCode: 1 };
|
|
2807
|
+
}
|
|
2808
|
+
return this.attendChild(job, {
|
|
2809
|
+
io,
|
|
2810
|
+
isJson: parsed.json === true,
|
|
2811
|
+
signal,
|
|
2812
|
+
stdinStream
|
|
2813
|
+
});
|
|
2814
|
+
}
|
|
2815
|
+
},
|
|
2795
2816
|
{
|
|
2796
2817
|
name: "list",
|
|
2797
|
-
summary: "Snapshot roster of this session's running children (finished
|
|
2798
|
-
output: { json: z.object({
|
|
2818
|
+
summary: "Snapshot roster of this session's running children, then its archived (finished, revivable via resume) children. One line per child with ages relative to now. A read, not a wait — not for polling loops.",
|
|
2819
|
+
output: { json: z.object({
|
|
2820
|
+
agents: z.array(z.unknown()),
|
|
2821
|
+
archived: z.array(z.unknown())
|
|
2822
|
+
}) },
|
|
2799
2823
|
run: async ({ parsed, io }) => {
|
|
2800
2824
|
const jobs = [...this.jobs.values()];
|
|
2825
|
+
const archived = await this.listArchivedJobs();
|
|
2801
2826
|
if (parsed.json) {
|
|
2802
|
-
await io.stdout(`${JSON.stringify({
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2827
|
+
await io.stdout(`${JSON.stringify({
|
|
2828
|
+
agents: jobs.map((job) => this.snapshot(job, false)),
|
|
2829
|
+
archived: archived.map(({ id, meta }) => ({
|
|
2830
|
+
subagentId: id,
|
|
2831
|
+
description: meta.description,
|
|
2832
|
+
profile: meta.profileName,
|
|
2833
|
+
phase: meta.closedPhase,
|
|
2834
|
+
closedAgoMs: meta.closedAt === void 0 ? null : Date.now() - meta.closedAt
|
|
2835
|
+
}))
|
|
2836
|
+
})}\n`);
|
|
2807
2837
|
return { exitCode: 0 };
|
|
2808
2838
|
}
|
|
2839
|
+
if (jobs.length === 0) await io.stdout("no running subagents\n");
|
|
2809
2840
|
for (const job of jobs) await io.stdout(`${this.renderListLine(job)}\n`);
|
|
2841
|
+
if (archived.length > 0) {
|
|
2842
|
+
await io.stdout("archived (revivable with `demi agent resume <id>`):\n");
|
|
2843
|
+
for (const { id, meta } of archived) {
|
|
2844
|
+
const closedAgo = meta.closedAt === void 0 ? "" : ` closed ${formatDuration(Date.now() - meta.closedAt)} ago`;
|
|
2845
|
+
await io.stdout(` ${id} ${meta.closedPhase}${closedAgo} ${meta.description ? `"${meta.description}"` : "(no description)"}\n`);
|
|
2846
|
+
}
|
|
2847
|
+
}
|
|
2810
2848
|
return { exitCode: 0 };
|
|
2811
2849
|
}
|
|
2812
2850
|
},
|
|
@@ -2860,9 +2898,129 @@ var ChildSupervisor = class {
|
|
|
2860
2898
|
});
|
|
2861
2899
|
}
|
|
2862
2900
|
}
|
|
2901
|
+
/**
|
|
2902
|
+
* Detaches every live child on connection teardown: aborts in-flight turns,
|
|
2903
|
+
* flushes checkpoints, and keeps the persisted job so the next open of this
|
|
2904
|
+
* parent restores it — the same dispose semantics as the parent session.
|
|
2905
|
+
* No `closed` frame is emitted: the children are not done, just paused.
|
|
2906
|
+
*/
|
|
2863
2907
|
async dispose() {
|
|
2864
2908
|
this.isDisposed = true;
|
|
2865
|
-
for (const job of [...this.jobs.values()])
|
|
2909
|
+
for (const job of [...this.jobs.values()]) {
|
|
2910
|
+
job.isClosing = true;
|
|
2911
|
+
job.unsubscribe();
|
|
2912
|
+
this.jobs.delete(job.id);
|
|
2913
|
+
await job.session.dispose().catch(noop);
|
|
2914
|
+
await this.disposeJobShells(job);
|
|
2915
|
+
job.settleClosed({ phase: "aborted" });
|
|
2916
|
+
}
|
|
2917
|
+
}
|
|
2918
|
+
/**
|
|
2919
|
+
* Rebuilds every persisted live child of this parent and finishes what it was
|
|
2920
|
+
* doing: an interrupted turn resumes from its resume point; an already
|
|
2921
|
+
* quiescent child closes with its result. Children share the parent's
|
|
2922
|
+
* persistence lifecycle — a parent restore is a child restore.
|
|
2923
|
+
*/
|
|
2924
|
+
async restore() {
|
|
2925
|
+
const parent = this.parentSession;
|
|
2926
|
+
if (!parent || this.isDisposed) return;
|
|
2927
|
+
const prefix = `agent-sessions/${parent.id()}/subagents/`;
|
|
2928
|
+
const keys = await this.options.store.list(prefix).catch(() => []);
|
|
2929
|
+
const ids = [...new Set(keys.map((key) => key.slice(prefix.length).split("/")[0] ?? "").filter(Boolean))];
|
|
2930
|
+
for (const id of ids) {
|
|
2931
|
+
if (this.jobs.has(id)) continue;
|
|
2932
|
+
try {
|
|
2933
|
+
await this.restoreJob(id);
|
|
2934
|
+
} catch {
|
|
2935
|
+
await this.deletePersistedJob(id);
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2938
|
+
}
|
|
2939
|
+
async restoreJob(id) {
|
|
2940
|
+
if (!this.parentSession) return;
|
|
2941
|
+
const meta = await this.options.store.readJson(this.childStoreKey(id, "job.json"));
|
|
2942
|
+
if (meta?.closedPhase) return;
|
|
2943
|
+
const checkpoint = await this.childSessionStore(id).loadCheckpoint();
|
|
2944
|
+
if (!meta || !checkpoint) throw new Error("incomplete persisted subagent");
|
|
2945
|
+
const job = this.reassembleJob(id, meta, checkpoint);
|
|
2946
|
+
this.watchTurn(job, job.session.resume(meta.metadata ? { metadata: meta.metadata } : {}));
|
|
2947
|
+
}
|
|
2948
|
+
/** Shared by restore and resume: rebuild a persisted child's job and session from its checkpoint. */
|
|
2949
|
+
reassembleJob(id, meta, checkpoint) {
|
|
2950
|
+
const parent = this.parentSession;
|
|
2951
|
+
if (!parent) throw new Error("subagent supervisor has no parent session");
|
|
2952
|
+
const profile = this.resolveProfile(meta.profileName ?? void 0);
|
|
2953
|
+
const { job, runtime } = this.assembleJob({
|
|
2954
|
+
id,
|
|
2955
|
+
description: meta.description,
|
|
2956
|
+
profileName: meta.profileName,
|
|
2957
|
+
profile,
|
|
2958
|
+
metadata: meta.metadata,
|
|
2959
|
+
spawnedAt: meta.spawnedAt
|
|
2960
|
+
});
|
|
2961
|
+
const session = AgentSession.fromCheckpoint({
|
|
2962
|
+
provider: parent.cloneProviderRuntime(),
|
|
2963
|
+
runtime,
|
|
2964
|
+
checkpoint
|
|
2965
|
+
}, {
|
|
2966
|
+
agentSessionId: id,
|
|
2967
|
+
store: this.childSessionStore(id),
|
|
2968
|
+
...this.options.sessionOptions
|
|
2969
|
+
});
|
|
2970
|
+
this.attachSession(job, session);
|
|
2971
|
+
return job;
|
|
2972
|
+
}
|
|
2973
|
+
/**
|
|
2974
|
+
* Revives an archived child: its job record turns live again (this round's
|
|
2975
|
+
* metadata, a fresh spawnedAt), the session rebuilds from the preserved
|
|
2976
|
+
* checkpoint, and the message opens its next turn on top of the old
|
|
2977
|
+
* transcript.
|
|
2978
|
+
*/
|
|
2979
|
+
async resumeArchived(id, message) {
|
|
2980
|
+
const parent = this.parentSession;
|
|
2981
|
+
if (!parent) throw new Error("subagent supervisor has no parent session");
|
|
2982
|
+
if (this.isDisposed) throw new Error("parent session is closing");
|
|
2983
|
+
if (this.jobs.has(id)) throw new Error(`subagent "${id}" is still running; steer it instead`);
|
|
2984
|
+
if (this.jobs.size >= 8) throw new Error(`at most 8 running subagents per session; abort one or wait for a result`);
|
|
2985
|
+
const meta = await this.options.store.readJson(this.childStoreKey(id, "job.json"));
|
|
2986
|
+
if (!meta?.closedPhase) throw new Error(`no archived subagent "${id}" (see \`demi agent list\`)`);
|
|
2987
|
+
const checkpoint = await this.childSessionStore(id).loadCheckpoint();
|
|
2988
|
+
if (!checkpoint) throw new Error(`archived subagent "${id}" has no checkpoint left`);
|
|
2989
|
+
const liveMeta = {
|
|
2990
|
+
description: meta.description,
|
|
2991
|
+
profileName: meta.profileName,
|
|
2992
|
+
metadata: parent.actionMetadata(),
|
|
2993
|
+
spawnedAt: Date.now()
|
|
2994
|
+
};
|
|
2995
|
+
await this.options.store.writeJson(this.childStoreKey(id, "job.json"), liveMeta);
|
|
2996
|
+
const job = this.reassembleJob(id, liveMeta, checkpoint);
|
|
2997
|
+
this.watchTurn(job, job.session.send([{
|
|
2998
|
+
type: "text",
|
|
2999
|
+
text: message
|
|
3000
|
+
}], liveMeta.metadata ? { metadata: liveMeta.metadata } : {}));
|
|
3001
|
+
return job;
|
|
3002
|
+
}
|
|
3003
|
+
/** Every archived (finished, revivable) child of this parent, newest first. */
|
|
3004
|
+
async listArchivedJobs() {
|
|
3005
|
+
const parent = this.parentSession;
|
|
3006
|
+
if (!parent) return [];
|
|
3007
|
+
const prefix = `agent-sessions/${parent.id()}/subagents/`;
|
|
3008
|
+
const keys = await this.options.store.list(prefix).catch(() => []);
|
|
3009
|
+
const ids = [...new Set(keys.map((key) => key.slice(prefix.length).split("/")[0] ?? "").filter(Boolean))];
|
|
3010
|
+
const archived = [];
|
|
3011
|
+
for (const id of ids) {
|
|
3012
|
+
if (this.jobs.has(id)) continue;
|
|
3013
|
+
const meta = await this.options.store.readJson(this.childStoreKey(id, "job.json"));
|
|
3014
|
+
if (meta?.closedPhase) archived.push({
|
|
3015
|
+
id,
|
|
3016
|
+
meta
|
|
3017
|
+
});
|
|
3018
|
+
}
|
|
3019
|
+
return archived.sort((a, b) => (b.meta.closedAt ?? 0) - (a.meta.closedAt ?? 0));
|
|
3020
|
+
}
|
|
3021
|
+
async pruneArchive() {
|
|
3022
|
+
const archived = await this.listArchivedJobs();
|
|
3023
|
+
for (const stale of archived.slice(16)) await this.deletePersistedJob(stale.id);
|
|
2866
3024
|
}
|
|
2867
3025
|
async abortSubtree(id) {
|
|
2868
3026
|
const job = this.jobs.get(id);
|
|
@@ -2877,6 +3035,40 @@ var ChildSupervisor = class {
|
|
|
2877
3035
|
const profile = this.resolveProfile(input.profileName);
|
|
2878
3036
|
const id = createId();
|
|
2879
3037
|
const metadata = parent.actionMetadata();
|
|
3038
|
+
const profileName = input.profileName ?? (this.options.profiles ? profile.name : null);
|
|
3039
|
+
const spawnedAt = Date.now();
|
|
3040
|
+
const { job, runtime } = this.assembleJob({
|
|
3041
|
+
id,
|
|
3042
|
+
description: input.description,
|
|
3043
|
+
profileName,
|
|
3044
|
+
profile,
|
|
3045
|
+
metadata,
|
|
3046
|
+
spawnedAt
|
|
3047
|
+
});
|
|
3048
|
+
await this.options.store.writeJson(this.childStoreKey(id, "job.json"), {
|
|
3049
|
+
description: input.description,
|
|
3050
|
+
profileName,
|
|
3051
|
+
metadata,
|
|
3052
|
+
spawnedAt
|
|
3053
|
+
});
|
|
3054
|
+
const session = new AgentSession({
|
|
3055
|
+
provider: parent.cloneProviderRuntime(),
|
|
3056
|
+
model: profile.model ?? structuredClone(parent.modelSelection),
|
|
3057
|
+
cwd: this.options.cwd,
|
|
3058
|
+
runtime,
|
|
3059
|
+
state: this.options.agent.initialState()
|
|
3060
|
+
}, {
|
|
3061
|
+
agentSessionId: id,
|
|
3062
|
+
store: this.childSessionStore(id),
|
|
3063
|
+
...this.options.sessionOptions
|
|
3064
|
+
});
|
|
3065
|
+
this.attachSession(job, session);
|
|
3066
|
+
this.watchChild(job, input.prompt);
|
|
3067
|
+
return job;
|
|
3068
|
+
}
|
|
3069
|
+
/** Everything spawn and restore share: the command tree, the harness runtime, and the job record (session attached separately). */
|
|
3070
|
+
assembleJob(input) {
|
|
3071
|
+
const { id, profile } = input;
|
|
2880
3072
|
const agentNode = this.createChildAgentNode(id, input.description);
|
|
2881
3073
|
const commands = injectSubagentCommand(profile.commands ? profile.commands([...this.options.parentCommands]) : [...this.options.parentCommands], agentNode);
|
|
2882
3074
|
const commandRegistry = new CommandRegistry();
|
|
@@ -2891,15 +3083,15 @@ var ChildSupervisor = class {
|
|
|
2891
3083
|
id,
|
|
2892
3084
|
description: input.description,
|
|
2893
3085
|
profile,
|
|
2894
|
-
profileName: input.profileName
|
|
2895
|
-
metadata,
|
|
3086
|
+
profileName: input.profileName,
|
|
3087
|
+
metadata: input.metadata,
|
|
2896
3088
|
session: null,
|
|
2897
3089
|
commandRegistry,
|
|
2898
3090
|
commandNames,
|
|
2899
3091
|
environments: /* @__PURE__ */ new Map(),
|
|
2900
3092
|
pendingEnvironments: /* @__PURE__ */ new Map(),
|
|
2901
3093
|
readonlyHosts: /* @__PURE__ */ new WeakMap(),
|
|
2902
|
-
spawnedAt:
|
|
3094
|
+
spawnedAt: input.spawnedAt,
|
|
2903
3095
|
lastEventAt: Date.now(),
|
|
2904
3096
|
tools: [],
|
|
2905
3097
|
lastAssistantTextAt: null,
|
|
@@ -2912,56 +3104,92 @@ var ChildSupervisor = class {
|
|
|
2912
3104
|
};
|
|
2913
3105
|
const agent = this.options.agent;
|
|
2914
3106
|
const preamble = this.subagentPreamble(id);
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
3107
|
+
return {
|
|
3108
|
+
job,
|
|
3109
|
+
runtime: {
|
|
3110
|
+
harnessName: agent.name,
|
|
3111
|
+
initialState: () => agent.initialState(),
|
|
3112
|
+
systemPrompt: (ctx) => (profile.systemPrompt ?? agent.systemPrompt).call(agent, {
|
|
3113
|
+
...ctx,
|
|
3114
|
+
commandsPrompt
|
|
3115
|
+
}),
|
|
3116
|
+
preamble: async (ctx) => {
|
|
3117
|
+
const inheritedPreamble = profile.systemPrompt ? null : await agent.preamble?.(ctx) ?? null;
|
|
3118
|
+
return inheritedPreamble ? `${inheritedPreamble}\n\n${preamble}` : preamble;
|
|
3119
|
+
},
|
|
3120
|
+
tools: () => createStandardAgentTools({
|
|
3121
|
+
environment: (ctx) => this.childEnvironment(job, ctx),
|
|
3122
|
+
scheduleYield: (ctx, durationMs) => job.session.scheduleYieldWakeup(durationMs, ctx.metadata)
|
|
3123
|
+
})
|
|
3124
|
+
}
|
|
2930
3125
|
};
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
runtime,
|
|
2936
|
-
state: agent.initialState()
|
|
2937
|
-
}, {
|
|
2938
|
-
agentSessionId: id,
|
|
2939
|
-
...this.options.sessionOptions
|
|
2940
|
-
});
|
|
2941
|
-
job.unsubscribe = job.session.subscribe((event) => {
|
|
3126
|
+
}
|
|
3127
|
+
attachSession(job, session) {
|
|
3128
|
+
job.session = session;
|
|
3129
|
+
job.unsubscribe = session.subscribe((event) => {
|
|
2942
3130
|
if (event.type !== "transcript_changed") return;
|
|
2943
3131
|
this.recordTelemetry(job, event.patches);
|
|
2944
3132
|
this.options.emit({
|
|
2945
3133
|
type: "subagent_transcript_patch",
|
|
2946
|
-
subagentId: id,
|
|
3134
|
+
subagentId: job.id,
|
|
2947
3135
|
patches: event.patches,
|
|
2948
3136
|
revision: event.revision
|
|
2949
3137
|
});
|
|
2950
3138
|
});
|
|
2951
|
-
this.jobs.set(id, job);
|
|
3139
|
+
this.jobs.set(job.id, job);
|
|
2952
3140
|
this.options.emit({
|
|
2953
3141
|
type: "subagent",
|
|
2954
3142
|
event: "started",
|
|
2955
3143
|
job: this.wireJob(job)
|
|
2956
3144
|
});
|
|
3145
|
+
const transcript = session.transcript();
|
|
2957
3146
|
this.options.emit({
|
|
2958
3147
|
type: "subagent_transcript_reset",
|
|
2959
|
-
subagentId: id,
|
|
2960
|
-
blocks:
|
|
2961
|
-
revision:
|
|
3148
|
+
subagentId: job.id,
|
|
3149
|
+
blocks: structuredClone(transcript.blocks),
|
|
3150
|
+
revision: transcript.revision
|
|
2962
3151
|
});
|
|
2963
|
-
|
|
2964
|
-
|
|
3152
|
+
}
|
|
3153
|
+
childStoreKey(childId, file) {
|
|
3154
|
+
return `agent-sessions/${this.parentSession?.id() ?? ""}/subagents/${childId}/${file}`;
|
|
3155
|
+
}
|
|
3156
|
+
childSessionStore(childId) {
|
|
3157
|
+
return {
|
|
3158
|
+
saveCheckpoint: (checkpoint) => this.options.store.writeJson(this.childStoreKey(childId, "checkpoint.json"), checkpoint),
|
|
3159
|
+
loadCheckpoint: () => this.options.store.readJson(this.childStoreKey(childId, "checkpoint.json"))
|
|
3160
|
+
};
|
|
3161
|
+
}
|
|
3162
|
+
async deletePersistedJob(id) {
|
|
3163
|
+
await this.options.store.delete(this.childStoreKey(id, "checkpoint.json")).catch(noop);
|
|
3164
|
+
await this.options.store.delete(this.childStoreKey(id, "job.json")).catch(noop);
|
|
3165
|
+
}
|
|
3166
|
+
/** Shared spawn/resume foreground behaviour: announce the id, wire abort and stdin steers, wait for close, report the outcome. */
|
|
3167
|
+
async attendChild(job, ctx) {
|
|
3168
|
+
const { io, isJson, signal, stdinStream } = ctx;
|
|
3169
|
+
await io.stderr(`subagentId: ${job.id}\n`);
|
|
3170
|
+
const onAbort = () => {
|
|
3171
|
+
this.abortSubtree(job.id).catch(noop);
|
|
3172
|
+
};
|
|
3173
|
+
if (signal.aborted) onAbort();
|
|
3174
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
3175
|
+
this.pumpStdinSteers(job.id, stdinStream);
|
|
3176
|
+
const close = await job.closed;
|
|
3177
|
+
signal.removeEventListener("abort", onAbort);
|
|
3178
|
+
if (close.phase === "completed") {
|
|
3179
|
+
const text = close.result ?? "";
|
|
3180
|
+
if (isJson) await io.stdout(`${JSON.stringify({
|
|
3181
|
+
subagentId: job.id,
|
|
3182
|
+
text
|
|
3183
|
+
})}\n`);
|
|
3184
|
+
else if (text.length > 0) await io.stdout(text.endsWith("\n") ? text : `${text}\n`);
|
|
3185
|
+
return { exitCode: 0 };
|
|
3186
|
+
}
|
|
3187
|
+
if (close.phase === "aborted") {
|
|
3188
|
+
await io.stderr(`demi agent: subagent ${job.id} aborted\n`);
|
|
3189
|
+
return { exitCode: 130 };
|
|
3190
|
+
}
|
|
3191
|
+
await io.stderr(`demi agent: subagent ${job.id} failed: ${close.failure ?? "unknown error"}\n`);
|
|
3192
|
+
return { exitCode: 1 };
|
|
2965
3193
|
}
|
|
2966
3194
|
/** Delivers one steer to a child: mid-turn as a steer, idle as a new user turn. */
|
|
2967
3195
|
async steerChild(job, message) {
|
|
@@ -3028,12 +3256,16 @@ var ChildSupervisor = class {
|
|
|
3028
3256
|
this.jobs.delete(job.id);
|
|
3029
3257
|
const result = phase === "completed" ? boundedResultText(lastAssistantText(job.session.transcript().blocks)) : void 0;
|
|
3030
3258
|
await job.session.dispose().catch(noop);
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3259
|
+
await this.disposeJobShells(job);
|
|
3260
|
+
await this.options.store.writeJson(this.childStoreKey(job.id, "job.json"), {
|
|
3261
|
+
description: job.description,
|
|
3262
|
+
profileName: job.profileName,
|
|
3263
|
+
metadata: job.metadata,
|
|
3264
|
+
spawnedAt: job.spawnedAt,
|
|
3265
|
+
closedPhase: phase,
|
|
3266
|
+
closedAt: Date.now()
|
|
3267
|
+
}).catch(noop);
|
|
3268
|
+
await this.pruneArchive().catch(noop);
|
|
3037
3269
|
const close = {
|
|
3038
3270
|
phase,
|
|
3039
3271
|
...result !== void 0 ? { result } : {},
|
|
@@ -3047,6 +3279,14 @@ var ChildSupervisor = class {
|
|
|
3047
3279
|
job.settleClosed(close);
|
|
3048
3280
|
this.notifyIdleParent(job, close);
|
|
3049
3281
|
}
|
|
3282
|
+
async disposeJobShells(job) {
|
|
3283
|
+
const environments = /* @__PURE__ */ new Set([...job.environments.values()]);
|
|
3284
|
+
for (const pending of job.pendingEnvironments.values()) {
|
|
3285
|
+
const environment = await pending.catch(() => null);
|
|
3286
|
+
if (environment) environments.add(environment);
|
|
3287
|
+
}
|
|
3288
|
+
for (const environment of environments) await environment.disposeAllShells().catch(noop);
|
|
3289
|
+
}
|
|
3050
3290
|
/** Wakes an idle parent with a user send; a parent blocked in the spawn gets the tool result instead. */
|
|
3051
3291
|
notifyIdleParent(job, close) {
|
|
3052
3292
|
if (this.isDisposed || !this.options.notifyParentOnIdle) return;
|
|
@@ -3308,6 +3548,7 @@ var ChildSupervisor = class {
|
|
|
3308
3548
|
description: job.description,
|
|
3309
3549
|
profile: job.profileName,
|
|
3310
3550
|
phase: job.phase,
|
|
3551
|
+
metadata: job.metadata,
|
|
3311
3552
|
...result !== void 0 ? { result } : {}
|
|
3312
3553
|
};
|
|
3313
3554
|
}
|
|
@@ -3738,10 +3979,11 @@ var AgentTransportBindingImpl = class {
|
|
|
3738
3979
|
await this.sessions.claim(agentSessionId, this);
|
|
3739
3980
|
this.currentSessionId = agentSessionId;
|
|
3740
3981
|
const initialState = agent.initialState();
|
|
3741
|
-
const
|
|
3982
|
+
const provisionalHost = await agent.host({
|
|
3742
3983
|
state: initialState,
|
|
3743
3984
|
cwd: frame.cwd
|
|
3744
|
-
})
|
|
3985
|
+
});
|
|
3986
|
+
const store = new HostAgentSessionStore(provisionalHost.store, agentSessionId);
|
|
3745
3987
|
const checkpoint = await store.loadCheckpoint();
|
|
3746
3988
|
const restoring = checkpoint !== null && checkpoint.harnessName === agent.name;
|
|
3747
3989
|
const state = restoring ? structuredClone(checkpoint.state) : initialState;
|
|
@@ -3760,6 +4002,7 @@ var AgentTransportBindingImpl = class {
|
|
|
3760
4002
|
prepareShell: this.prepareShell,
|
|
3761
4003
|
sessionOptions: this.sessionOptions,
|
|
3762
4004
|
notifyParentOnIdle: this.notifyParentOnIdle,
|
|
4005
|
+
store: provisionalHost.store,
|
|
3763
4006
|
emit: (subagentFrame) => this.send(subagentFrame)
|
|
3764
4007
|
});
|
|
3765
4008
|
const commands = injectSubagentCommand(harnessCommands, supervisor.rootCommandNode());
|
|
@@ -3830,6 +4073,7 @@ var AgentTransportBindingImpl = class {
|
|
|
3830
4073
|
type: "queue",
|
|
3831
4074
|
queue: this.session.queuedMessages()
|
|
3832
4075
|
});
|
|
4076
|
+
if (restoring) await supervisor.restore();
|
|
3833
4077
|
}
|
|
3834
4078
|
sendTranscriptReset(session) {
|
|
3835
4079
|
const transcript = session.transcript();
|
|
@@ -4247,4 +4491,4 @@ function createProviderMap(providers) {
|
|
|
4247
4491
|
return map;
|
|
4248
4492
|
}
|
|
4249
4493
|
//#endregion
|
|
4250
|
-
export { AgentClient, AgentServer, AgentSession, ChildSupervisor, DEFAULT_MAX_MEDIA_BYTES, DEFAULT_TURN_RETRY_POLICY, MAX_LIVE_SUBAGENTS, ProviderStreamError, RunCommandLineCommandNotRegisteredError, RunCommandLineShellNotFoundError, RunCommandLineTimeoutError, SHELL_VIEW_MAX_CHARS, SUBAGENT_RESULT_MAX_BYTES, TranscriptLog, applyTranscriptPatches, cloneBlocks, createInProcessTransportPair, createReadonlyHost, createStandardAgentTools, createWebSocketClientTransport, createWebSocketServerTransport, estimateTranscriptBlockTokens, findResumePoint, finishShellToolResult, injectSubagentCommand, isContextLengthExceeded, isRetryableCode, resolveRetryPolicy, retryDelayMs, shellCommandHandleRequired, shellPreviewBudgetTokens, toShellToolResult };
|
|
4494
|
+
export { AgentClient, AgentServer, AgentSession, ChildSupervisor, DEFAULT_MAX_MEDIA_BYTES, DEFAULT_TURN_RETRY_POLICY, MAX_ARCHIVED_SUBAGENTS, MAX_LIVE_SUBAGENTS, ProviderStreamError, RunCommandLineCommandNotRegisteredError, RunCommandLineShellNotFoundError, RunCommandLineTimeoutError, SHELL_VIEW_MAX_CHARS, SUBAGENT_RESULT_MAX_BYTES, TranscriptLog, applyTranscriptPatches, cloneBlocks, createInProcessTransportPair, createReadonlyHost, createStandardAgentTools, createWebSocketClientTransport, createWebSocketServerTransport, estimateTranscriptBlockTokens, findResumePoint, finishShellToolResult, injectSubagentCommand, isContextLengthExceeded, isRetryableCode, resolveRetryPolicy, retryDelayMs, shellCommandHandleRequired, shellPreviewBudgetTokens, toShellToolResult };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as AgentServerTransport, t as AgentClientTransport } from "./transport-
|
|
1
|
+
import { n as AgentServerTransport, t as AgentClientTransport } from "./transport-CHrPzcrU.mjs";
|
|
2
2
|
import { Readable, Writable } from "node:stream";
|
|
3
3
|
//#region src/stdio-transport.d.ts
|
|
4
4
|
declare function createStdioClientTransport(readable: Readable, writable: Writable): AgentClientTransport;
|
|
@@ -398,6 +398,8 @@ interface SubagentJob {
|
|
|
398
398
|
description: string;
|
|
399
399
|
profile: string | null;
|
|
400
400
|
phase: 'running' | 'completed' | 'aborted' | 'error';
|
|
401
|
+
/** Action metadata of the round that spawned the child. */
|
|
402
|
+
metadata: AgentMetadata | null;
|
|
401
403
|
/** Present on `closed`: the child's last assistant text, at most 32 KiB. */
|
|
402
404
|
result?: string;
|
|
403
405
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { I as ModelSwitchApply, c as ConversationSummary, n as AgentServerTransport, p as AbortResult, s as ClientSessionEvent, t as AgentClientTransport, x as AgentMetadata } from "./transport-
|
|
1
|
+
import { I as ModelSwitchApply, c as ConversationSummary, n as AgentServerTransport, p as AbortResult, s as ClientSessionEvent, t as AgentClientTransport, x as AgentMetadata } from "./transport-CHrPzcrU.mjs";
|
|
2
2
|
import { ProviderSelection } from "@demicodes/provider";
|
|
3
3
|
import { Block, UserContentBlock } from "@demicodes/core";
|
|
4
4
|
//#region src/client.d.ts
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@demicodes/agent",
|
|
3
3
|
"description": "Session runtime and transport-neutral client and server protocol for Demi.",
|
|
4
|
-
"version": "0.19.
|
|
4
|
+
"version": "0.19.3",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
7
7
|
"exports": {
|
|
@@ -19,10 +19,10 @@
|
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@demicodes/core": "^0.19.
|
|
23
|
-
"@demicodes/provider": "^0.19.
|
|
24
|
-
"@demicodes/shell": "^0.19.
|
|
25
|
-
"@demicodes/utils": "^0.19.
|
|
22
|
+
"@demicodes/core": "^0.19.3",
|
|
23
|
+
"@demicodes/provider": "^0.19.3",
|
|
24
|
+
"@demicodes/shell": "^0.19.3",
|
|
25
|
+
"@demicodes/utils": "^0.19.3",
|
|
26
26
|
"zod": "^4.0.0"
|
|
27
27
|
},
|
|
28
28
|
"license": "Apache-2.0",
|