@xneog/dsh-subagent 0.1.2-rc.1 → 0.1.3-alpha.1

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/lib/index.js CHANGED
@@ -1,13 +1,13 @@
1
- import { AttachmentError, admitPromptContent } from "@xneog/dsh-attachment";
2
1
  import { scopeTarget } from "@xneog/dsh-scope";
3
2
  import { assertObjectJsonSchema } from "@xneog/dsh-tools";
4
3
  import { canonicalClientTimeZone } from "@xneog/dsh-util-time";
5
4
  import { Remote, RemoteError, TypertRemoteService } from "@xneog/dsh-typert-protocol";
5
+ import { AttachmentError } from "@xneog/dsh-attachment";
6
6
  import { z } from "zod";
7
- import { HarnessError, ReasoningEffortId, boundContextSummary, contentHasImage, createUserMessage, errorChain } from "@xneog/dsh-llm";
7
+ import { HarnessError, ReasoningEffortId, boundContextSummary, contentHasImage, createUserMessage, errorChain, expandAssistantStream } from "@xneog/dsh-llm";
8
8
  import { randomUUID } from "node:crypto";
9
9
  import { foldConsumedWork } from "@xneog/dsh-agent";
10
- import { Session, SessionLogOffset, SessionSeq } from "@xneog/dsh-session";
10
+ import { SessionLogOffset, SessionSeq } from "@xneog/dsh-session";
11
11
  import { brandString } from "@xneog/dsh-brand";
12
12
  import { snapshotJsonValue } from "@xneog/dsh-util-values";
13
13
  import { accessSync, constants, statSync } from "node:fs";
@@ -175,15 +175,18 @@ var AssistantOutputFold = class {
175
175
  partial = [];
176
176
  /**
177
177
  * Fold one session event: a non-empty assistant message becomes the
178
- * candidate final answer, and a `text-delta` chunk extends the streamed
179
- * fallback; every other event contributes nothing.
178
+ * candidate final answer, while its embedded stream and any log-only attempt
179
+ * extend the streamed fallback; every other event contributes nothing.
180
180
  * @param event - the next observed session event.
181
181
  */
182
182
  push(event) {
183
183
  if (event.type === "assistant/message") {
184
184
  const content = event.data.message.content;
185
185
  if (content.length > 0) this.message = content;
186
- } else if (event.type === "assistant/chunk" && event.data.chunk.type === "text-delta") this.pushText(event.data.chunk.text);
186
+ }
187
+ if (event.type === "assistant/message" || event.type === "assistant/attempt") {
188
+ for (const { chunk } of expandAssistantStream(event.data.stream)) if (chunk.type === "text-delta") this.pushText(chunk.text);
189
+ }
187
190
  }
188
191
  /**
189
192
  * Extend the streamed fallback with text observed outside session events.
@@ -746,30 +749,6 @@ function appendDelegatedPolicyOverrides(childSession, overrides) {
746
749
  });
747
750
  }
748
751
  //#endregion
749
- //#region lib/types/descriptor-seed.js
750
- /**
751
- * Seeding of a continuable child's durable descriptor event: the model-hidden
752
- * record of the child's declared composition before its first request, so a
753
- * later cold resume can reconstruct it from its own log.
754
- *
755
- * @module @xneog/dsh-subagent/descriptor-seed
756
- */
757
- /**
758
- * Build the child's creation seed: any inherited parent-history prefix followed
759
- * by one model-hidden, between-turn `descriptor` event. Staging through a
760
- * `Session` assigns the sequence number and enforces the same lossless-JSON
761
- * rules the durable log does.
762
- * @param childId - the reserved child session id the staged log belongs to.
763
- * @param seed - the inherited completed-turn prefix, or `undefined` for a fresh child.
764
- * @param descriptor - the snapshotted composition record to persist.
765
- * @returns the complete seed events, contiguous from sequence zero.
766
- */
767
- function seedDescriptorTurn(childId, seed, descriptor) {
768
- const staged = Session.create(childId, seed);
769
- staged.append("subagent/descriptor", descriptor);
770
- return staged.snapshotEvents();
771
- }
772
- //#endregion
773
752
  //#region lib/types/internal.js
