@demicodes/agent 0.19.1 → 0.19.2

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.
@@ -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-BRqZoaeo.mjs";
2
- import { a as AgentClient, i as AgentActionOptions, n as createWebSocketClientTransport, o as AgentClientListener, r as createWebSocketServerTransport, t as JsonWebSocket } from "./websocket-transport-C6Y5CeLG.mjs";
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-BRqZoaeo.mjs";
2
- import { a as AgentClient, i as AgentActionOptions, n as createWebSocketClientTransport, o as AgentClientListener, r as createWebSocketServerTransport, t as JsonWebSocket } from "./websocket-transport-C6Y5CeLG.mjs";
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
@@ -353,14 +353,18 @@ interface ChildSupervisorOptions<State> {
353
353
  sessionOptions: AgentServerSessionOptions;
354
354
  /** When false, a child closing never wakes an idle parent; the host app orchestrates the wakeup from the `subagent closed` frame. */
355
355
  notifyParentOnIdle: boolean;
356
+ /** Backing store for child checkpoints and job metadata, keyed under the parent's session directory. */
357
+ store: HostStore;
356
358
  emit(frame: ServerFrame): void;
357
359
  }
358
360
  /**
359
361
  * Per-parent subagent supervisor. Owns every child `AgentSession` this parent
360
362
  * spawns: lifecycle (spawn / steer / abort / natural end), the `demi agent`
361
363
  * command tree, child shell environments, and the `subagent*` protocol frames
362
- * on the parent connection. Children are in-memory only: no store, no
363
- * checkpoint, gone with the parent.
364
+ * on the parent connection. Children persist exactly like the parent: each
365
+ * live child keeps a checkpoint and job record under the parent's session
366
+ * directory, and reopening the parent restores and resumes them (`restore`).
367
+ * A closed child leaves nothing behind.
364
368
  */
365
369
  declare class ChildSupervisor<State = unknown> {
366
370
  private readonly options;
@@ -380,9 +384,29 @@ declare class ChildSupervisor<State = unknown> {
380
384
  } | null;
381
385
  /** Re-emits `subagent started` + transcript reset for every running child (transcript resync). */
382
386
  replay(): void;
387
+ /**
388
+ * Detaches every live child on connection teardown: aborts in-flight turns,
389
+ * flushes checkpoints, and keeps the persisted job so the next open of this
390
+ * parent restores it — the same dispose semantics as the parent session.
391
+ * No `closed` frame is emitted: the children are not done, just paused.
392
+ */
383
393
  dispose(): Promise<void>;
394
+ /**
395
+ * Rebuilds every persisted live child of this parent and finishes what it was
396
+ * doing: an interrupted turn resumes from its resume point; an already
397
+ * quiescent child closes with its result. Children share the parent's
398
+ * persistence lifecycle — a parent restore is a child restore.
399
+ */
400
+ restore(): Promise<void>;
401
+ private restoreJob;
384
402
  abortSubtree(id: string): Promise<void>;
385
403
  private spawn;
404
+ /** Everything spawn and restore share: the command tree, the harness runtime, and the job record (session attached separately). */
405
+ private assembleJob;
406
+ private attachSession;
407
+ private childStoreKey;
408
+ private childSessionStore;
409
+ private deletePersistedJob;
386
410
  /** Delivers one steer to a child: mid-turn as a steer, idle as a new user turn. */
387
411
  private steerChild;
388
412
  private pumpStdinSteers;
@@ -392,6 +416,7 @@ declare class ChildSupervisor<State = unknown> {
392
416
  /** Resolves when the child is idle with no pending yield wakeups (or the job closed). */
393
417
  private waitForQuiescence;
394
418
  private closeJob;
419
+ private disposeJobShells;
395
420
  /** Wakes an idle parent with a user send; a parent blocked in the spawn gets the tool result instead. */
396
421
  private notifyIdleParent;
397
422
  private createChildAgentNode;
package/dist/index.mjs CHANGED
@@ -2660,8 +2660,10 @@ const SPAWN_PROMPT_DESCRIPTION = "The child's first user message and only task b
2660
2660
  * Per-parent subagent supervisor. Owns every child `AgentSession` this parent
2661
2661
  * spawns: lifecycle (spawn / steer / abort / natural end), the `demi agent`
2662
2662
  * command tree, child shell environments, and the `subagent*` protocol frames
2663
- * on the parent connection. Children are in-memory only: no store, no
2664
- * checkpoint, gone with the parent.
2663
+ * on the parent connection. Children persist exactly like the parent: each
2664
+ * live child keeps a checkpoint and job record under the parent's session
2665
+ * directory, and reopening the parent restores and resumes them (`restore`).
2666
+ * A closed child leaves nothing behind.
2665
2667
  */
2666
2668
  var ChildSupervisor = class {
2667
2669
  options;
@@ -2860,9 +2862,70 @@ var ChildSupervisor = class {
2860
2862
  });
2861
2863
  }
2862
2864
  }
