@nextclaw/kernel 0.5.1 → 0.5.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.
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import { APP_NAME, AgentRouteResolver, BUILTIN_MAIN_AGENT_ID, CLEAR_THINKING_TOK
4
4
  import { NcpEventType, sanitizeAssistantReplyTags } from "@nextclaw/ncp";
5
5
  import { LocalAssetStore, buildAssetContentPath, buildNcpUserContent, buildOpenAiFunctionTool, ncpMessageToOpenAiMessages, validateToolArgs } from "@nextclaw/ncp-agent-runtime";
6
6
  import { createHash, createHmac, randomBytes, randomUUID, scryptSync, timingSafeEqual } from "node:crypto";
7
- import { EventBus, Ingress, eventKeys, ingressKeys, isRuntimeDefaultModelValue, normalizeRuntimeModelSelectionMode } from "@nextclaw/shared";
7
+ import { CHAT_SESSION_MATERIALIZATION_METADATA_KEY, EventBus, Ingress, eventKeys, ingressKeys, isRuntimeDefaultModelValue, normalizeRuntimeModelSelectionMode } from "@nextclaw/shared";
8
8
  import { catchError, from, lastValueFrom, tap } from "rxjs";
9
9
  import { appendFileSync, chmodSync, constants, existsSync, mkdirSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs";
10
10
  import { basename, delimiter, dirname, extname, isAbsolute, join, normalize, relative, resolve } from "node:path";
@@ -584,6 +584,20 @@ function readOptionalString$10(value) {
584
584
  if (typeof value !== "string") return;
585
585
  return value.trim() || void 0;
586
586
  }
587
+ function readSessionMaterialization(metadata) {
588
+ const value = metadata[CHAT_SESSION_MATERIALIZATION_METADATA_KEY];
589
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
590
+ const materialization = value;
591
+ if (materialization.kind !== "child") throw new Error("session_materialization.kind must be \"child\".");
592
+ const parentSessionId = readOptionalString$10(materialization.parentSessionId);
593
+ if (!parentSessionId) throw new Error("session_materialization.parentSessionId is required.");
594
+ if (materialization.inheritContext !== true) throw new Error("session_materialization.inheritContext must be true.");
595
+ return {
596
+ kind: "child",
597
+ parentSessionId,
598
+ inheritContext: true
599
+ };
600
+ }
587
601
  function toRunHandle(accepted) {
588
602
  return {
589
603
  sessionId: accepted.sessionId,
@@ -642,18 +656,7 @@ var AgentRunRequestManager = class {
642
656
  }));
643
657
  };
644
658
  send = async (request) => {
645
- const session = await this.sessionManager.getOrCreateAgentRunSession({
646
- sessionId: request.sessionId,
647
- peerId: request.peerId,
648
- agentId: request.agentId,
649
- agentRuntimeId: request.agentRuntimeId,
650
- channel: request.channel,
651
- metadata: request.metadata,
652
- model: request.model,
653
- projectRoot: request.projectRoot,
654
- task: readMessageTask(request.message),
655
- thinkingEffort: request.thinkingEffort
656
- });
659
+ const session = await this.getOrCreateSessionForRequest(request);
657
660
  const sessionRun = this.sessionRunManager.getSessionRun(session.sessionId) ?? await this.sessionRunManager.createSessionRun(session.sessionId);
658
661
  const message = {
659
662
  ...request.message,
@@ -763,6 +766,25 @@ var AgentRunRequestManager = class {
763
766
  correlationId: request.correlationId
764
767
  };
765
768
  };
769
+ getOrCreateSessionForRequest = async (request) => {
770
+ const sessionMaterialization = readSessionMaterialization(request.metadata ?? {});
771
+ if (sessionMaterialization && (request.sessionId || request.peerId)) throw new Error("session_materialization requires a new session request.");
772
+ return await this.sessionManager.getOrCreateAgentRunSession({
773
+ sessionId: request.sessionId,
774
+ peerId: request.peerId,
775
+ agentId: request.agentId,
776
+ agentRuntimeId: request.agentRuntimeId,
777
+ channel: request.channel,
778
+ contextInheritance: sessionMaterialization ? {} : void 0,
779
+ metadata: request.metadata,
780
+ model: request.model,
781
+ parentSessionId: sessionMaterialization?.parentSessionId,
782
+ projectRoot: request.projectRoot,
783
+ sourceSessionId: sessionMaterialization?.parentSessionId,
784
+ task: readMessageTask(request.message),
785
+ thinkingEffort: request.thinkingEffort
786
+ });
787
+ };
766
788
  abort = async (request) => {
767
789
  this.sessionRunManager.getSessionRun(request.sessionId)?.abortRun(request.runId);
768
790
  };
@@ -3581,6 +3603,144 @@ function readOptionalMetadataString(value) {
3581
3603
  function readEventSessionId$1(event) {
3582
3604
  return "payload" in event && "sessionId" in event.payload ? readOptionalMetadataString(event.payload.sessionId) : void 0;
3583
3605
  }
3606
+ const DEFAULT_SESSION_LIFECYCLE = "persistent";
3607
+ const SESSION_METADATA_LABEL_KEY = "label";
3608
+ const CHILD_SESSION_PARENT_METADATA_KEY = "parent_session_id";
3609
+ const CHILD_SESSION_REQUEST_METADATA_KEY = "spawned_by_request_id";
3610
+ const CHILD_SESSION_LIFECYCLE_METADATA_KEY = "session_lifecycle";
3611
+ function readThinkingEffort(metadata) {
3612
+ return readOptionalMetadataString(metadata?.thinkingEffort) ?? readOptionalMetadataString(metadata?.preferred_thinking) ?? readOptionalMetadataString(metadata?.thinking) ?? null;
3613
+ }
3614
+ function readProjectRoot(metadata) {
3615
+ return readOptionalMetadataString(metadata?.project_root) ?? readOptionalMetadataString(metadata?.projectRoot);
3616
+ }
3617
+ function readAgentRuntimeId(metadata) {
3618
+ return readOptionalMetadataString(metadata?.agentRuntimeId) ?? readOptionalMetadataString(metadata?.runtime) ?? readOptionalMetadataString(metadata?.session_type);
3619
+ }
3620
+ function summarizeTask(task) {
3621
+ const normalized = task.trim().replace(/\s+/g, " ");
3622
+ if (!normalized) return "Session";
3623
+ return normalized.length <= 72 ? normalized : `${normalized.slice(0, 69)}...`;
3624
+ }
3625
+ function cloneInheritedMetadata(sourceMetadata) {
3626
+ const nextMetadata = {};
3627
+ for (const key of [
3628
+ "runtime",
3629
+ "session_type",
3630
+ "preferred_model",
3631
+ "preferred_thinking",
3632
+ "project_root",
3633
+ "requested_skill_refs",
3634
+ "codex_runtime_backend",
3635
+ "reasoningNormalizationMode",
3636
+ "reasoning_normalization_mode"
3637
+ ]) if (Object.prototype.hasOwnProperty.call(sourceMetadata, key)) nextMetadata[key] = structuredClone(sourceMetadata[key]);
3638
+ return nextMetadata;
3639
+ }
3640
+ function mergeMetadataOverrides(metadata, overrides) {
3641
+ return overrides && Object.keys(overrides).length > 0 ? {
3642
+ ...metadata,
3643
+ ...structuredClone(overrides)
3644
+ } : metadata;
3645
+ }
3646
+ function resolveSessionType(params) {
3647
+ const { metadata, runtime, sessionType } = params;
3648
+ return readOptionalString$8(runtime) ?? readOptionalString$8(metadata.runtime) ?? readOptionalString$8(sessionType) ?? readOptionalString$8(metadata.session_type) ?? "native";
3649
+ }
3650
+ function applySessionOverrides(params) {
3651
+ const { lifecycle, metadata, model, parentSessionId, projectRoot, requestId, sessionType, thinkingLevel, title } = params;
3652
+ metadata.session_type = sessionType;
3653
+ metadata.runtime = sessionType;
3654
+ metadata[SESSION_METADATA_LABEL_KEY] = title;
3655
+ metadata[CHILD_SESSION_LIFECYCLE_METADATA_KEY] = lifecycle;
3656
+ if (parentSessionId) metadata[CHILD_SESSION_PARENT_METADATA_KEY] = parentSessionId;
3657
+ if (requestId) metadata[CHILD_SESSION_REQUEST_METADATA_KEY] = requestId;
3658
+ if (readOptionalString$8(model)) {
3659
+ metadata.model = model?.trim();
3660
+ metadata.preferred_model = model?.trim();
3661
+ }
3662
+ if (readOptionalString$8(thinkingLevel)) {
3663
+ metadata.thinking = thinkingLevel?.trim();
3664
+ metadata.preferred_thinking = thinkingLevel?.trim();
3665
+ }
3666
+ if (readOptionalString$8(projectRoot)) metadata.project_root = projectRoot?.trim();
3667
+ }
3668
+ //#endregion
3669
+ //#region src/utils/session-context-inheritance.utils.ts
3670
+ const CONTEXT_INHERITANCE_METADATA_KEY = "context_inheritance";
3671
+ const INHERITED_FROM_SESSION_METADATA_KEY = "inherited_from_session_id";
3672
+ const INHERITED_FROM_MESSAGE_METADATA_KEY = "inherited_from_message_id";
3673
+ function hasToolCall(message, toolCallId) {
3674
+ return message.parts.some((part) => part.type === "tool-invocation" && part.toolCallId === toolCallId);
3675
+ }
3676
+ function findContextInheritanceAnchor(params) {
3677
+ const anchorToolCallId = readOptionalString$8(params.anchorToolCallId);
3678
+ if (!anchorToolCallId) return null;
3679
+ const index = params.messages.findIndex((message) => hasToolCall(message, anchorToolCallId));
3680
+ const message = index >= 0 ? params.messages[index] : void 0;
3681
+ return message ? {
3682
+ index,
3683
+ message
3684
+ } : null;
3685
+ }
3686
+ function createInheritedContextMessage(params) {
3687
+ const { childSessionId, index, sourceMessage, sourceSessionId } = params;
3688
+ const message = structuredClone(sourceMessage);
3689
+ const metadata = structuredClone(message.metadata ?? {});
3690
+ metadata[INHERITED_FROM_SESSION_METADATA_KEY] = sourceSessionId;
3691
+ metadata[INHERITED_FROM_MESSAGE_METADATA_KEY] = sourceMessage.id;
3692
+ return {
3693
+ ...message,
3694
+ id: `${childSessionId}:inherited:${index + 1}`,
3695
+ sessionId: childSessionId,
3696
+ metadata
3697
+ };
3698
+ }
3699
+ function createInheritedContextSnapshot(params) {
3700
+ const { anchorToolCallId, childSessionId, sourceRecord } = params;
3701
+ const anchor = findContextInheritanceAnchor({
3702
+ anchorToolCallId,
3703
+ messages: sourceRecord.messages
3704
+ });
3705
+ const messages = (anchor ? sourceRecord.messages.slice(0, anchor.index) : sourceRecord.messages).filter((message) => message.status === "final").map((sourceMessage, index) => createInheritedContextMessage({
3706
+ childSessionId,
3707
+ index,
3708
+ sourceMessage,
3709
+ sourceSessionId: sourceRecord.sessionId
3710
+ }));
3711
+ return {
3712
+ messages,
3713
+ metadata: {
3714
+ enabled: true,
3715
+ sourceSessionId: sourceRecord.sessionId,
3716
+ anchorKind: anchor ? "tool_call" : "latest_persisted",
3717
+ anchorToolCallId: readOptionalString$8(anchorToolCallId),
3718
+ anchorMessageId: anchor?.message.id,
3719
+ inheritedMessageCount: messages.length
3720
+ }
3721
+ };
3722
+ }
3723
+ function createSessionContextInheritance(params) {
3724
+ const { childSessionId, contextInheritance, metadata, parentSessionId, sourceRecord } = params;
3725
+ if (!contextInheritance) return {
3726
+ messages: [],
3727
+ metadata
3728
+ };
3729
+ if (!parentSessionId) throw new Error("contextInheritance requires a child session parentSessionId.");
3730
+ if (!sourceRecord) throw new Error("Cannot inherit context because the source session was not found.");
3731
+ const snapshot = createInheritedContextSnapshot({
3732
+ anchorToolCallId: contextInheritance.anchorToolCallId,
3733
+ childSessionId,
3734
+ sourceRecord
3735
+ });
3736
+ return {
3737
+ messages: snapshot.messages,
3738
+ metadata: {
3739
+ ...metadata,
3740
+ [CONTEXT_INHERITANCE_METADATA_KEY]: snapshot.metadata
3741
+ }
3742
+ };
3743
+ }
3584
3744
  //#endregion
3585
3745
  //#region src/contributions/session-activity-preview/utils/session-activity-preview-ncp-event.utils.ts
3586
3746
  const PREVIEW_TEXT_MAX_LENGTH = 160;
@@ -3860,69 +4020,9 @@ var SessionWorkingDirResolver = class {
3860
4020
  };
3861
4021
  //#endregion
3862
4022
  //#region src/managers/session.manager.ts
3863
- const DEFAULT_SESSION_TYPE = "native";
3864
- const DEFAULT_LIFECYCLE = "persistent";
3865
- const SESSION_METADATA_LABEL_KEY = "label";
3866
- const CHILD_SESSION_PARENT_METADATA_KEY = "parent_session_id";
3867
- const CHILD_SESSION_REQUEST_METADATA_KEY = "spawned_by_request_id";
3868
- const CHILD_SESSION_LIFECYCLE_METADATA_KEY = "session_lifecycle";
3869
- function readThinkingEffort(metadata) {
3870
- return readOptionalMetadataString(metadata?.thinkingEffort) ?? null;
3871
- }
3872
- function readProjectRoot(metadata) {
3873
- return readOptionalMetadataString(metadata?.project_root) ?? readOptionalMetadataString(metadata?.projectRoot);
3874
- }
3875
- function summarizeTask(task) {
3876
- const normalized = task.trim().replace(/\s+/g, " ");
3877
- if (!normalized) return "Session";
3878
- return normalized.length <= 72 ? normalized : `${normalized.slice(0, 69)}...`;
3879
- }
3880
4023
  function buildSessionId() {
3881
4024
  return `ncp-${Date.now().toString(36)}-${randomUUID().replace(/-/g, "").slice(0, 8)}`;
3882
4025
  }
3883
- function cloneInheritedMetadata(sourceMetadata) {
3884
- const nextMetadata = {};
3885
- for (const key of [
3886
- "runtime",
3887
- "session_type",
3888
- "preferred_model",
3889
- "preferred_thinking",
3890
- "project_root",
3891
- "requested_skill_refs",
3892
- "codex_runtime_backend",
3893
- "reasoningNormalizationMode",
3894
- "reasoning_normalization_mode"
3895
- ]) if (Object.prototype.hasOwnProperty.call(sourceMetadata, key)) nextMetadata[key] = structuredClone(sourceMetadata[key]);
3896
- return nextMetadata;
3897
- }
3898
- function mergeMetadataOverrides(metadata, overrides) {
3899
- return overrides && Object.keys(overrides).length > 0 ? {
3900
- ...metadata,
3901
- ...structuredClone(overrides)
3902
- } : metadata;
3903
- }
3904
- function resolveSessionType(params) {
3905
- const { metadata, runtime, sessionType } = params;
3906
- return readOptionalString$8(runtime) ?? readOptionalString$8(metadata.runtime) ?? readOptionalString$8(sessionType) ?? readOptionalString$8(metadata.session_type) ?? DEFAULT_SESSION_TYPE;
3907
- }
3908
- function applySessionOverrides(params) {
3909
- const { lifecycle, metadata, model, parentSessionId, projectRoot, requestId, sessionType, thinkingLevel, title } = params;
3910
- metadata.session_type = sessionType;
3911
- metadata.runtime = sessionType;
3912
- metadata[SESSION_METADATA_LABEL_KEY] = title;
3913
- metadata[CHILD_SESSION_LIFECYCLE_METADATA_KEY] = lifecycle;
3914
- if (parentSessionId) metadata[CHILD_SESSION_PARENT_METADATA_KEY] = parentSessionId;
3915
- if (requestId) metadata[CHILD_SESSION_REQUEST_METADATA_KEY] = requestId;
3916
- if (readOptionalString$8(model)) {
3917
- metadata.model = model?.trim();
3918
- metadata.preferred_model = model?.trim();
3919
- }
3920
- if (readOptionalString$8(thinkingLevel)) {
3921
- metadata.thinking = thinkingLevel?.trim();
3922
- metadata.preferred_thinking = thinkingLevel?.trim();
3923
- }
3924
- if (readOptionalString$8(projectRoot)) metadata.project_root = projectRoot?.trim();
3925
- }
3926
4026
  function isSessionSummaryRefreshEvent(event) {
3927
4027
  switch (event.type) {
3928
4028
  case NcpEventType.MessageSent:
@@ -3964,7 +4064,7 @@ var SessionManager = class {
3964
4064
  this.started = false;
3965
4065
  };
3966
4066
  createSession = async (params) => {
3967
- const { agentId: requestedAgentId, metadataOverrides, model, parentSessionId: rawParentSessionId, projectRoot, requestId: rawRequestId, runtime, sessionId: requestedSessionId, sessionType: requestedSessionType, sourceSessionId, sourceSessionMetadata, task, thinkingLevel, title: requestedTitle } = params;
4067
+ const { agentId: requestedAgentId, contextInheritance, metadataOverrides, model, parentSessionId: rawParentSessionId, projectRoot, requestId: rawRequestId, runtime, sessionId: requestedSessionId, sessionType: requestedSessionType, sourceSessionId, sourceSessionMetadata, task, thinkingLevel, title: requestedTitle } = params;
3968
4068
  const sourceRecord = sourceSessionId ? await this.getSessionRecord(sourceSessionId) : null;
3969
4069
  const metadata = cloneInheritedMetadata(sourceSessionMetadata);
3970
4070
  const title = readOptionalString$8(requestedTitle) ?? summarizeTask(task);
@@ -3976,7 +4076,7 @@ var SessionManager = class {
3976
4076
  metadata
3977
4077
  });
3978
4078
  applySessionOverrides({
3979
- lifecycle: DEFAULT_LIFECYCLE,
4079
+ lifecycle: DEFAULT_SESSION_LIFECYCLE,
3980
4080
  metadata,
3981
4081
  model,
3982
4082
  parentSessionId: parentSessionId ?? void 0,
@@ -3990,13 +4090,20 @@ var SessionManager = class {
3990
4090
  const nextMetadata = mergeMetadataOverrides(metadata, metadataOverrides);
3991
4091
  const agentId = readOptionalString$8(requestedAgentId) ?? readOptionalString$8(sourceRecord?.agentId) ?? BUILTIN_MAIN_AGENT_ID;
3992
4092
  const sessionId = readOptionalString$8(requestedSessionId) ?? buildSessionId();
4093
+ const inheritedContext = createSessionContextInheritance({
4094
+ childSessionId: sessionId,
4095
+ contextInheritance,
4096
+ metadata: nextMetadata,
4097
+ parentSessionId,
4098
+ sourceRecord
4099
+ });
3993
4100
  const record = {
3994
4101
  sessionId,
3995
4102
  ...agentId ? { agentId } : {},
3996
- messages: [],
4103
+ messages: inheritedContext.messages,
3997
4104
  createdAt: now,
3998
4105
  updatedAt: now,
3999
- metadata: nextMetadata
4106
+ metadata: inheritedContext.metadata
4000
4107
  };
4001
4108
  await this.options.journalStore.importSessionSnapshot(record);
4002
4109
  await this.publishSessionChange(sessionId);
@@ -4004,12 +4111,12 @@ var SessionManager = class {
4004
4111
  sessionId,
4005
4112
  agentId,
4006
4113
  sessionType,
4007
- runtimeFamily: sessionType === DEFAULT_SESSION_TYPE ? "native" : "external",
4114
+ runtimeFamily: sessionType === "native" ? "native" : "external",
4008
4115
  ...parentSessionId ? { parentSessionId } : {},
4009
4116
  ...requestId ? { spawnedByRequestId: requestId } : {},
4010
- lifecycle: DEFAULT_LIFECYCLE,
4117
+ lifecycle: DEFAULT_SESSION_LIFECYCLE,
4011
4118
  title,
4012
- metadata: nextMetadata,
4119
+ metadata: inheritedContext.metadata,
4013
4120
  createdAt: now,
4014
4121
  updatedAt: now
4015
4122
  };
@@ -4097,9 +4204,13 @@ var SessionManager = class {
4097
4204
  };
4098
4205
  };
4099
4206
  createAgentRunSession = async (params) => {
4100
- const { agentId, agentRuntimeId: requestedAgentRuntimeId, channel, metadata, model, peerId: rawPeerId, projectRoot, sessionId, task, thinkingEffort } = params;
4101
- const agentRuntimeId = requestedAgentRuntimeId ?? "native";
4207
+ const { agentId, agentRuntimeId: requestedAgentRuntimeId, channel, contextInheritance, metadata, model, parentSessionId: rawParentSessionId, peerId: rawPeerId, projectRoot, sessionId, sourceSessionId: rawSourceSessionId, sourceSessionMetadata: requestedSourceSessionMetadata, task, thinkingEffort } = params;
4102
4208
  const peerId = readOptionalString$8(rawPeerId);
4209
+ const parentSessionId = readOptionalString$8(rawParentSessionId);
4210
+ const sourceSessionId = readOptionalString$8(rawSourceSessionId);
4211
+ const sourceRecord = sourceSessionId ? await this.getSessionRecord(sourceSessionId) : null;
4212
+ const sourceSessionMetadata = requestedSourceSessionMetadata ?? sourceRecord?.metadata ?? {};
4213
+ const agentRuntimeId = requestedAgentRuntimeId ?? readAgentRuntimeId(sourceSessionMetadata) ?? "native";
4103
4214
  const peerIdentity = peerId ? createAgentPeerSessionIdentity({
4104
4215
  agentId,
4105
4216
  channel,
@@ -4108,7 +4219,10 @@ var SessionManager = class {
4108
4219
  }) : void 0;
4109
4220
  const requestedSessionId = readOptionalString$8(sessionId);
4110
4221
  const created = await this.createSession({
4111
- sourceSessionMetadata: {},
4222
+ contextInheritance,
4223
+ parentSessionId: parentSessionId ?? void 0,
4224
+ sourceSessionId: sourceSessionId ?? void 0,
4225
+ sourceSessionMetadata,
4112
4226
  sessionId: requestedSessionId ?? peerIdentity?.sessionId,
4113
4227
  task: task ?? "Session",
4114
4228
  agentId,
@@ -4124,16 +4238,16 @@ var SessionManager = class {
4124
4238
  });
4125
4239
  return {
4126
4240
  sessionId: created.sessionId,
4127
- agentId,
4241
+ agentId: created.agentId,
4128
4242
  agentRuntimeId,
4129
4243
  metadata: structuredClone(created.metadata ?? {}),
4130
- model,
4131
- projectRoot,
4244
+ model: model ?? readOptionalMetadataString(created.metadata?.model) ?? readOptionalMetadataString(created.metadata?.preferred_model),
4245
+ projectRoot: projectRoot ?? readProjectRoot(created.metadata),
4132
4246
  workingDir: this.workingDirResolver.resolve({
4133
- agentId,
4247
+ agentId: created.agentId,
4134
4248
  metadata: created.metadata
4135
4249
  }),
4136
- thinkingEffort: thinkingEffort ?? null
4250
+ thinkingEffort: thinkingEffort ?? readThinkingEffort(created.metadata)
4137
4251
  };
4138
4252
  };
4139
4253
  getOrCreateAgentRunSession = async (params) => {
@@ -7151,7 +7265,7 @@ var SessionRequestManager = class {
7151
7265
  this.options = options;
7152
7266
  }
7153
7267
  spawnSessionAndRequest = async (params) => {
7154
- const { sourceSessionId, sourceToolCallId, updateToolCallResult, sourceSessionMetadata, metadataOverrides, task, title, model, runtime, handoffDepth, sessionType, thinkingLevel, projectRoot, agentId, parentSessionId, notify } = params;
7268
+ const { sourceSessionId, sourceToolCallId, updateToolCallResult, sourceSessionMetadata, metadataOverrides, contextInheritance, task, title, model, runtime, handoffDepth, sessionType, thinkingLevel, projectRoot, agentId, parentSessionId, notify } = params;
7155
7269
  const requestId = randomUUID();
7156
7270
  const createdSession = await this.options.sessionManager.createSession({
7157
7271
  sourceSessionId,
@@ -7160,6 +7274,7 @@ var SessionRequestManager = class {
7160
7274
  title,
7161
7275
  sourceSessionMetadata,
7162
7276
  ...metadataOverrides ? { metadataOverrides } : {},
7277
+ contextInheritance,
7163
7278
  agentId,
7164
7279
  model,
7165
7280
  runtime,
@@ -9534,6 +9649,11 @@ function readSpawnNotify(value) {
9534
9649
  if (notifyMode === "none" || notifyMode === "final_reply") return notifyMode;
9535
9650
  throw new Error("notify must be \"none\" or \"final_reply\".");
9536
9651
  }
9652
+ function readInheritContext(value) {
9653
+ if (typeof value === "undefined") return false;
9654
+ if (typeof value === "boolean") return value;
9655
+ throw new Error("inheritContext must be a boolean.");
9656
+ }
9537
9657
  var SessionSpawnTool = class {
9538
9658
  name = "sessions_spawn";
9539
9659
  description = "Create a new session. Use scope=\"child\" to create a child session of the current flow, and add notify when the new session should start immediately.";
@@ -9569,6 +9689,10 @@ var SessionSpawnTool = class {
9569
9689
  type: "string",
9570
9690
  enum: ["none", "final_reply"],
9571
9691
  description: "Optional. Starts the new session immediately. Use \"final_reply\" to continue this session after the new session reaches its final reply, or \"none\" to let it run independently."
9692
+ },
9693
+ inheritContext: {
9694
+ type: "boolean",
9695
+ description: "Child sessions only. When true, the child starts with parent context inherited up to this tool call."
9572
9696
  }
9573
9697
  },
9574
9698
  required: ["task"],
@@ -9587,11 +9711,14 @@ var SessionSpawnTool = class {
9587
9711
  this.handoffDepth = params.handoffDepth ?? 0;
9588
9712
  };
9589
9713
  execute = async (args, context) => {
9590
- const { agentId: rawAgentId, model: rawModel, notify: rawNotify, runtime: rawRuntime, scope: rawScope, task: rawTask, title: rawTitle } = normalizeToolParams(args);
9714
+ const { agentId: rawAgentId, model: rawModel, notify: rawNotify, runtime: rawRuntime, scope: rawScope, task: rawTask, title: rawTitle, inheritContext: rawInheritContext } = normalizeToolParams(args);
9591
9715
  const task = readRequiredString$1(rawTask, "task");
9592
9716
  const scope = readSpawnScope(rawScope);
9593
9717
  const notify = readSpawnNotify(rawNotify);
9718
+ const inheritContext = readInheritContext(rawInheritContext);
9719
+ if (inheritContext && scope !== "child") throw new Error("inheritContext=true requires scope=\"child\".");
9594
9720
  const parentSessionId = scope === "child" ? this.readParentSessionIdOrThrow() : void 0;
9721
+ const contextInheritance = inheritContext ? { anchorToolCallId: context?.toolCallId } : void 0;
9595
9722
  if (notify) return this.sessionRequestManager.spawnSessionAndRequest({
9596
9723
  sourceSessionId: this.sourceSessionId,
9597
9724
  sourceToolCallId: context?.toolCallId,
@@ -9602,6 +9729,7 @@ var SessionSpawnTool = class {
9602
9729
  agentId: readOptionalString$2(rawAgentId),
9603
9730
  model: readOptionalString$2(rawModel),
9604
9731
  runtime: readOptionalString$2(rawRuntime),
9732
+ contextInheritance,
9605
9733
  handoffDepth: this.handoffDepth,
9606
9734
  parentSessionId,
9607
9735
  notify
@@ -9614,6 +9742,7 @@ var SessionSpawnTool = class {
9614
9742
  agentId: readOptionalString$2(rawAgentId),
9615
9743
  model: readOptionalString$2(rawModel),
9616
9744
  runtime: readOptionalString$2(rawRuntime),
9745
+ contextInheritance,
9617
9746
  parentSessionId
9618
9747
  });
9619
9748
  return {