774
753
  /**
775
754
  * Continuation integration markers and host adapters outside the public
@@ -1036,7 +1015,7 @@ var SubagentContinuationManager = class {
1036
1015
  spec.signal.throwIfAborted();
1037
1016
  this.assertAdmitting(parent);
1038
1017
  const inheritedEventCount = SessionLogOffset(prepared.seed?.length ?? 0);
1039
- const seed = seedDescriptorTurn(childId, prepared.seed, descriptor);
1018
+ const seed = prepared.seed;
1040
1019
  return {
1041
1020
  childId,
1042
1021
  messageId: await this.locks.run(childId, async () => {
@@ -1058,7 +1037,8 @@ var SubagentContinuationManager = class {
1058
1037
  seed,
1059
1038
  meta: childSessionMeta(parent, childDepth, prepared.seed !== void 0),
1060
1039
  inheritedEventCount,
1061
- delegatedPolicies
1040
+ delegatedPolicies,
1041
+ descriptor
1062
1042
  },
1063
1043
  agentOptions,
1064
1044
  composition: {
@@ -1559,7 +1539,11 @@ var SubagentContinuationManager = class {
1559
1539
  const { childId, provider, parent, create } = inputs;
1560
1540
  inputs.signal.throwIfAborted();
1561
1541
  const setup = (childCtx) => {
1562
- if (create !== void 0) appendDelegatedPolicyOverrides(childCtx.agent.session, create.delegatedPolicies);
1542
+ const child = childCtx.agent;
1543
+ if (create !== void 0) {
1544
+ child.session.append("subagent/descriptor", create.descriptor);
1545
+ appendDelegatedPolicyOverrides(child.session, create.delegatedPolicies);
1546
+ }
1563
1547
  applyChildComposition(childCtx, parent, inputs.composition);
1564
1548
  };
1565
1549
  const observer = this.host.observeActivation(provider, childId, parent);
@@ -1571,7 +1555,7 @@ var SubagentContinuationManager = class {
1571
1555
  }) : await this.ownerCtx.agents.create({
1572
1556
  sessionId: childId,
1573
1557
  meta: create.meta,
1574
- seed: create.seed,
1558
+ ...create.seed === void 0 ? {} : { seed: create.seed },
1575
1559
  inheritedEventCount: create.inheritedEventCount,
1576
1560
  agentOptions: inputs.agentOptions,
1577
1561
  signal: inputs.signal,
@@ -2970,7 +2954,7 @@ let SubagentRuntime = (() => {
2970
2954
  else {
2971
2955
  const attachments = this.ctx.get("attachments");
2972
2956
  if (attachments === void 0) throw new Error("subagent image prompt requires an attachment store");
2973
- content = await admitPromptContent(attachments, request.content);
2957
+ content = await attachments.admitPromptContent(request.content);
2974
2958
  }
2975
2959
  return { messageId: await this[deliverSubagentPrompt](parent, childSessionId, content, source, signal, "queue") };
2976
2960
  } catch (error) {
@@ -3125,4 +3109,4 @@ let SubagentRuntime = (() => {
3125
3109
  };
3126
3110
  })();
3127
3111
  //#endregion
3128
- export { AssistantOutputFold, NO_START_CAPABILITIES, SUBAGENT_DESCRIPTOR_VERSION, SubagentDepthError, SubagentError, SubagentRunId, SubagentRuntime, SubagentRuntime as default, appendDelegatedPolicyOverrides, applyChildComposition, assertPositiveFinite, assertSubagentMaxDepth, assertUsableCwd, captureDelegatedPolicyOverrides, childSessionMeta, delegationDepthOf, finalAssistantOutput, foldSubagentDescriptor, parentAgentOptionsForDelegation, resolveChildAgentOptions, resolveChildCwd, resolveChildDepth, seedDescriptorTurn, settleRun, settleRunResult, snapshotSubagentDescriptor, subprocessRunHandle, validateConfiguredCwd };
3112
+ export { AssistantOutputFold, NO_START_CAPABILITIES, SUBAGENT_DESCRIPTOR_VERSION, SubagentDepthError, SubagentError, SubagentRunId, SubagentRuntime, SubagentRuntime as default, appendDelegatedPolicyOverrides, applyChildComposition, assertPositiveFinite, assertSubagentMaxDepth, assertUsableCwd, captureDelegatedPolicyOverrides, childSessionMeta, delegationDepthOf, finalAssistantOutput, foldSubagentDescriptor, parentAgentOptionsForDelegation, resolveChildAgentOptions, resolveChildCwd, resolveChildDepth, settleRun, settleRunResult, snapshotSubagentDescriptor, subprocessRunHandle, validateConfiguredCwd };
@@ -101,7 +101,7 @@ export const TYPERT = {
101
101
  typeSymbol: '@xneog/dsh-subagent/client#SubagentInterruptReceipt',
102
102
  schema: _xneog_dsh_subagent_subagents_interruptByParent_result$schema,
103
103
  },
104
- sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":481,"column":3},
104
+ sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":480,"column":3},
105
105
  },
106
106
  {
107
107
  id: '@xneog/dsh-subagent#subagents/list',
@@ -128,7 +128,7 @@ export const TYPERT = {
128
128
  typeSymbol: '@xneog/dsh-subagent/client#SubagentCatalog',
129
129
  schema: _xneog_dsh_subagent_subagents_list_result$schema,
130
130
  },
131
- sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":388,"column":9},
131
+ sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":387,"column":9},
132
132
  },
133
133
  {
134
134
  id: '@xneog/dsh-subagent#subagents/prompt',
@@ -154,7 +154,7 @@ export const TYPERT = {
154
154
  typeSymbol: '@xneog/dsh-subagent/client#SubagentPromptReceipt',
155
155
  schema: _xneog_dsh_subagent_subagents_prompt_result$schema,
156
156
  },
157
- sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":414,"column":9},
157
+ sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":413,"column":9},
158
158
  },
159
159
  ],
160
160
  model: {
@@ -307,6 +307,10 @@ export const TYPERT = {
307
307
  "name": "AssistantProvenance",
308
308
  "declaration": "export interface AssistantProvenance {\n provider: string;\n model: string;\n replayState?: unknown;\n}"
309
309
  },
310
+ {
311
+ "name": "AssistantStreamRecord",
312
+ "declaration": "export type AssistantStreamRecord = { readonly type: 'text-chunks'; readonly time0: number; readonly index: number; readonly dt: readonly number[]; readonly texts: readonly string[]; } | { readonly type: 'reasoning-chunks'; readonly time0: number; readonly index: number; readonly dt: readonly number[]; readonly texts: readonly string[]; } | { readonly type: 'tool-call-chunks'; readonly time0: number; readonly index: number; readonly dt: readonly number[]; readonly id: ToolCallId; readonly name?: string; readonly args: readonly string[]; } | { readonly type: 'chunk'; readonly time: number; readonly chunk: StreamChunk; };"
313
+ },
310
314
  {
311
315
  "name": "AttachmentId",
312
316
  "declaration": "export type AttachmentId = Branded<'AttachmentId'>;"
@@ -345,7 +349,7 @@ export const TYPERT = {
345
349
  },
346
350
  {
347
351
  "name": "ContentBlockMap",
348
- "declaration": "export interface ContentBlockMap {\n text: TextBlock;\n reasoning: ReasoningBlock;\n image: ImageBlock;\n 'tool-call': ToolCallBlock;\n 'tool-result': ToolResultBlock;\n}"
352
+ "declaration": "export interface ContentBlockMap {\n text: TextBlock;\n reasoning: ReasoningBlock;\n image: ImageBlock;\n file: FileBlock;\n 'tool-call': ToolCallBlock;\n 'tool-result': ToolResultBlock;\n}"
349
353
  },
350
354
  {
351
355
  "name": "ContentBlockType",
@@ -383,6 +387,14 @@ export const TYPERT = {
383
387
  "name": "EpochHeader",
384
388
  "declaration": "export interface EpochHeader {\n config: LlmCallConfig;\n adapterDefaults?: LlmCallConfigAdapterDefaults;\n system?: string;\n tools?: ToolSchema[];\n}"
385
389
  },
390
+ {
391
+ "name": "FileAttachmentRef",
392
+ "declaration": "export interface FileAttachmentRef {\n attachmentId: AttachmentId;\n name: string;\n bytes: number;\n}"
393
+ },
394
+ {
395
+ "name": "FileBlock",
396
+ "declaration": "export interface FileBlock {\n type: 'file';\n attachment: FileAttachmentRef;\n}"
397
+ },
386
398
  {
387
399
  "name": "FinishReason",
388
400
  "declaration": "export type FinishReason = FinishReasonMap[keyof FinishReasonMap];"
@@ -561,7 +573,7 @@ export const TYPERT = {
561
573
  },
562
574
  {
563
575
  "name": "Session",
564
- "declaration": "export class Session {\n get surface(): SessionSurface;\n readonly header: SessionHeader;\n readonly inheritedEventCount: SessionLogOffset;\n get id(): SessionId;\n readonly firstLiveSeq: SessionLogOffset;\n eventAt(seq: SessionSeq): SessionEvent | undefined;\n snapshotEvents(fromSeq: SessionLogOffset = SessionLogOffset(0), toSeqExclusive: SessionLogOffset = this.seq): readonly SessionEvent[];\n ownEvents(): readonly SessionEvent[];\n isOwnSeq(seq: SessionSeq): boolean;\n get seq(): SessionLogOffset;\n append<T extends SessionEventType>(type: T, data: SessionEventMap[T], ...opts: T extends SurfaceEventType ? [opts: SurfaceIntent] : []): SessionEvent<T>;\n requestHeader(): EpochHeader | undefined;\n requestContext(): RequestContext | undefined;\n deriveMessages(): Message[];\n deriveEventMessage(event: SessionEvent): Message | null;\n}"
576
+ "declaration": "export class Session {\n get surface(): SessionSurface;\n readonly header: SessionHeader;\n readonly inheritedEventCount: SessionLogOffset;\n get id(): SessionId;\n readonly firstLiveSeq: SessionLogOffset;\n eventAt(seq: SessionSeq): SessionEvent | undefined;\n snapshotEvents(fromSeq: SessionLogOffset = SessionLogOffset(0), toSeqExclusive: SessionLogOffset = this.seq): readonly SessionEvent[];\n ownEvents(): readonly SessionEvent[];\n isOwnSeq(seq: SessionSeq): boolean;\n get seq(): SessionLogOffset;\n append<T extends SessionEventType>(type: T, data: SessionEventMap[T], ...opts: T extends SurfaceEventType ? [opts: SurfaceIntent<T>] : []): SessionEvent<T>;\n requestHeader(): EpochHeader | undefined;\n requestContext(): RequestContext | undefined;\n deriveMessages(): Message[];\n deriveEventMessage(event: SessionEvent): Message | null;\n}"
565
577
  },
566
578
  {
567
579
  "name": "SessionEvent",
@@ -569,7 +581,7 @@ export const TYPERT = {
569
581
  },
570
582
  {
571
583
  "name": "SessionEventMap",
572
- "declaration": "export interface SessionEventMap {\n 'turn/start': { turn: number; };\n 'turn/end': { turn: number; reason: TurnEndReason; };\n 'step/start': { turn: number; step: number; };\n 'step/end': { turn: number; step: number; };\n 'user/message': UserMessage;\n 'assistant/chunk': { turn: number; step: number; chunk: StreamChunk; };\n 'assistant/message': { turn: number; step: number; message: AssistantMessage; usage?: TokenUsage; interrupted?: true; };\n 'tool/call': { turn: number; step: number; callId: ToolCallId; name: string; arguments: string; };\n 'tool/result': { turn: number; step: number; message: ToolResultMessage; error?: { name: string; code: string; }; meta?: JsonValue; };\n 'request/header': { header: EpochHeader; reason: RequestHeaderReason; startsSeries?: true; };\n 'request/context': RequestContext;\n 'session/end-seed': Record<string, never>;\n 'agent/inbox/spliced': { target: InboxTarget; start: number; removedCount?: number; inserted: UserMessage[]; outcome?: 'canceled'; };\n 'approval/asked': { id: ApprovalRequestId; toolName: string; callId?: ToolCallId; reason?: string; };\n 'approval/decided': { id: ApprovalRequestId; outcome: ApprovalOutcome; };\n 'approval/policy': { policy: ApprovalPolicy; source?: 'delegation'; };\n 'tool/code-dispatch-start': PtcDispatchStartEventData;\n 'tool/code-dispatch': PtcDispatchEventData;\n 'agent-preset/selected': { agentPreset: string; };\n 'session/title': SessionTitleEventData;\n 'todo/write': { todos: TodoItem[]; };\n 'model/selection': ModelSelection;\n 'subagent/descriptor': SubagentDescriptorData;\n 'sandbox/mode': { mode: SandboxMode; source?: 'delegation'; };\n 'command/run': { commandId: CommandId; name: string; args?: string; source: CommandSource; };\n 'command/done': { commandId: CommandId; kind: 'success' | 'error'; text?: string; sourceEventSeq?: import('@xneog/dsh-session/types').SessionSeq; };\n 'team/member': { version: 2; teamId: TeamId; member: TeamMemberSnapshot; };\n 'team/task': { version: 2; teamId: TeamId; task: TeamTaskSnapshot; };\n 'team/message/queued': { version: 2; teamId: TeamId; message: TeamMessageSnapshot; };\n 'team/message/delivered': { version: 2; teamId: TeamId; messageId: TeamMessageId; targetId: SessionId; };\n 'goal/change': GoalChangeMeta;\n 'compaction/start': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; };\n 'compaction/summary': { compactionId: CompactionId; sourceCommandId?: CommandId; summary: ContentBlock[]; shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; provider: string; model: string; maxTokens?: number; usage?: TokenUsage; } & ({ rawOutput: ContentBlock[]; llmStreamCall: true; } | { rawOutput?: ContentBlock[]; llmStreamCall?: never; });\n 'compaction/end': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; error?: string; };\n 'compaction/prune': { shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; };\n}"
584
+ "declaration": "export interface SessionEventMap {\n 'turn/start': { turn: number; };\n 'turn/end': { turn: number; reason: TurnEndReason; };\n 'step/start': { turn: number; step: number; };\n 'step/end': { turn: number; step: number; };\n 'user/message': UserMessage;\n 'assistant/message': { turn: number; step: number; message: AssistantMessage; stream: AssistantStreamRecord[]; usage?: TokenUsage; interrupted?: true; };\n 'assistant/attempt': { turn: number; step: number; stream: AssistantStreamRecord[]; };\n 'tool/call': { turn: number; step: number; callId: ToolCallId; name: string; arguments: string; };\n 'tool/result': { turn: number; step: number; message: ToolResultMessage; error?: { name: string; code: string; }; meta?: JsonValue; };\n 'request/header': { header: EpochHeader; reason: RequestHeaderReason; startsSeries?: true; };\n 'request/context': RequestContext;\n 'session/end-seed': { inherited?: true; };\n 'agent/inbox/spliced': { target: InboxTarget; start: number; removedCount?: number; inserted: UserMessage[]; outcome?: 'canceled'; };\n 'approval/asked': { id: ApprovalRequestId; toolName: string; callId?: ToolCallId; reason?: string; };\n 'approval/decided': { id: ApprovalRequestId; outcome: ApprovalOutcome; };\n 'approval/policy': { policy: ApprovalPolicy; source?: 'delegation'; };\n 'tool/code-dispatch-start': PtcDispatchStartEventData;\n 'tool/code-dispatch': PtcDispatchEventData;\n 'agent-preset/selected': { agentPreset: string; };\n 'command/run': { commandId: CommandId; name: string; args?: string; source: CommandSource; };\n 'command/done': { commandId: CommandId; kind: 'success' | 'error'; text?: string; sourceEventSeq?: import('@xneog/dsh-session/types').SessionSeq; };\n 'session/title': SessionTitleEventData;\n 'todo/write': { todos: TodoItem[]; };\n 'model/selection': ModelSelection;\n 'subagent/descriptor': SubagentDescriptorData;\n 'sandbox/mode': { mode: SandboxMode; source?: 'delegation'; };\n 'team/member': { version: 2; teamId: TeamId; member: TeamMemberSnapshot; };\n 'team/task': { version: 2; teamId: TeamId; task: TeamTaskSnapshot; };\n 'team/message/queued': { version: 2; teamId: TeamId; message: TeamMessageSnapshot; };\n 'team/message/delivered': { version: 2; teamId: TeamId; messageId: TeamMessageId; targetId: SessionId; };\n 'goal/change': GoalChangeMeta;\n 'compaction/start': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; };\n 'compaction/summary': { compactionId: CompactionId; sourceCommandId?: CommandId; summary: ContentBlock[]; shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; provider: string; model: string; maxTokens?: number; usage?: TokenUsage; } & ({ rawOutput: ContentBlock[]; llmStreamCall: true; } | { rawOutput?: ContentBlock[]; llmStreamCall?: never; });\n 'compaction/end': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; error?: string; };\n 'compaction/prune': { shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; };\n}"
573
585
  },
574
586
  {
575
587
  "name": "SessionEventType",
@@ -577,7 +589,7 @@ export const TYPERT = {
577
589
  },
578
590
  {
579
591
  "name": "SessionHeader",
580
- "declaration": "export interface SessionHeader {\n readonly version: number;\n readonly id: SessionId;\n readonly createdAt: number;\n readonly cwd?: string;\n readonly parentSession?: SessionId;\n readonly isSeeded: boolean;\n readonly origin?: 'subagent';\n readonly delegationDepth?: number;\n readonly agentPreset?: string;\n}"
592
+ "declaration": "export interface SessionHeader {\n readonly version: typeof SESSION_FORMAT_VERSION;\n readonly id: SessionId;\n readonly createdAt: number;\n readonly cwd?: string;\n readonly parentSession?: SessionId;\n readonly isSeeded: boolean;\n readonly origin?: 'subagent';\n readonly delegationDepth?: number;\n readonly agentPreset?: string;\n}"
581
593
  },
582
594
  {
583
595
  "name": "SessionId",
@@ -589,7 +601,7 @@ export const TYPERT = {
589
601
  },
590
602
  {
591
603
  "name": "SessionReferenceSource",
592
- "declaration": "export interface SessionReferenceSource {\n kind: 'session-reference';\n form: 'recall';\n version: 1;\n references: { sessionId: string; label: string; capturedThroughSeq: OptionalSessionSeq; compacted: boolean; originalMessages: number; retainedMessages: number; omittedMessages: number; omittedBytes: number; truncated: boolean; inputIndex: number; }[];\n}"
604
+ "declaration": "export interface SessionReferenceSource {\n kind: 'session-reference';\n form: 'recall';\n version: 1;\n references: { sessionId: string; label: string; capturedFormatVersion?: number; capturedThroughSeq: OptionalSessionSeq; compacted: boolean; originalMessages: number; retainedMessages: number; omittedMessages: number; omittedBytes: number; truncated: boolean; inputIndex: number; }[];\n}"
593
605
  },
594
606
  {
595
607
  "name": "SessionRequestId",
@@ -709,7 +721,7 @@ export const TYPERT = {
709
721
  },
710
722
  {
711
723
  "name": "SurfaceIntent",
712
- "declaration": "export interface SurfaceIntent {\n surfaceOp: SurfaceOp;\n sourceEventSeqs?: SessionSeq[];\n}"
724
+ "declaration": "export type SurfaceIntent<T extends SurfaceEventType = SurfaceEventType> = { surfaceOp: SurfaceOp; } & (T extends 'assistant/message' ? { sourceEventSeqs?: never; } : { sourceEventSeqs?: SessionSeq[]; });"
713
725
  },
714
726
  {
715
727
  "name": "SurfaceOp",
@@ -98,7 +98,7 @@ export const TYPERT_REMOTE = {
98
98
  typeSymbol: '@xneog/dsh-subagent/client#SubagentInterruptReceipt',
99
99
  schema: _xneog_dsh_subagent_subagents_interruptByParent_result$schema,
100
100
  },
101
- sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":481,"column":3},
101
+ sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":480,"column":3},
102
102
  },
103
103
  {
104
104
  id: '@xneog/dsh-subagent#subagents/list',
@@ -125,7 +125,7 @@ export const TYPERT_REMOTE = {
125
125
  typeSymbol: '@xneog/dsh-subagent/client#SubagentCatalog',
126
126
  schema: _xneog_dsh_subagent_subagents_list_result$schema,
127
127
  },
128
- sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":388,"column":9},
128
+ sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":387,"column":9},
129
129
  },
130
130
  {
131
131
  id: '@xneog/dsh-subagent#subagents/prompt',
@@ -151,7 +151,7 @@ export const TYPERT_REMOTE = {
151
151
  typeSymbol: '@xneog/dsh-subagent/client#SubagentPromptReceipt',
152
152
  schema: _xneog_dsh_subagent_subagents_prompt_result$schema,
153
153
  },
154
- sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":414,"column":9},
154
+ sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":413,"column":9},
155
155
  },
156
156
  ],
157
157
  }
@@ -9,7 +9,7 @@
9
9
  *
10
10
  * @module @xneog/dsh-subagent/assistant-output
11
11
  */