2865
+ /**
2866
+ * Detaches every live child on connection teardown: aborts in-flight turns,
2867
+ * flushes checkpoints, and keeps the persisted job so the next open of this
2868
+ * parent restores it — the same dispose semantics as the parent session.
2869
+ * No `closed` frame is emitted: the children are not done, just paused.
2870
+ */
2863
2871
  async dispose() {
2864
2872
  this.isDisposed = true;
2865
- for (const job of [...this.jobs.values()]) await this.closeJob(job, "aborted");
2873
+ for (const job of [...this.jobs.values()]) {
2874
+ job.isClosing = true;
2875
+ job.unsubscribe();
2876
+ this.jobs.delete(job.id);
2877
+ await job.session.dispose().catch(noop);
2878
+ await this.disposeJobShells(job);
2879
+ job.settleClosed({ phase: "aborted" });
2880
+ }
2881
+ }
2882
+ /**
2883
+ * Rebuilds every persisted live child of this parent and finishes what it was
2884
+ * doing: an interrupted turn resumes from its resume point; an already
2885
+ * quiescent child closes with its result. Children share the parent's
2886
+ * persistence lifecycle — a parent restore is a child restore.
2887
+ */
2888
+ async restore() {
2889
+ const parent = this.parentSession;
2890
+ if (!parent || this.isDisposed) return;
2891
+ const prefix = `agent-sessions/${parent.id()}/subagents/`;
2892
+ const keys = await this.options.store.list(prefix).catch(() => []);
2893
+ const ids = [...new Set(keys.map((key) => key.slice(prefix.length).split("/")[0] ?? "").filter(Boolean))];
2894
+ for (const id of ids) {
2895
+ if (this.jobs.has(id)) continue;
2896
+ try {
2897
+ await this.restoreJob(id);
2898
+ } catch {
2899
+ await this.deletePersistedJob(id);
2900
+ }
2901
+ }
2902
+ }
2903
+ async restoreJob(id) {
2904
+ const parent = this.parentSession;
2905
+ if (!parent) return;
2906
+ const meta = await this.options.store.readJson(this.childStoreKey(id, "job.json"));
2907
+ const checkpoint = await this.childSessionStore(id).loadCheckpoint();
2908
+ if (!meta || !checkpoint) throw new Error("incomplete persisted subagent");
2909
+ const profile = this.resolveProfile(meta.profileName ?? void 0);
2910
+ const { job, runtime } = this.assembleJob({
2911
+ id,
2912
+ description: meta.description,
2913
+ profileName: meta.profileName,
2914
+ profile,
2915
+ metadata: meta.metadata,
2916
+ spawnedAt: meta.spawnedAt
2917
+ });
2918
+ const session = AgentSession.fromCheckpoint({
2919
+ provider: parent.cloneProviderRuntime(),
2920
+ runtime,
2921
+ checkpoint
2922
+ }, {
2923
+ agentSessionId: id,
2924
+ store: this.childSessionStore(id),
2925
+ ...this.options.sessionOptions
2926
+ });
2927
+ this.attachSession(job, session);
2928
+ this.watchTurn(job, session.resume(meta.metadata ? { metadata: meta.metadata } : {}));
2866
2929
  }