12
- import type { ContentBlock } from '@xneog/dsh-llm';
12
+ import { type ContentBlock } from '@xneog/dsh-llm';
13
13
  import type { SessionEvent } from '@xneog/dsh-session';
14
14
  /**
15
15
  * Incremental fold of the selection rule, for backends that observe a child's
@@ -22,8 +22,8 @@ export declare class AssistantOutputFold {
22
22
  private partial;
23
23
  /**
24
24
  * Fold one session event: a non-empty assistant message becomes the
25
- * candidate final answer, and a `text-delta` chunk extends the streamed
26
- * fallback; every other event contributes nothing.
25
+ * candidate final answer, while its embedded stream and any log-only attempt
26
+ * extend the streamed fallback; every other event contributes nothing.
27
27
  * @param event - the next observed session event.
28
28
  */
29
29
  push(event: SessionEvent): void;
@@ -9,6 +9,7 @@
9
9
  *
10
10
  * @module @xneog/dsh-subagent/assistant-output
11
11
  */
12
+ import { expandAssistantStream } from '@xneog/dsh-llm';
12
13
  /**
13
14
  * Incremental fold of the selection rule, for backends that observe a child's
14
15
  * output as it streams: session-event backends {@link push} each event, and
@@ -20,8 +21,8 @@ export class AssistantOutputFold {
20
21
  partial = [];
21
22
  /**
22
23
  * Fold one session event: a non-empty assistant message becomes the
23
- * candidate final answer, and a `text-delta` chunk extends the streamed
24
- * fallback; every other event contributes nothing.
24
+ * candidate final answer, while its embedded stream and any log-only attempt
25
+ * extend the streamed fallback; every other event contributes nothing.
25
26
  * @param event - the next observed session event.
26
27
  */