2867
2930
  async abortSubtree(id) {
2868
2931
  const job = this.jobs.get(id);
@@ -2877,6 +2940,40 @@ var ChildSupervisor = class {
2877
2940
  const profile = this.resolveProfile(input.profileName);
2878
2941
  const id = createId();
2879
2942
  const metadata = parent.actionMetadata();
2943
+ const profileName = input.profileName ?? (this.options.profiles ? profile.name : null);
2944
+ const spawnedAt = Date.now();
2945
+ const { job, runtime } = this.assembleJob({
2946
+ id,
2947
+ description: input.description,
2948
+ profileName,
2949
+ profile,
2950
+ metadata,
2951
+ spawnedAt
2952
+ });
2953
+ await this.options.store.writeJson(this.childStoreKey(id, "job.json"), {
2954
+ description: input.description,
2955
+ profileName,
2956
+ metadata,
2957
+ spawnedAt
2958
+ });
2959
+ const session = new AgentSession({
2960
+ provider: parent.cloneProviderRuntime(),
2961
+ model: profile.model ?? structuredClone(parent.modelSelection),
2962
+ cwd: this.options.cwd,
2963
+ runtime,
2964
+ state: this.options.agent.initialState()
2965
+ }, {
2966
+ agentSessionId: id,
2967
+ store: this.childSessionStore(id),
2968
+ ...this.options.sessionOptions
2969
+ });
2970
+ this.attachSession(job, session);
2971
+ this.watchChild(job, input.prompt);
2972
+ return job;
2973
+ }
2974
+ /** Everything spawn and restore share: the command tree, the harness runtime, and the job record (session attached separately). */
2975
+ assembleJob(input) {
2976
+ const { id, profile } = input;
2880
2977
  const agentNode = this.createChildAgentNode(id, input.description);
2881
2978
  const commands = injectSubagentCommand(profile.commands ? profile.commands([...this.options.parentCommands]) : [...this.options.parentCommands], agentNode);
2882
2979
  const commandRegistry = new CommandRegistry();
@@ -2891,15 +2988,15 @@ var ChildSupervisor = class {
2891
2988
  id,
2892
2989
  description: input.description,
2893
2990
  profile,
2894
- profileName: input.profileName ?? (this.options.profiles ? profile.name : null),
2895
- metadata,
2991
+ profileName: input.profileName,
2992
+ metadata: input.metadata,
2896
2993
  session: null,
2897
2994
  commandRegistry,
2898
2995
  commandNames,
2899
2996
  environments: /* @__PURE__ */ new Map(),
2900
2997
  pendingEnvironments: /* @__PURE__ */ new Map(),
2901
2998
  readonlyHosts: /* @__PURE__ */ new WeakMap(),
2902
- spawnedAt: Date.now(),
2999
+ spawnedAt: input.spawnedAt,
2903
3000
  lastEventAt: Date.now(),
2904
3001
  tools: [],
2905
3002
  lastAssistantTextAt: null,
@@ -2912,56 +3009,64 @@ var ChildSupervisor = class {
2912
3009
  };
2913
3010
  const agent = this.options.agent;
2914
3011
  const preamble = this.subagentPreamble(id);
2915
- const runtime = {
2916
- harnessName: agent.name,
2917
- initialState: () => agent.initialState(),
2918
- systemPrompt: (ctx) => (profile.systemPrompt ?? agent.systemPrompt).call(agent, {
2919
- ...ctx,
2920
- commandsPrompt
2921
- }),
2922
- preamble: async (ctx) => {
2923
- const inheritedPreamble = profile.systemPrompt ? null : await agent.preamble?.(ctx) ?? null;
2924
- return inheritedPreamble ? `${inheritedPreamble}\n\n${preamble}` : preamble;
2925
- },
2926
- tools: () => createStandardAgentTools({
2927
- environment: (ctx) => this.childEnvironment(job, ctx),
2928
- scheduleYield: (ctx, durationMs) => job.session.scheduleYieldWakeup(durationMs, ctx.metadata)
2929
- })
3012
+ return {
3013
+ job,
3014
+ runtime: {
3015
+ harnessName: agent.name,
3016
+ initialState: () => agent.initialState(),
3017
+ systemPrompt: (ctx) => (profile.systemPrompt ?? agent.systemPrompt).call(agent, {
3018
+ ...ctx,
3019
+ commandsPrompt
3020
+ }),
3021
+ preamble: async (ctx) => {
3022
+ const inheritedPreamble = profile.systemPrompt ? null : await agent.preamble?.(ctx) ?? null;
3023
+ return inheritedPreamble ? `${inheritedPreamble}\n\n${preamble}` : preamble;
3024
+ },
3025
+ tools: () => createStandardAgentTools({
3026
+ environment: (ctx) => this.childEnvironment(job, ctx),
3027
+ scheduleYield: (ctx, durationMs) => job.session.scheduleYieldWakeup(durationMs, ctx.metadata)
3028
+ })
3029
+ }
2930
3030
  };
2931
- job.session = new AgentSession({
2932
- provider: parent.cloneProviderRuntime(),
2933
- model: profile.model ?? structuredClone(parent.modelSelection),
2934
- cwd: this.options.cwd,
2935
- runtime,
2936
- state: agent.initialState()
2937
- }, {
2938
- agentSessionId: id,
2939
- ...this.options.sessionOptions
2940
- });
2941
- job.unsubscribe = job.session.subscribe((event) => {
3031
+ }
3032
+ attachSession(job, session) {
3033
+ job.session = session;
3034
+ job.unsubscribe = session.subscribe((event) => {
2942
3035
  if (event.type !== "transcript_changed") return;
2943
3036
  this.recordTelemetry(job, event.patches);
2944
3037
  this.options.emit({
2945
3038
  type: "subagent_transcript_patch",
2946
- subagentId: id,
3039
+ subagentId: job.id,
2947
3040
  patches: event.patches,
2948
3041
  revision: event.revision
2949
3042
  });
2950
3043
  });
2951
- this.jobs.set(id, job);
3044
+ this.jobs.set(job.id, job);
2952
3045
  this.options.emit({
2953
3046
  type: "subagent",
2954
3047
  event: "started",
2955
3048
  job: this.wireJob(job)
2956
3049
  });
3050
+ const transcript = session.transcript();
2957
3051
  this.options.emit({
2958
3052
  type: "subagent_transcript_reset",
2959
- subagentId: id,
2960
- blocks: [],
2961
- revision: 0
3053
+ subagentId: job.id,
3054
+ blocks: structuredClone(transcript.blocks),
3055
+ revision: transcript.revision
2962
3056
  });
2963
- this.watchChild(job, input.prompt);
2964
- return job;
3057
+ }
3058
+ childStoreKey(childId, file) {
3059
+ return `agent-sessions/${this.parentSession?.id() ?? ""}/subagents/${childId}/${file}`;
3060
+ }
3061
+ childSessionStore(childId) {
3062
+ return {
3063
+ saveCheckpoint: (checkpoint) => this.options.store.writeJson(this.childStoreKey(childId, "checkpoint.json"), checkpoint),
3064
+ loadCheckpoint: () => this.options.store.readJson(this.childStoreKey(childId, "checkpoint.json"))
3065
+ };
3066
+ }
3067
+ async deletePersistedJob(id) {
3068
+ await this.options.store.delete(this.childStoreKey(id, "checkpoint.json")).catch(noop);
3069
+ await this.options.store.delete(this.childStoreKey(id, "job.json")).catch(noop);
2965
3070
  }
2966
3071
  /** Delivers one steer to a child: mid-turn as a steer, idle as a new user turn. */
2967
3072
  async steerChild(job, message) {
@@ -3028,12 +3133,8 @@ var ChildSupervisor = class {
3028
3133
  this.jobs.delete(job.id);
3029
3134
  const result = phase === "completed" ? boundedResultText(lastAssistantText(job.session.transcript().blocks)) : void 0;
3030
3135
  await job.session.dispose().catch(noop);
3031
- const environments = /* @__PURE__ */ new Set([...job.environments.values()]);
3032
- for (const pending of job.pendingEnvironments.values()) {
3033
- const environment = await pending.catch(() => null);
3034
- if (environment) environments.add(environment);
3035
- }
3036
- for (const environment of environments) await environment.disposeAllShells().catch(noop);
3136
+ await this.disposeJobShells(job);
3137
+ await this.deletePersistedJob(job.id);
3037
3138
  const close = {
3038
3139
  phase,
3039
3140
  ...result !== void 0 ? { result } : {},
@@ -3047,6 +3148,14 @@ var ChildSupervisor = class {
3047
3148
  job.settleClosed(close);
3048
3149
  this.notifyIdleParent(job, close);
3049
3150
  }
3151
+ async disposeJobShells(job) {
3152
+ const environments = /* @__PURE__ */ new Set([...job.environments.values()]);
3153
+ for (const pending of job.pendingEnvironments.values()) {
3154
+ const environment = await pending.catch(() => null);
3155
+ if (environment) environments.add(environment);
3156
+ }
3157
+ for (const environment of environments) await environment.disposeAllShells().catch(noop);
3158
+ }
3050
3159
  /** Wakes an idle parent with a user send; a parent blocked in the spawn gets the tool result instead. */
3051
3160
  notifyIdleParent(job, close) {
3052
3161
  if (this.isDisposed || !this.options.notifyParentOnIdle) return;
@@ -3308,6 +3417,7 @@ var ChildSupervisor = class {
3308
3417
  description: job.description,
3309
3418
  profile: job.profileName,
3310
3419
  phase: job.phase,
3420
+ metadata: job.metadata,
3311
3421
  ...result !== void 0 ? { result } : {}
3312
3422
  };
3313
3423
  }
@@ -3738,10 +3848,11 @@ var AgentTransportBindingImpl = class {
3738
3848
  await this.sessions.claim(agentSessionId, this);
3739
3849
  this.currentSessionId = agentSessionId;
3740
3850
  const initialState = agent.initialState();
3741
- const store = new HostAgentSessionStore((await agent.host({
3851
+ const provisionalHost = await agent.host({
3742
3852
  state: initialState,
3743
3853
  cwd: frame.cwd
3744
- })).store, agentSessionId);
3854
+ });
3855
+ const store = new HostAgentSessionStore(provisionalHost.store, agentSessionId);
3745
3856
  const checkpoint = await store.loadCheckpoint();
3746
3857
  const restoring = checkpoint !== null && checkpoint.harnessName === agent.name;
3747
3858
  const state = restoring ? structuredClone(checkpoint.state) : initialState;
@@ -3760,6 +3871,7 @@ var AgentTransportBindingImpl = class {
3760
3871
  prepareShell: this.prepareShell,
3761
3872
  sessionOptions: this.sessionOptions,
3762
3873
  notifyParentOnIdle: this.notifyParentOnIdle,
3874
+ store: provisionalHost.store,
3763
3875
  emit: (subagentFrame) => this.send(subagentFrame)
3764
3876
  });
3765
3877
  const commands = injectSubagentCommand(harnessCommands, supervisor.rootCommandNode());
@@ -3830,6 +3942,7 @@ var AgentTransportBindingImpl = class {
3830
3942
  type: "queue",
3831
3943
  queue: this.session.queuedMessages()
3832
3944
  });
3945
+ if (restoring) await supervisor.restore();
3833
3946
  }
3834
3947
  sendTranscriptReset(session) {
3835
3948
  const transcript = session.transcript();
@@ -1,4 +1,4 @@
1
- import { n as AgentServerTransport, t as AgentClientTransport } from "./transport-BRqZoaeo.mjs";
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-BRqZoaeo.mjs";
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.1",
4
+ "version": "0.19.2",
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.1",
23
- "@demicodes/provider": "^0.19.1",
24
- "@demicodes/shell": "^0.19.1",
25
- "@demicodes/utils": "^0.19.1",
22
+ "@demicodes/core": "^0.19.2",
23
+ "@demicodes/provider": "^0.19.2",
24
+ "@demicodes/shell": "^0.19.2",
25
+ "@demicodes/utils": "^0.19.2",
26
26
  "zod": "^4.0.0"
27
27
  },
28
28
  "license": "Apache-2.0",