27
28
  push(event) {
@@ -30,8 +31,11 @@ export class AssistantOutputFold {
30
31
  if (content.length > 0)
31
32
  this.message = content;
32
33
  }
33
- else if (event.type === 'assistant/chunk' && event.data.chunk.type === 'text-delta') {
34
- this.pushText(event.data.chunk.text);
34
+ if (event.type === 'assistant/message' || event.type === 'assistant/attempt') {
35
+ for (const { chunk } of expandAssistantStream(event.data.stream)) {
36
+ if (chunk.type === 'text-delta')
37
+ this.pushText(chunk.text);
38
+ }
35
39
  }
36
40
  }
37
41
  /**
@@ -79,7 +79,6 @@ import { SessionLogOffset } from '@xneog/dsh-session';
79
79
  import { foldSubagentDescriptor, snapshotSubagentDescriptor } from "./descriptor.js";
80
80
  import { appendDelegatedPolicyOverrides, applyChildComposition, captureDelegatedPolicyOverrides, childSessionMeta, resolveChildAgentOptions, resolveChildDepth, } from "./child-agent.js";
81
81
  import { assertSubagentMaxDepth } from "./depth.js";
82
- import { seedDescriptorTurn } from "./descriptor-seed.js";
83
82
  import { SubagentError } from "./error.js";
84
83
  import { isAdjacentAgentSendMessageTool } from "./internal.js";
85
84
  /**
@@ -278,7 +277,7 @@ export class SubagentContinuationManager {
278
277
  spec.signal.throwIfAborted();
279
278
  this.assertAdmitting(parent);
280
279
  const inheritedEventCount = SessionLogOffset(prepared.seed?.length ?? 0);
281
- const seed = seedDescriptorTurn(childId, prepared.seed, descriptor);
280
+ const seed = prepared.seed;
282
281
  const messageId = await this.locks.run(childId, async () => {
283
282
  spec.signal.throwIfAborted();
284
283
  this.assertAdmitting(parent);
@@ -296,7 +295,13 @@ export class SubagentContinuationManager {
296
295
  childId,
297
296
  provider: spec.provider,
298
297
  parent,
299
- create: { seed, meta: childSessionMeta(parent, childDepth, prepared.seed !== undefined), inheritedEventCount, delegatedPolicies },
298
+ create: {
299
+ seed,
300
+ meta: childSessionMeta(parent, childDepth, prepared.seed !== undefined),
301
+ inheritedEventCount,
302
+ delegatedPolicies,
303
+ descriptor,
304
+ },
300
305
  agentOptions,
301
306
  composition: { persona: request.persona, toolFilter: request.toolFilter },
302
307
  signal: spec.signal,
@@ -914,11 +919,12 @@ export class SubagentContinuationManager {
914
919
  // some other owner holds — a duplicate would reject there with rollback.
915
920
  inputs.signal.throwIfAborted();
916
921
  const setup = (childCtx) => {
917
- // Only fresh creation seeds the delegation policy onto the child's own
918
- // log (after any fork seed, so fresh policy wins stale seed state); a
919
- // cold resume replays those persisted events instead.
922
+ const child = childCtx.agent;
923
+ // Only fresh creation appends the descriptor and delegated policy after
924
+ // the inherited marker; a cold resume replays those persisted events.
920
925
  if (create !== undefined) {
921
- appendDelegatedPolicyOverrides(childCtx.agent.session, create.delegatedPolicies);
926
+ child.session.append('subagent/descriptor', create.descriptor);
927
+ appendDelegatedPolicyOverrides(child.session, create.delegatedPolicies);
922
928
  }
923
929
  applyChildComposition(childCtx, parent, inputs.composition);
924
930
  };
@@ -935,7 +941,7 @@ export class SubagentContinuationManager {
935
941
  : await this.ownerCtx.agents.create({
936
942
  sessionId: childId,
937
943
  meta: create.meta,
938
- seed: create.seed,
944
+ ...(create.seed === undefined ? {} : { seed: create.seed }),
939
945
  inheritedEventCount: create.inheritedEventCount,
940
946
  agentOptions: inputs.agentOptions,
941
947
  signal: inputs.signal,
@@ -45,7 +45,6 @@ export { SubagentRunId } from './types.ts';
45
45
  export type { ContinuableCreateRequest, ContinuableCreateSpec, ResolvedSubagentStartRequest, SubagentCapabilities, SubagentProvider, SubagentResult, SubagentRun, SubagentStartRequest, SubagentStopReason, SubagentStopReasonMap, } from './types.ts';
46
46
  export { foldSubagentDescriptor, snapshotSubagentDescriptor, SUBAGENT_DESCRIPTOR_VERSION, } from './descriptor.ts';
47
47
  export type { ContinuableSubagentDescriptorData, ContinuableSubagentDescriptorInput, OneShotSubagentDescriptorData, OneShotSubagentDescriptorInput, SubagentDescriptorData, SubagentDescriptorInput, } from './descriptor.ts';
48
- export { seedDescriptorTurn } from './descriptor-seed.ts';
49
48
  export { SubagentError } from './error.ts';
50
49
  export { settleRun } from './run-settlement.ts';
51
50
  export { assertSubagentMaxDepth, delegationDepthOf } from './depth.ts';
@@ -62,7 +62,6 @@ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn,
62
62
  if (target) Object.defineProperty(target, contextIn.name, descriptor);
63
63
  done = true;
64
64
  };
65
- import { admitPromptContent } from '@xneog/dsh-attachment';
66
65
  import { scopeTarget } from '@xneog/dsh-scope';
67
66
  import { assertObjectJsonSchema } from '@xneog/dsh-tools';
68
67
  import { canonicalClientTimeZone } from '@xneog/dsh-util-time';
@@ -80,7 +79,6 @@ export * from "./out-of-process.js";
80
79
  export { AssistantOutputFold, finalAssistantOutput } from "./assistant-output.js";
81
80
  export { SubagentRunId } from "./types.js";
82
81
  export { foldSubagentDescriptor, snapshotSubagentDescriptor, SUBAGENT_DESCRIPTOR_VERSION, } from "./descriptor.js";
83
- export { seedDescriptorTurn } from "./descriptor-seed.js";
84
82
  export { SubagentError } from "./error.js";
85
83
  export { settleRun } from "./run-settlement.js";
86
84
  export { assertSubagentMaxDepth, delegationDepthOf } from "./depth.js";
@@ -333,7 +331,7 @@ let SubagentRuntime = (() => {
333
331
  const attachments = this.ctx.get('attachments');
334
332
  if (attachments === undefined)
335
333
  throw new Error('subagent image prompt requires an attachment store');
336
- content = await admitPromptContent(attachments, request.content);
334
+ content = await attachments.admitPromptContent(request.content);
337
335
  }
338
336
  return {
339
337
  messageId: await this[deliverSubagentPrompt](parent, childSessionId, content, source, signal, 'queue'),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xneog/dsh-subagent",
3
3
  "description": "Abstract subagent seam (ctx.subagents): named-provider registry for delegating to child agents",
4
- "version": "0.1.2-rc.1",
4
+ "version": "0.1.3-alpha.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -54,30 +54,30 @@
54
54
  "license": "MIT",
55
55
  "dependencies": {
56
56
  "zod": "^4.4.3",
57
- "@xneog/dsh-brand": "^0.1.2-rc.1",
58
- "@xneog/dsh-util-values": "^0.1.2-rc.1"
57
+ "@xneog/dsh-brand": "^0.1.3-alpha.1",
58
+ "@xneog/dsh-util-values": "^0.1.3-alpha.1"
59
59
  },
60
60
  "peerDependencies": {
61
61
  "@xneog/cordis": "^4.0.2",
62
- "@xneog/dsh-agent": "^0.1.2-rc.1",
63
- "@xneog/dsh-agent-presets": "^0.1.2-rc.1",
64
- "@xneog/dsh-attachment": "^0.1.2-rc.1",
65
- "@xneog/dsh-invariants": "^0.1.2-rc.1",
66
- "@xneog/dsh-jobs": "^0.1.2-rc.1",
67
- "@xneog/dsh-llm": "^0.1.2-rc.1",
68
- "@xneog/dsh-sandbox": "^0.1.2-rc.1",
69
- "@xneog/dsh-sandbox-policy": "^0.1.2-rc.1",
70
- "@xneog/dsh-scope": "^0.1.2-rc.1",
71
- "@xneog/dsh-session-persistence": "^0.1.2-rc.1",
72
- "@xneog/dsh-session-projection": "^0.1.2-rc.1",
73
- "@xneog/dsh-session-projection-cache": "^0.1.2-rc.1",
74
- "@xneog/dsh-session-query": "^0.1.2-rc.1",
75
- "@xneog/dsh-system-prompt": "^0.1.2-rc.1",
76
- "@xneog/dsh-tools": "^0.1.2-rc.1",
77
- "@xneog/dsh-typert-protocol": "^0.1.2-rc.1",
78
- "@xneog/dsh-user-approval": "^0.1.2-rc.1",
79
- "@xneog/dsh-util-time": "^0.1.2-rc.1",
80
- "@xneog/dsh-session": "^0.1.2-rc.1"
62
+ "@xneog/dsh-agent-presets": "^0.1.3-alpha.1",
63
+ "@xneog/dsh-invariants": "^0.1.3-alpha.1",
64
+ "@xneog/dsh-llm": "^0.1.3-alpha.1",
65
+ "@xneog/dsh-sandbox-policy": "^0.1.3-alpha.1",
66
+ "@xneog/dsh-scope": "^0.1.3-alpha.1",
67
+ "@xneog/dsh-session": "^0.1.3-alpha.1",
68
+ "@xneog/dsh-jobs": "^0.1.3-alpha.1",
69
+ "@xneog/dsh-agent": "^0.1.3-alpha.1",
70
+ "@xneog/dsh-attachment": "^0.1.3-alpha.1",
71
+ "@xneog/dsh-sandbox": "^0.1.3-alpha.1",
72
+ "@xneog/dsh-session-persistence": "^0.1.3-alpha.1",
73
+ "@xneog/dsh-session-projection": "^0.1.3-alpha.1",
74
+ "@xneog/dsh-tools": "^0.1.3-alpha.1",
75
+ "@xneog/dsh-session-query": "^0.1.3-alpha.1",
76
+ "@xneog/dsh-system-prompt": "^0.1.3-alpha.1",
77
+ "@xneog/dsh-user-approval": "^0.1.3-alpha.1",
78
+ "@xneog/dsh-session-projection-cache": "^0.1.3-alpha.1",
79
+ "@xneog/dsh-typert-protocol": "^0.1.3-alpha.1",
80
+ "@xneog/dsh-util-time": "^0.1.3-alpha.1"
81
81
  },
82
82
  "peerDependenciesMeta": {
83
83
  "@xneog/dsh-agent-presets": {
@@ -109,28 +109,28 @@
109
109
  }
110
110
  },
111
111
  "devDependencies": {
112
- "@xneog/dsh-agent": "^0.1.2-rc.1",
113
112
  "@xneog/cordis": "^4.0.2",
114
- "@xneog/dsh-agent-presets": "^0.1.2-rc.1",
115
- "@xneog/dsh-invariants": "^0.1.2-rc.1",
116
- "@xneog/dsh-llm": "^0.1.2-rc.1",
117
- "@xneog/dsh-sandbox-policy": "^0.1.2-rc.1",
118
- "@xneog/dsh-jobs": "^0.1.2-rc.1",
119
- "@xneog/dsh-scope": "^0.1.2-rc.1",
120
- "@xneog/dsh-session": "^0.1.2-rc.1",
121
- "@xneog/dsh-session-persistence": "^0.1.2-rc.1",
122
- "@xneog/dsh-session-projection": "^0.1.2-rc.1",
123
- "@xneog/dsh-sandbox": "^0.1.2-rc.1",
124
- "@xneog/dsh-session-projection-cache": "^0.1.2-rc.1",
125
- "@xneog/dsh-session-query": "^0.1.2-rc.1",
126
- "@xneog/dsh-storage-domain": "^0.1.2-rc.1",
127
- "@xneog/dsh-storage": "^0.1.2-rc.1",
128
- "@xneog/dsh-storage-json": "^0.1.2-rc.1",
129
- "@xneog/dsh-tools": "^0.1.2-rc.1",
130
- "@xneog/dsh-system-prompt": "^0.1.2-rc.1",
131
- "@xneog/dsh-attachment": "^0.1.2-rc.1",
132
- "@xneog/dsh-util-time": "^0.1.2-rc.1",
133
- "@xneog/dsh-user-approval": "^0.1.2-rc.1",
134
- "@xneog/dsh-typert-protocol": "^0.1.2-rc.1"
113
+ "@xneog/dsh-agent": "^0.1.3-alpha.1",
114
+ "@xneog/dsh-attachment": "^0.1.3-alpha.1",
115
+ "@xneog/dsh-agent-presets": "^0.1.3-alpha.1",
116
+ "@xneog/dsh-llm": "^0.1.3-alpha.1",
117
+ "@xneog/dsh-jobs": "^0.1.3-alpha.1",
118
+ "@xneog/dsh-sandbox": "^0.1.3-alpha.1",
119
+ "@xneog/dsh-sandbox-policy": "^0.1.3-alpha.1",
120
+ "@xneog/dsh-session": "^0.1.3-alpha.1",
121
+ "@xneog/dsh-session-persistence": "^0.1.3-alpha.1",
122
+ "@xneog/dsh-session-projection": "^0.1.3-alpha.1",
123
+ "@xneog/dsh-session-projection-cache": "^0.1.3-alpha.1",
124
+ "@xneog/dsh-session-query": "^0.1.3-alpha.1",
125
+ "@xneog/dsh-scope": "^0.1.3-alpha.1",
126
+ "@xneog/dsh-storage": "^0.1.3-alpha.1",
127
+ "@xneog/dsh-invariants": "^0.1.3-alpha.1",
128
+ "@xneog/dsh-system-prompt": "^0.1.3-alpha.1",
129
+ "@xneog/dsh-tools": "^0.1.3-alpha.1",
130
+ "@xneog/dsh-typert-protocol": "^0.1.3-alpha.1",
131
+ "@xneog/dsh-storage-json": "^0.1.3-alpha.1",
132
+ "@xneog/dsh-util-time": "^0.1.3-alpha.1",
133
+ "@xneog/dsh-user-approval": "^0.1.3-alpha.1",
134
+ "@xneog/dsh-storage-domain": "^0.1.3-alpha.1"
135
135
  }
136
136
  }