@truefoundry/trueforge-core 0.1.0-rc.0 → 0.1.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.
Files changed (184) hide show
  1. package/README.md +27 -0
  2. package/dist/agent-session/TurnResourceResolver.d.ts.map +1 -1
  3. package/dist/agent-session/TurnResourceResolver.js +6 -2
  4. package/dist/agent-session/TurnResourceResolver.js.map +1 -1
  5. package/dist/agent-session/TurnResourceResolver.mjs +6 -2
  6. package/dist/agent-session/TurnResourceResolver.mjs.map +1 -1
  7. package/dist/agent-session/schemas/turn.d.ts.map +1 -1
  8. package/dist/agent-session/schemas/turn.js +3 -1
  9. package/dist/agent-session/schemas/turn.js.map +1 -1
  10. package/dist/agent-session/schemas/turn.mjs +3 -1
  11. package/dist/agent-session/schemas/turn.mjs.map +1 -1
  12. package/dist/agent-session/store/InMemorySessionStore.d.ts.map +1 -1
  13. package/dist/agent-session/store/InMemorySessionStore.js +24 -8
  14. package/dist/agent-session/store/InMemorySessionStore.js.map +1 -1
  15. package/dist/agent-session/store/InMemorySessionStore.mjs +24 -8
  16. package/dist/agent-session/store/InMemorySessionStore.mjs.map +1 -1
  17. package/dist/agent-session/store/OffsetPageToken.d.ts.map +1 -1
  18. package/dist/agent-session/store/OffsetPageToken.js +3 -1
  19. package/dist/agent-session/store/OffsetPageToken.js.map +1 -1
  20. package/dist/agent-session/store/OffsetPageToken.mjs +3 -1
  21. package/dist/agent-session/store/OffsetPageToken.mjs.map +1 -1
  22. package/dist/agent-session/store/SessionListPageToken.d.ts.map +1 -1
  23. package/dist/agent-session/store/SessionListPageToken.js +3 -1
  24. package/dist/agent-session/store/SessionListPageToken.js.map +1 -1
  25. package/dist/agent-session/store/SessionListPageToken.mjs +3 -1
  26. package/dist/agent-session/store/SessionListPageToken.mjs.map +1 -1
  27. package/dist/core/InstructionBuilder.d.ts.map +1 -1
  28. package/dist/core/InstructionBuilder.js +12 -4
  29. package/dist/core/InstructionBuilder.js.map +1 -1
  30. package/dist/core/InstructionBuilder.mjs +12 -4
  31. package/dist/core/InstructionBuilder.mjs.map +1 -1
  32. package/dist/core/capabilities/builtins/AskUserQuestion.d.ts.map +1 -1
  33. package/dist/core/capabilities/builtins/AskUserQuestion.js +5 -0
  34. package/dist/core/capabilities/builtins/AskUserQuestion.js.map +1 -1
  35. package/dist/core/capabilities/builtins/AskUserQuestion.mjs +5 -0
  36. package/dist/core/capabilities/builtins/AskUserQuestion.mjs.map +1 -1
  37. package/dist/core/capabilities/builtins/LargeToolResponse.d.ts.map +1 -1
  38. package/dist/core/capabilities/builtins/LargeToolResponse.js +6 -2
  39. package/dist/core/capabilities/builtins/LargeToolResponse.js.map +1 -1
  40. package/dist/core/capabilities/builtins/LargeToolResponse.mjs +6 -2
  41. package/dist/core/capabilities/builtins/LargeToolResponse.mjs.map +1 -1
  42. package/dist/core/index.d.ts +9 -3
  43. package/dist/core/index.d.ts.map +1 -1
  44. package/dist/core/index.js +25 -0
  45. package/dist/core/index.js.map +1 -1
  46. package/dist/core/index.mjs +24 -2
  47. package/dist/core/index.mjs.map +1 -1
  48. package/dist/core/llm/VercelAILLM.d.ts +1 -0
  49. package/dist/core/llm/VercelAILLM.d.ts.map +1 -1
  50. package/dist/core/llm/VercelAILLM.js +13 -14
  51. package/dist/core/llm/VercelAILLM.js.map +1 -1
  52. package/dist/core/llm/VercelAILLM.mjs +13 -15
  53. package/dist/core/llm/VercelAILLM.mjs.map +1 -1
  54. package/dist/core/mcp/RemoteMCP.d.ts.map +1 -1
  55. package/dist/core/mcp/RemoteMCP.js +15 -5
  56. package/dist/core/mcp/RemoteMCP.js.map +1 -1
  57. package/dist/core/mcp/RemoteMCP.mjs +15 -5
  58. package/dist/core/mcp/RemoteMCP.mjs.map +1 -1
  59. package/dist/core/mcp/ToolSelectorPolicy.d.ts.map +1 -1
  60. package/dist/core/mcp/ToolSelectorPolicy.js +3 -1
  61. package/dist/core/mcp/ToolSelectorPolicy.js.map +1 -1
  62. package/dist/core/mcp/ToolSelectorPolicy.mjs +3 -1
  63. package/dist/core/mcp/ToolSelectorPolicy.mjs.map +1 -1
  64. package/dist/core/mcp/ToolSet.d.ts.map +1 -1
  65. package/dist/core/mcp/ToolSet.js +9 -3
  66. package/dist/core/mcp/ToolSet.js.map +1 -1
  67. package/dist/core/mcp/ToolSet.mjs +9 -3
  68. package/dist/core/mcp/ToolSet.mjs.map +1 -1
  69. package/dist/core/mcp/convertMCPServers.d.ts.map +1 -1
  70. package/dist/core/mcp/convertMCPServers.js +6 -2
  71. package/dist/core/mcp/convertMCPServers.js.map +1 -1
  72. package/dist/core/mcp/convertMCPServers.mjs +6 -2
  73. package/dist/core/mcp/convertMCPServers.mjs.map +1 -1
  74. package/dist/core/mcp/remoteMcpClient.d.ts.map +1 -1
  75. package/dist/core/mcp/remoteMcpClient.js +21 -7
  76. package/dist/core/mcp/remoteMcpClient.js.map +1 -1
  77. package/dist/core/mcp/remoteMcpClient.mjs +21 -7
  78. package/dist/core/mcp/remoteMcpClient.mjs.map +1 -1
  79. package/dist/core/mcp/toolSelectors.d.ts.map +1 -1
  80. package/dist/core/mcp/toolSelectors.js +18 -6
  81. package/dist/core/mcp/toolSelectors.js.map +1 -1
  82. package/dist/core/mcp/toolSelectors.mjs +18 -6
  83. package/dist/core/mcp/toolSelectors.mjs.map +1 -1
  84. package/dist/core/runtime/AgentThread.d.ts.map +1 -1
  85. package/dist/core/runtime/AgentThread.js +45 -15
  86. package/dist/core/runtime/AgentThread.js.map +1 -1
  87. package/dist/core/runtime/AgentThread.mjs +45 -15
  88. package/dist/core/runtime/AgentThread.mjs.map +1 -1
  89. package/dist/core/runtime/AgentThreadOrchestrator.d.ts.map +1 -1
  90. package/dist/core/runtime/AgentThreadOrchestrator.js +27 -9
  91. package/dist/core/runtime/AgentThreadOrchestrator.js.map +1 -1
  92. package/dist/core/runtime/AgentThreadOrchestrator.mjs +27 -9
  93. package/dist/core/runtime/AgentThreadOrchestrator.mjs.map +1 -1
  94. package/dist/core/runtime/DeferredTool.d.ts.map +1 -1
  95. package/dist/core/runtime/DeferredTool.js +15 -5
  96. package/dist/core/runtime/DeferredTool.js.map +1 -1
  97. package/dist/core/runtime/DeferredTool.mjs +15 -5
  98. package/dist/core/runtime/DeferredTool.mjs.map +1 -1
  99. package/dist/core/runtime/contextUtils.d.ts.map +1 -1
  100. package/dist/core/runtime/contextUtils.js +3 -1
  101. package/dist/core/runtime/contextUtils.js.map +1 -1
  102. package/dist/core/runtime/contextUtils.mjs +3 -1
  103. package/dist/core/runtime/contextUtils.mjs.map +1 -1
  104. package/dist/core/sandbox/Sandbox.d.ts +7 -9
  105. package/dist/core/sandbox/Sandbox.d.ts.map +1 -1
  106. package/dist/core/sandbox/Sandbox.js +55 -63
  107. package/dist/core/sandbox/Sandbox.js.map +1 -1
  108. package/dist/core/sandbox/Sandbox.mjs +56 -64
  109. package/dist/core/sandbox/Sandbox.mjs.map +1 -1
  110. package/dist/core/sandbox/codeMode/CodeModeDispatcher.d.ts +29 -0
  111. package/dist/core/sandbox/codeMode/CodeModeDispatcher.d.ts.map +1 -0
  112. package/dist/core/sandbox/codeMode/CodeModeDispatcher.js +134 -0
  113. package/dist/core/sandbox/codeMode/CodeModeDispatcher.js.map +1 -0
  114. package/dist/core/sandbox/codeMode/CodeModeDispatcher.mjs +113 -0
  115. package/dist/core/sandbox/codeMode/CodeModeDispatcher.mjs.map +1 -0
  116. package/dist/core/sandbox/codeMode/CodeModeTransport.d.ts +21 -0
  117. package/dist/core/sandbox/codeMode/CodeModeTransport.d.ts.map +1 -0
  118. package/dist/core/sandbox/codeMode/CodeModeTransport.js +19 -0
  119. package/dist/core/sandbox/codeMode/CodeModeTransport.js.map +1 -0
  120. package/dist/core/sandbox/codeMode/CodeModeTransport.mjs +1 -0
  121. package/dist/core/sandbox/codeMode/CodeModeTransport.mjs.map +1 -0
  122. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.d.ts +34 -0
  123. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.d.ts.map +1 -0
  124. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.js +193 -0
  125. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.js.map +1 -0
  126. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.mjs +168 -0
  127. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.mjs.map +1 -0
  128. package/dist/core/sandbox/codeMode/types.d.ts +34 -0
  129. package/dist/core/sandbox/codeMode/types.d.ts.map +1 -0
  130. package/dist/core/sandbox/codeMode/types.js +59 -0
  131. package/dist/core/sandbox/codeMode/types.js.map +1 -0
  132. package/dist/core/sandbox/codeMode/types.mjs +32 -0
  133. package/dist/core/sandbox/codeMode/types.mjs.map +1 -0
  134. package/dist/core/sandbox/provider/DaytonaProvider.d.ts +19 -1
  135. package/dist/core/sandbox/provider/DaytonaProvider.d.ts.map +1 -1
  136. package/dist/core/sandbox/provider/DaytonaProvider.js +96 -23
  137. package/dist/core/sandbox/provider/DaytonaProvider.js.map +1 -1
  138. package/dist/core/sandbox/provider/DaytonaProvider.mjs +96 -23
  139. package/dist/core/sandbox/provider/DaytonaProvider.mjs.map +1 -1
  140. package/dist/core/sandbox/provider/Provider.d.ts +4 -3
  141. package/dist/core/sandbox/provider/Provider.d.ts.map +1 -1
  142. package/dist/core/sandbox/provider/Provider.js.map +1 -1
  143. package/dist/core/sandbox/provider/Provider.mjs.map +1 -1
  144. package/dist/core/sandbox/provider/TFYSandboxProvider.d.ts +2 -1
  145. package/dist/core/sandbox/provider/TFYSandboxProvider.d.ts.map +1 -1
  146. package/dist/core/sandbox/provider/TFYSandboxProvider.js +20 -6
  147. package/dist/core/sandbox/provider/TFYSandboxProvider.js.map +1 -1
  148. package/dist/core/sandbox/provider/TFYSandboxProvider.mjs +20 -6
  149. package/dist/core/sandbox/provider/TFYSandboxProvider.mjs.map +1 -1
  150. package/dist/core/sandbox/sandboxImage.d.ts +1 -1
  151. package/dist/core/sandbox/sandboxImage.d.ts.map +1 -1
  152. package/dist/core/sandbox/sandboxImage.js +1 -1
  153. package/dist/core/sandbox/sandboxImage.js.map +1 -1
  154. package/dist/core/sandbox/sandboxImage.mjs +1 -1
  155. package/dist/core/sandbox/sandboxImage.mjs.map +1 -1
  156. package/dist/core/sandbox/sandboxScripts.gen.d.ts +1 -1
  157. package/dist/core/sandbox/sandboxScripts.gen.d.ts.map +1 -1
  158. package/dist/core/sandbox/sandboxScripts.gen.js +8 -8
  159. package/dist/core/sandbox/sandboxScripts.gen.js.map +1 -1
  160. package/dist/core/sandbox/sandboxScripts.gen.mjs +8 -8
  161. package/dist/core/sandbox/sandboxScripts.gen.mjs.map +1 -1
  162. package/dist/core/sandbox/skills/SkillMounter.d.ts.map +1 -1
  163. package/dist/core/sandbox/skills/SkillMounter.js +3 -1
  164. package/dist/core/sandbox/skills/SkillMounter.js.map +1 -1
  165. package/dist/core/sandbox/skills/SkillMounter.mjs +3 -1
  166. package/dist/core/sandbox/skills/SkillMounter.mjs.map +1 -1
  167. package/dist/core/util/abort.d.ts.map +1 -1
  168. package/dist/core/util/abort.js +3 -1
  169. package/dist/core/util/abort.js.map +1 -1
  170. package/dist/core/util/abort.mjs +3 -1
  171. package/dist/core/util/abort.mjs.map +1 -1
  172. package/dist/core/util/errorLogFields.d.ts +5 -0
  173. package/dist/core/util/errorLogFields.d.ts.map +1 -1
  174. package/dist/core/util/errorLogFields.js +38 -2
  175. package/dist/core/util/errorLogFields.js.map +1 -1
  176. package/dist/core/util/errorLogFields.mjs +37 -2
  177. package/dist/core/util/errorLogFields.mjs.map +1 -1
  178. package/package.json +10 -6
  179. package/dist/core/sandbox/SandboxNatsBridge.d.ts +0 -33
  180. package/dist/core/sandbox/SandboxNatsBridge.d.ts.map +0 -1
  181. package/dist/core/sandbox/SandboxNatsBridge.js +0 -222
  182. package/dist/core/sandbox/SandboxNatsBridge.js.map +0 -1
  183. package/dist/core/sandbox/SandboxNatsBridge.mjs +0 -201
  184. package/dist/core/sandbox/SandboxNatsBridge.mjs.map +0 -1
@@ -27,8 +27,12 @@ function turnKey({ session_id, turn_id }) {
27
27
  return `${session_id}:${turn_id}`;
28
28
  }
29
29
  function compareSessionId(a, b) {
30
- if (a < b) return -1;
31
- if (a > b) return 1;
30
+ if (a < b) {
31
+ return -1;
32
+ }
33
+ if (a > b) {
34
+ return 1;
35
+ }
32
36
  return 0;
33
37
  }
34
38
  function newThreadSnapshot(thread) {
@@ -156,7 +160,9 @@ var InMemorySessionStore = class {
156
160
  async listSessions(input) {
157
161
  const records = [];
158
162
  for (const stored of this.sessions.values()) {
159
- if (stored.record.tenant_id !== input.tenant_id) continue;
163
+ if (stored.record.tenant_id !== input.tenant_id) {
164
+ continue;
165
+ }
160
166
  if (input.agent_id !== void 0 && (stored.record.agent.type !== "reference" || stored.record.agent.id !== input.agent_id)) {
161
167
  continue;
162
168
  }
@@ -164,8 +170,12 @@ var InMemorySessionStore = class {
164
170
  continue;
165
171
  }
166
172
  const createdAt = stored.record.created_at.getTime();
167
- if (input.start_timestamp !== void 0 && createdAt < input.start_timestamp.getTime()) continue;
168
- if (input.end_timestamp !== void 0 && createdAt > input.end_timestamp.getTime()) continue;
173
+ if (input.start_timestamp !== void 0 && createdAt < input.start_timestamp.getTime()) {
174
+ continue;
175
+ }
176
+ if (input.end_timestamp !== void 0 && createdAt > input.end_timestamp.getTime()) {
177
+ continue;
178
+ }
169
179
  records.push(stored.record);
170
180
  }
171
181
  records.sort((a, b) => {
@@ -445,11 +455,17 @@ var InMemorySessionStore = class {
445
455
  let oldestId = chain[0];
446
456
  while (oldestId && oldestId !== anchor.turn_id) {
447
457
  const oldest = this.turns.get(turnKey({ session_id: sessionId, turn_id: oldestId }));
448
- if (!oldest) break;
458
+ if (!oldest) {
459
+ break;
460
+ }
449
461
  const older = oldest.ancestor_ids.filter((id) => !seen.has(id));
450
- if (older.length === 0) break;
462
+ if (older.length === 0) {
463
+ break;
464
+ }
451
465
  chain.unshift(...older);
452
- for (const id of older) seen.add(id);
466
+ for (const id of older) {
467
+ seen.add(id);
468
+ }
453
469
  oldestId = older[0];
454
470
  }
455
471
  return chain;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/agent-session/store/InMemorySessionStore.ts"],"sourcesContent":["import type { AgentThreadSnapshot } from '../../core/runtime/AgentThread.types';\nimport { getEmptyCurrentContextUsage } from '../../core/runtime/contextUsage';\nimport type { SessionRecord } from '../models/SessionRecord';\nimport type { TurnRecord, TurnSnapshot } from '../models/TurnRecord';\nimport type { PersistedTurnEvent, SessionEventItem } from '../schemas/events';\nimport type { TokenPagination } from '../schemas/pagination';\nimport { CancellationReason, type TerminalTurnState } from '../schemas/turn';\nimport { assertCreateTurnThreadDelta } from './assertCreateTurnThreadDelta';\nimport type {\n AddThreadsInput,\n AppendToEventsInput,\n AppendToThreadContextInput,\n CreateSessionInput,\n CreateTurnInput,\n DeleteSessionInput,\n FreezeAndGetTurnInput,\n GetSessionInput,\n GetTurnInput,\n ISessionStore,\n ListSessionEventsInput,\n ListSessionsInput,\n ListTurnEventsInput,\n ListTurnsInput,\n NewThreadInit,\n OverwriteThreadContextInput,\n PatchMCPServersInput,\n PatchSandboxInfoInput,\n PatchThreadCapabilityStateInput,\n RemoveThreadsInput,\n TurnContextAppend,\n TurnRecordWithoutSnapshot,\n UpdateSessionInput,\n UpdateTurnStateInput,\n} from './ISessionStore';\nimport { decodeOffsetPageToken, encodeOffsetPageToken } from './OffsetPageToken';\nimport {\n decodeSessionEventPageToken,\n paginateSessionEventRows,\n type SessionEventPageCursor,\n} from './SessionEventPageToken';\nimport { decodeSessionListPageToken, paginateSessionListRows } from './SessionListPageToken';\nimport {\n PreviousTurnRunningError,\n SessionAlreadyExistsError,\n SessionNotFoundError,\n SessionStoreInvariantError,\n TurnAlreadyExistsError,\n TurnNotFoundError,\n TurnNotRunningError,\n} from './SessionStoreErrors';\n\n/* eslint-disable @typescript-eslint/require-await -- in-memory store is synchronous; methods stay async so thrown SessionStore*Error reject as Promises for ISessionStore callers */\n\ntype StoredEvent = PersistedTurnEvent;\n\ninterface StoredSession<TSessionCustom extends object> {\n record: SessionRecord<TSessionCustom>;\n turnIds: string[];\n}\n\nfunction deepCopy<T>(value: T): T {\n return structuredClone(value);\n}\n\nfunction sessionKey(sessionId: string): string {\n return sessionId;\n}\n\nfunction turnKey({ session_id, turn_id }: { session_id: string; turn_id: string }): string {\n return `${session_id}:${turn_id}`;\n}\n\n/** Lexicographic session_id order — shared by listSessions sort and keyset filter. */\nfunction compareSessionId(a: string, b: string): number {\n if (a < b) return -1;\n if (a > b) return 1;\n return 0;\n}\n\nfunction newThreadSnapshot(thread: NewThreadInit): AgentThreadSnapshot {\n return {\n thread_id: thread.thread_id,\n parent: thread.parent ?? null,\n agent_info: thread.agent_info ?? null,\n capability_state: null,\n context: [],\n current_context_usage: getEmptyCurrentContextUsage(),\n completion: null,\n };\n}\n\nfunction applyContextAppends(threads: Record<string, AgentThreadSnapshot>, appends: TurnContextAppend[]): void {\n for (const append of appends) {\n const thread = threads[append.thread_id];\n if (!thread) {\n throw new SessionStoreInvariantError(`new_context_appends references unknown thread ${append.thread_id}`);\n }\n thread.context.push(...deepCopy(append.context));\n if (append.current_context_usage !== null) {\n thread.current_context_usage = deepCopy(append.current_context_usage);\n }\n }\n}\n\nfunction buildSnapshotFromDelta(input: {\n previousSnapshot: TurnSnapshot | undefined;\n new_threads: NewThreadInit[];\n new_context_appends: TurnContextAppend[];\n capability_states: CreateTurnInput['capability_states'];\n}): TurnSnapshot {\n const threads: Record<string, AgentThreadSnapshot> = input.previousSnapshot\n ? deepCopy(input.previousSnapshot.threads)\n : {};\n\n assertCreateTurnThreadDelta({\n previousThreadIds: new Set(Object.keys(threads)),\n new_threads: input.new_threads,\n new_context_appends: input.new_context_appends,\n capability_states: input.capability_states,\n });\n\n for (const nt of input.new_threads) {\n threads[nt.thread_id] = newThreadSnapshot(nt);\n }\n\n applyContextAppends(threads, input.new_context_appends);\n for (const capability of input.capability_states) {\n const thread = threads[capability.thread_id];\n if (thread === undefined) {\n throw new SessionStoreInvariantError(`capability_states references unknown thread ${capability.thread_id}`);\n }\n thread.capability_state = deepCopy(capability.capability_state);\n }\n\n return {\n threads,\n mcp_servers: input.previousSnapshot ? deepCopy(input.previousSnapshot.mcp_servers) : null,\n sandbox_info: input.previousSnapshot ? deepCopy(input.previousSnapshot.sandbox_info) : null,\n };\n}\n\nfunction paginate<T>(items: T[], limit: number, pageToken?: string): { data: T[]; pagination: TokenPagination } {\n const offset = decodeOffsetPageToken(pageToken);\n const slice = items.slice(offset, offset + limit);\n return {\n data: slice,\n pagination: {\n limit,\n ...(offset + limit < items.length ? { next_page_token: encodeOffsetPageToken(offset + limit) } : {}),\n ...(offset > 0 ? { previous_page_token: encodeOffsetPageToken(Math.max(0, offset - limit)) } : {}),\n },\n };\n}\n\n/**\n * Reference ISessionStore implementation. Proves the contract without SSE/subscription\n * hooks. Deep-copies on read/write boundaries so callers cannot mutate stored state.\n */\nexport class InMemorySessionStore<\n TSessionCustom extends object = Record<string, never>,\n TTurnCustom extends object = Record<string, never>,\n> implements ISessionStore<TSessionCustom, TTurnCustom> {\n private readonly sessions = new Map<string, StoredSession<TSessionCustom>>();\n private readonly turns = new Map<string, TurnRecord<TTurnCustom>>();\n private readonly events = new Map<string, StoredEvent[]>();\n\n async createSession(input: CreateSessionInput<TSessionCustom>): Promise<void> {\n const key = sessionKey(input.session_id);\n if (this.sessions.has(key)) {\n throw new SessionAlreadyExistsError(input.session_id);\n }\n const now = new Date();\n const record: SessionRecord<TSessionCustom> = {\n tenant_id: input.tenant_id,\n session_id: input.session_id,\n created_by: input.created_by,\n agent: deepCopy(input.agent),\n title: null,\n last_turn_id: null,\n created_at: now,\n updated_at: now,\n last_activity_timestamp_ms: Date.now(),\n custom: input.custom !== null ? deepCopy(input.custom) : null,\n };\n this.sessions.set(key, { record, turnIds: [] });\n return;\n }\n\n async deleteSession(input: DeleteSessionInput): Promise<void> {\n const sKey = sessionKey(input.session_id);\n const stored = this.sessions.get(sKey);\n if (stored?.record.tenant_id !== input.tenant_id) {\n return;\n }\n for (const turnId of stored.turnIds) {\n const tKey = turnKey({ session_id: input.session_id, turn_id: turnId });\n this.turns.delete(tKey);\n this.events.delete(tKey);\n }\n this.sessions.delete(sKey);\n }\n\n async getSession(input: GetSessionInput): Promise<SessionRecord<TSessionCustom> | undefined> {\n const stored = this.sessions.get(sessionKey(input.session_id));\n return stored?.record.tenant_id === input.tenant_id ? deepCopy(stored.record) : undefined;\n }\n\n async updateSession(input: UpdateSessionInput<TSessionCustom>): Promise<void> {\n const key = sessionKey(input.session_id);\n const stored = this.sessions.get(key);\n if (stored?.record.tenant_id !== input.tenant_id) {\n throw new SessionNotFoundError(input.session_id);\n }\n if (input.agent !== undefined) {\n if (stored.record.agent.type === 'reference') {\n throw new SessionStoreInvariantError(`Session ${input.session_id} is named; agent cannot be updated`);\n }\n stored.record.agent = deepCopy(input.agent);\n }\n if (input.title !== undefined) {\n stored.record.title = input.title;\n }\n const now = Date.now();\n stored.record.updated_at = new Date(now);\n stored.record.last_activity_timestamp_ms = now;\n return;\n }\n\n async listSessions(\n input: ListSessionsInput,\n ): Promise<{ data: SessionRecord<TSessionCustom>[]; pagination: TokenPagination }> {\n const records: SessionRecord<TSessionCustom>[] = [];\n for (const stored of this.sessions.values()) {\n if (stored.record.tenant_id !== input.tenant_id) continue;\n if (\n input.agent_id !== undefined &&\n (stored.record.agent.type !== 'reference' || stored.record.agent.id !== input.agent_id)\n ) {\n continue;\n }\n if (input.created_by !== undefined && stored.record.created_by !== input.created_by) {\n continue;\n }\n const createdAt = stored.record.created_at.getTime();\n if (input.start_timestamp !== undefined && createdAt < input.start_timestamp.getTime()) continue;\n if (input.end_timestamp !== undefined && createdAt > input.end_timestamp.getTime()) continue;\n records.push(stored.record);\n }\n records.sort((a, b) => {\n const aTime = a.updated_at.getTime();\n const bTime = b.updated_at.getTime();\n if (aTime !== bTime) {\n return input.order === 'asc' ? aTime - bTime : bTime - aTime;\n }\n // Same lexicographic order as the keyset predicate below (and Postgres/SQLite).\n return input.order === 'asc'\n ? compareSessionId(a.session_id, b.session_id)\n : compareSessionId(b.session_id, a.session_id);\n });\n\n let filtered = records;\n const cursor = decodeSessionListPageToken(input.page_token);\n if (cursor) {\n const cursorTime = new Date(cursor.updated_at).getTime();\n filtered = records.filter(record => {\n const t = record.updated_at.getTime();\n const idCmp = compareSessionId(record.session_id, cursor.session_id);\n if (input.order === 'asc') {\n return t > cursorTime || (t === cursorTime && idCmp > 0);\n }\n return t < cursorTime || (t === cursorTime && idCmp < 0);\n });\n }\n\n const page = paginateSessionListRows(filtered, input.limit, row => row.updated_at.toISOString());\n return { data: deepCopy(page.data), pagination: page.pagination };\n }\n\n async createTurn(input: CreateTurnInput<TTurnCustom>): Promise<void> {\n // Atomicity is free here: this body is fully synchronous, so Node's\n // run-to-completion guarantees it. Real backends must still use their own\n // locking/transactions to satisfy the ISessionStore createTurn contract.\n const sKey = sessionKey(input.turn.session_id);\n const stored = this.sessions.get(sKey);\n if (!stored) {\n throw new SessionNotFoundError(input.turn.session_id);\n }\n\n const previousTurnId = input.turn.previous_turn_id;\n let previousSnapshot: TurnSnapshot | undefined;\n if (previousTurnId !== null) {\n const prevKey = turnKey({ session_id: input.turn.session_id, turn_id: previousTurnId });\n const prev = this.turns.get(prevKey);\n // Unknown previous_turn_id is allowed (relaxed): treat as no inheritance.\n // A still-running previous must be frozen first.\n if (prev !== undefined) {\n if (prev.state.status === 'running') {\n throw new PreviousTurnRunningError(previousTurnId);\n }\n previousSnapshot = prev.snapshot;\n }\n }\n\n const tKey = turnKey(input.turn);\n if (this.turns.has(tKey)) {\n throw new TurnAlreadyExistsError(input.turn.turn_id);\n }\n\n const snapshot = buildSnapshotFromDelta({\n previousSnapshot,\n new_threads: input.new_threads,\n new_context_appends: input.new_context_appends,\n capability_states: input.capability_states,\n });\n\n const turnRecord: TurnRecord<TTurnCustom> = {\n ...deepCopy(input.turn),\n snapshot,\n };\n\n this.turns.set(tKey, turnRecord);\n this.events.set(tKey, []);\n stored.turnIds.push(input.turn.turn_id);\n stored.record.last_turn_id = input.turn.turn_id;\n stored.record.last_activity_timestamp_ms = Date.now();\n stored.record.updated_at = new Date();\n if (input.update_session_title_if_not_exist !== null && stored.record.title === null) {\n stored.record.title = input.update_session_title_if_not_exist;\n }\n }\n\n async freezeAndGetTurn(input: FreezeAndGetTurnInput): Promise<TurnRecord<TTurnCustom>> {\n const tKey = turnKey(input);\n const turn = this.requireTurn(input.session_id, input.turn_id);\n\n if (turn.state.status === 'running') {\n const cancelledState: TerminalTurnState = {\n status: 'cancelled',\n reason: CancellationReason.CancelledForNextTurn,\n completed_at: new Date().toISOString(),\n };\n turn.state = cancelledState;\n turn.updated_at = new Date();\n const list = this.events.get(tKey);\n if (list) {\n list.push(deepCopy(input.turn_done_event));\n }\n }\n\n return deepCopy(turn);\n }\n\n async getTurn(input: GetTurnInput): Promise<TurnRecord<TTurnCustom> | undefined> {\n const turn = this.turns.get(turnKey(input));\n return turn ? deepCopy(turn) : undefined;\n }\n\n async listTurns(\n input: ListTurnsInput,\n ): Promise<{ data: TurnRecordWithoutSnapshot<TTurnCustom>[]; pagination: TokenPagination }> {\n const stored = this.sessions.get(sessionKey(input.session_id));\n if (!stored) {\n throw new SessionNotFoundError(input.session_id);\n }\n const records = stored.turnIds.map(id => {\n const turn = this.turns.get(turnKey({ session_id: input.session_id, turn_id: id }));\n if (!turn) {\n throw new TurnNotFoundError(id);\n }\n const { snapshot, ...row } = deepCopy(turn);\n void snapshot;\n return row;\n });\n return paginate(records, input.limit, input.page_token);\n }\n\n async updateTurnState(input: UpdateTurnStateInput): Promise<void> {\n // Same as createTurn: synchronous body ⇒ atomic under run-to-completion.\n const tKey = turnKey(input);\n const turn = this.requireTurn(input.session_id, input.turn_id);\n if (turn.state.status !== 'running') {\n throw new TurnNotRunningError(input.turn_id, turn.state);\n }\n turn.state = deepCopy(input.state);\n turn.updated_at = new Date();\n const list = this.events.get(tKey);\n if (list) {\n list.push(deepCopy(input.turn_done_event));\n }\n }\n\n async appendToEvents(input: AppendToEventsInput): Promise<void> {\n this.requireRunningTurn(input.session_id, input.turn_id);\n const tKey = turnKey(input);\n const list = this.events.get(tKey);\n if (!list) {\n throw new TurnNotFoundError(input.turn_id);\n }\n list.push(...deepCopy(input.events));\n return;\n }\n\n private requireTurn(sessionId: string, turnId: string): TurnRecord<TTurnCustom> {\n const turn = this.turns.get(turnKey({ session_id: sessionId, turn_id: turnId }));\n if (!turn) {\n throw new TurnNotFoundError(turnId);\n }\n return turn;\n }\n\n private requireRunningTurn(sessionId: string, turnId: string): TurnRecord<TTurnCustom> {\n const turn = this.requireTurn(sessionId, turnId);\n if (turn.state.status !== 'running') {\n throw new TurnNotRunningError(turnId, turn.state);\n }\n return turn;\n }\n\n async addThreads(input: AddThreadsInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n for (const thread of input.threads) {\n turn.snapshot.threads[thread.thread_id] = deepCopy(thread);\n }\n turn.updated_at = new Date();\n return;\n }\n\n async removeThreads(input: RemoveThreadsInput): Promise<void> {\n if (input.thread_ids.length === 0) {\n return;\n }\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n for (const id of input.thread_ids) {\n Reflect.deleteProperty(turn.snapshot.threads, id);\n }\n turn.updated_at = new Date();\n return;\n }\n\n async appendToThreadContext(input: AppendToThreadContextInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n const thread = turn.snapshot.threads[input.thread_id];\n if (!thread) {\n throw new SessionStoreInvariantError(`Thread not found: ${input.thread_id}`);\n }\n thread.context.push(...deepCopy(input.context));\n if (input.current_context_usage !== null) {\n thread.current_context_usage = deepCopy(input.current_context_usage);\n }\n if (input.completion !== null) {\n thread.completion = deepCopy(input.completion);\n }\n turn.updated_at = new Date();\n return;\n }\n\n async overwriteThreadContext(input: OverwriteThreadContextInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n const threadId = input.event.thread_id;\n const thread = turn.snapshot.threads[threadId];\n if (!thread) {\n throw new SessionStoreInvariantError(`Thread not found: ${threadId}`);\n }\n thread.context = deepCopy(input.event.context);\n thread.current_context_usage = deepCopy(input.event.current_context_usage);\n turn.updated_at = new Date();\n return;\n }\n\n async patchMCPServers(input: PatchMCPServersInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n turn.snapshot.mcp_servers ??= {};\n for (const server of input.mcp_servers) {\n turn.snapshot.mcp_servers[server.id] = deepCopy(server);\n }\n turn.updated_at = new Date();\n return;\n }\n\n async patchSandboxInfo(input: PatchSandboxInfoInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n turn.snapshot.sandbox_info = deepCopy(input.sandbox_info);\n turn.updated_at = new Date();\n return;\n }\n\n async patchThreadCapabilityState(input: PatchThreadCapabilityStateInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n const thread = turn.snapshot.threads[input.thread_id];\n if (!thread) {\n throw new SessionStoreInvariantError(`Thread not found: ${input.thread_id}`);\n }\n thread.capability_state ??= {};\n if (input.state === null) {\n Reflect.deleteProperty(thread.capability_state, input.key);\n if (Object.keys(thread.capability_state).length === 0) {\n thread.capability_state = null;\n }\n } else {\n thread.capability_state[input.key] = deepCopy(input.state);\n }\n turn.updated_at = new Date();\n return;\n }\n\n async listTurnEvents(input: ListTurnEventsInput): Promise<{\n data: PersistedTurnEvent[];\n pagination: TokenPagination;\n }> {\n this.requireTurn(input.session_id, input.turn_id);\n const list = this.events.get(turnKey(input));\n if (!list) {\n throw new TurnNotFoundError(input.turn_id);\n }\n const ordered = [...list].sort((a, b) =>\n input.order === 'desc' ? b.id.localeCompare(a.id) : a.id.localeCompare(b.id),\n );\n const page = paginate(ordered, input.limit, input.page_token);\n return { data: deepCopy(page.data), pagination: page.pagination };\n }\n\n async listSessionEvents(input: ListSessionEventsInput): Promise<{\n data: SessionEventItem[];\n pagination: TokenPagination;\n }> {\n const stored = this.sessions.get(sessionKey(input.session_id));\n if (!stored) {\n throw new SessionNotFoundError(input.session_id);\n }\n\n const decodedCursor = input.page_token === undefined ? undefined : decodeSessionEventPageToken(input.page_token);\n const lastTurnId = decodedCursor?.last_turn_id ?? input.last_turn_id ?? stored.record.last_turn_id;\n if (lastTurnId === null) {\n return { data: [], pagination: { limit: input.limit } };\n }\n const cursor: SessionEventPageCursor = {\n last_turn_id: lastTurnId,\n offset: decodedCursor?.offset ?? 0,\n };\n\n const anchor = this.turns.get(turnKey({ session_id: input.session_id, turn_id: cursor.last_turn_id }));\n if (!anchor) {\n throw new TurnNotFoundError(cursor.last_turn_id);\n }\n const turnIds = this.resolveAncestorChain(input.session_id, anchor);\n const flattened: SessionEventItem[] = [];\n for (const turnId of [...turnIds].reverse()) {\n const evts = this.events.get(turnKey({ session_id: input.session_id, turn_id: turnId })) ?? [];\n for (const event of [...evts].sort((a, b) => b.id.localeCompare(a.id))) {\n flattened.push({ turn_id: turnId, event });\n }\n }\n const page = paginateSessionEventRows(\n flattened.slice(cursor.offset, cursor.offset + input.limit + 1),\n input.limit,\n cursor,\n );\n return { data: deepCopy(page.data), pagination: page.pagination };\n }\n\n /**\n * Full chain (oldest first, anchor last). `ancestor_ids` may be only the\n * previous N ancestors, so spill through the oldest ancestor's own window\n * until a root or gap. A missing turn or repeated id ends the walk.\n */\n private resolveAncestorChain(sessionId: string, anchor: TurnRecord<TTurnCustom>): string[] {\n const chain = [...anchor.ancestor_ids, anchor.turn_id];\n const seen = new Set(chain);\n let oldestId = chain[0];\n while (oldestId && oldestId !== anchor.turn_id) {\n const oldest = this.turns.get(turnKey({ session_id: sessionId, turn_id: oldestId }));\n if (!oldest) break;\n const older = oldest.ancestor_ids.filter(id => !seen.has(id));\n if (older.length === 0) break;\n chain.unshift(...older);\n for (const id of older) seen.add(id);\n oldestId = older[0];\n }\n return chain;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/agent-session/store/InMemorySessionStore.ts"],"sourcesContent":["import type { AgentThreadSnapshot } from '../../core/runtime/AgentThread.types';\nimport { getEmptyCurrentContextUsage } from '../../core/runtime/contextUsage';\nimport type { SessionRecord } from '../models/SessionRecord';\nimport type { TurnRecord, TurnSnapshot } from '../models/TurnRecord';\nimport type { PersistedTurnEvent, SessionEventItem } from '../schemas/events';\nimport type { TokenPagination } from '../schemas/pagination';\nimport { CancellationReason, type TerminalTurnState } from '../schemas/turn';\nimport { assertCreateTurnThreadDelta } from './assertCreateTurnThreadDelta';\nimport type {\n AddThreadsInput,\n AppendToEventsInput,\n AppendToThreadContextInput,\n CreateSessionInput,\n CreateTurnInput,\n DeleteSessionInput,\n FreezeAndGetTurnInput,\n GetSessionInput,\n GetTurnInput,\n ISessionStore,\n ListSessionEventsInput,\n ListSessionsInput,\n ListTurnEventsInput,\n ListTurnsInput,\n NewThreadInit,\n OverwriteThreadContextInput,\n PatchMCPServersInput,\n PatchSandboxInfoInput,\n PatchThreadCapabilityStateInput,\n RemoveThreadsInput,\n TurnContextAppend,\n TurnRecordWithoutSnapshot,\n UpdateSessionInput,\n UpdateTurnStateInput,\n} from './ISessionStore';\nimport { decodeOffsetPageToken, encodeOffsetPageToken } from './OffsetPageToken';\nimport {\n decodeSessionEventPageToken,\n paginateSessionEventRows,\n type SessionEventPageCursor,\n} from './SessionEventPageToken';\nimport { decodeSessionListPageToken, paginateSessionListRows } from './SessionListPageToken';\nimport {\n PreviousTurnRunningError,\n SessionAlreadyExistsError,\n SessionNotFoundError,\n SessionStoreInvariantError,\n TurnAlreadyExistsError,\n TurnNotFoundError,\n TurnNotRunningError,\n} from './SessionStoreErrors';\n\n/* eslint-disable @typescript-eslint/require-await -- in-memory store is synchronous; methods stay async so thrown SessionStore*Error reject as Promises for ISessionStore callers */\n\ntype StoredEvent = PersistedTurnEvent;\n\ninterface StoredSession<TSessionCustom extends object> {\n record: SessionRecord<TSessionCustom>;\n turnIds: string[];\n}\n\nfunction deepCopy<T>(value: T): T {\n return structuredClone(value);\n}\n\nfunction sessionKey(sessionId: string): string {\n return sessionId;\n}\n\nfunction turnKey({ session_id, turn_id }: { session_id: string; turn_id: string }): string {\n return `${session_id}:${turn_id}`;\n}\n\n/** Lexicographic session_id order — shared by listSessions sort and keyset filter. */\nfunction compareSessionId(a: string, b: string): number {\n if (a < b) {\n return -1;\n }\n if (a > b) {\n return 1;\n }\n return 0;\n}\n\nfunction newThreadSnapshot(thread: NewThreadInit): AgentThreadSnapshot {\n return {\n thread_id: thread.thread_id,\n parent: thread.parent ?? null,\n agent_info: thread.agent_info ?? null,\n capability_state: null,\n context: [],\n current_context_usage: getEmptyCurrentContextUsage(),\n completion: null,\n };\n}\n\nfunction applyContextAppends(threads: Record<string, AgentThreadSnapshot>, appends: TurnContextAppend[]): void {\n for (const append of appends) {\n const thread = threads[append.thread_id];\n if (!thread) {\n throw new SessionStoreInvariantError(`new_context_appends references unknown thread ${append.thread_id}`);\n }\n thread.context.push(...deepCopy(append.context));\n if (append.current_context_usage !== null) {\n thread.current_context_usage = deepCopy(append.current_context_usage);\n }\n }\n}\n\nfunction buildSnapshotFromDelta(input: {\n previousSnapshot: TurnSnapshot | undefined;\n new_threads: NewThreadInit[];\n new_context_appends: TurnContextAppend[];\n capability_states: CreateTurnInput['capability_states'];\n}): TurnSnapshot {\n const threads: Record<string, AgentThreadSnapshot> = input.previousSnapshot\n ? deepCopy(input.previousSnapshot.threads)\n : {};\n\n assertCreateTurnThreadDelta({\n previousThreadIds: new Set(Object.keys(threads)),\n new_threads: input.new_threads,\n new_context_appends: input.new_context_appends,\n capability_states: input.capability_states,\n });\n\n for (const nt of input.new_threads) {\n threads[nt.thread_id] = newThreadSnapshot(nt);\n }\n\n applyContextAppends(threads, input.new_context_appends);\n for (const capability of input.capability_states) {\n const thread = threads[capability.thread_id];\n if (thread === undefined) {\n throw new SessionStoreInvariantError(`capability_states references unknown thread ${capability.thread_id}`);\n }\n thread.capability_state = deepCopy(capability.capability_state);\n }\n\n return {\n threads,\n mcp_servers: input.previousSnapshot ? deepCopy(input.previousSnapshot.mcp_servers) : null,\n sandbox_info: input.previousSnapshot ? deepCopy(input.previousSnapshot.sandbox_info) : null,\n };\n}\n\nfunction paginate<T>(items: T[], limit: number, pageToken?: string): { data: T[]; pagination: TokenPagination } {\n const offset = decodeOffsetPageToken(pageToken);\n const slice = items.slice(offset, offset + limit);\n return {\n data: slice,\n pagination: {\n limit,\n ...(offset + limit < items.length ? { next_page_token: encodeOffsetPageToken(offset + limit) } : {}),\n ...(offset > 0 ? { previous_page_token: encodeOffsetPageToken(Math.max(0, offset - limit)) } : {}),\n },\n };\n}\n\n/**\n * Reference ISessionStore implementation. Proves the contract without SSE/subscription\n * hooks. Deep-copies on read/write boundaries so callers cannot mutate stored state.\n */\nexport class InMemorySessionStore<\n TSessionCustom extends object = Record<string, never>,\n TTurnCustom extends object = Record<string, never>,\n> implements ISessionStore<TSessionCustom, TTurnCustom> {\n private readonly sessions = new Map<string, StoredSession<TSessionCustom>>();\n private readonly turns = new Map<string, TurnRecord<TTurnCustom>>();\n private readonly events = new Map<string, StoredEvent[]>();\n\n async createSession(input: CreateSessionInput<TSessionCustom>): Promise<void> {\n const key = sessionKey(input.session_id);\n if (this.sessions.has(key)) {\n throw new SessionAlreadyExistsError(input.session_id);\n }\n const now = new Date();\n const record: SessionRecord<TSessionCustom> = {\n tenant_id: input.tenant_id,\n session_id: input.session_id,\n created_by: input.created_by,\n agent: deepCopy(input.agent),\n title: null,\n last_turn_id: null,\n created_at: now,\n updated_at: now,\n last_activity_timestamp_ms: Date.now(),\n custom: input.custom !== null ? deepCopy(input.custom) : null,\n };\n this.sessions.set(key, { record, turnIds: [] });\n return;\n }\n\n async deleteSession(input: DeleteSessionInput): Promise<void> {\n const sKey = sessionKey(input.session_id);\n const stored = this.sessions.get(sKey);\n if (stored?.record.tenant_id !== input.tenant_id) {\n return;\n }\n for (const turnId of stored.turnIds) {\n const tKey = turnKey({ session_id: input.session_id, turn_id: turnId });\n this.turns.delete(tKey);\n this.events.delete(tKey);\n }\n this.sessions.delete(sKey);\n }\n\n async getSession(input: GetSessionInput): Promise<SessionRecord<TSessionCustom> | undefined> {\n const stored = this.sessions.get(sessionKey(input.session_id));\n return stored?.record.tenant_id === input.tenant_id ? deepCopy(stored.record) : undefined;\n }\n\n async updateSession(input: UpdateSessionInput<TSessionCustom>): Promise<void> {\n const key = sessionKey(input.session_id);\n const stored = this.sessions.get(key);\n if (stored?.record.tenant_id !== input.tenant_id) {\n throw new SessionNotFoundError(input.session_id);\n }\n if (input.agent !== undefined) {\n if (stored.record.agent.type === 'reference') {\n throw new SessionStoreInvariantError(`Session ${input.session_id} is named; agent cannot be updated`);\n }\n stored.record.agent = deepCopy(input.agent);\n }\n if (input.title !== undefined) {\n stored.record.title = input.title;\n }\n const now = Date.now();\n stored.record.updated_at = new Date(now);\n stored.record.last_activity_timestamp_ms = now;\n return;\n }\n\n async listSessions(\n input: ListSessionsInput,\n ): Promise<{ data: SessionRecord<TSessionCustom>[]; pagination: TokenPagination }> {\n const records: SessionRecord<TSessionCustom>[] = [];\n for (const stored of this.sessions.values()) {\n if (stored.record.tenant_id !== input.tenant_id) {\n continue;\n }\n if (\n input.agent_id !== undefined &&\n (stored.record.agent.type !== 'reference' || stored.record.agent.id !== input.agent_id)\n ) {\n continue;\n }\n if (input.created_by !== undefined && stored.record.created_by !== input.created_by) {\n continue;\n }\n const createdAt = stored.record.created_at.getTime();\n if (input.start_timestamp !== undefined && createdAt < input.start_timestamp.getTime()) {\n continue;\n }\n if (input.end_timestamp !== undefined && createdAt > input.end_timestamp.getTime()) {\n continue;\n }\n records.push(stored.record);\n }\n records.sort((a, b) => {\n const aTime = a.updated_at.getTime();\n const bTime = b.updated_at.getTime();\n if (aTime !== bTime) {\n return input.order === 'asc' ? aTime - bTime : bTime - aTime;\n }\n // Same lexicographic order as the keyset predicate below (and Postgres/SQLite).\n return input.order === 'asc'\n ? compareSessionId(a.session_id, b.session_id)\n : compareSessionId(b.session_id, a.session_id);\n });\n\n let filtered = records;\n const cursor = decodeSessionListPageToken(input.page_token);\n if (cursor) {\n const cursorTime = new Date(cursor.updated_at).getTime();\n filtered = records.filter(record => {\n const t = record.updated_at.getTime();\n const idCmp = compareSessionId(record.session_id, cursor.session_id);\n if (input.order === 'asc') {\n return t > cursorTime || (t === cursorTime && idCmp > 0);\n }\n return t < cursorTime || (t === cursorTime && idCmp < 0);\n });\n }\n\n const page = paginateSessionListRows(filtered, input.limit, row => row.updated_at.toISOString());\n return { data: deepCopy(page.data), pagination: page.pagination };\n }\n\n async createTurn(input: CreateTurnInput<TTurnCustom>): Promise<void> {\n // Atomicity is free here: this body is fully synchronous, so Node's\n // run-to-completion guarantees it. Real backends must still use their own\n // locking/transactions to satisfy the ISessionStore createTurn contract.\n const sKey = sessionKey(input.turn.session_id);\n const stored = this.sessions.get(sKey);\n if (!stored) {\n throw new SessionNotFoundError(input.turn.session_id);\n }\n\n const previousTurnId = input.turn.previous_turn_id;\n let previousSnapshot: TurnSnapshot | undefined;\n if (previousTurnId !== null) {\n const prevKey = turnKey({ session_id: input.turn.session_id, turn_id: previousTurnId });\n const prev = this.turns.get(prevKey);\n // Unknown previous_turn_id is allowed (relaxed): treat as no inheritance.\n // A still-running previous must be frozen first.\n if (prev !== undefined) {\n if (prev.state.status === 'running') {\n throw new PreviousTurnRunningError(previousTurnId);\n }\n previousSnapshot = prev.snapshot;\n }\n }\n\n const tKey = turnKey(input.turn);\n if (this.turns.has(tKey)) {\n throw new TurnAlreadyExistsError(input.turn.turn_id);\n }\n\n const snapshot = buildSnapshotFromDelta({\n previousSnapshot,\n new_threads: input.new_threads,\n new_context_appends: input.new_context_appends,\n capability_states: input.capability_states,\n });\n\n const turnRecord: TurnRecord<TTurnCustom> = {\n ...deepCopy(input.turn),\n snapshot,\n };\n\n this.turns.set(tKey, turnRecord);\n this.events.set(tKey, []);\n stored.turnIds.push(input.turn.turn_id);\n stored.record.last_turn_id = input.turn.turn_id;\n stored.record.last_activity_timestamp_ms = Date.now();\n stored.record.updated_at = new Date();\n if (input.update_session_title_if_not_exist !== null && stored.record.title === null) {\n stored.record.title = input.update_session_title_if_not_exist;\n }\n }\n\n async freezeAndGetTurn(input: FreezeAndGetTurnInput): Promise<TurnRecord<TTurnCustom>> {\n const tKey = turnKey(input);\n const turn = this.requireTurn(input.session_id, input.turn_id);\n\n if (turn.state.status === 'running') {\n const cancelledState: TerminalTurnState = {\n status: 'cancelled',\n reason: CancellationReason.CancelledForNextTurn,\n completed_at: new Date().toISOString(),\n };\n turn.state = cancelledState;\n turn.updated_at = new Date();\n const list = this.events.get(tKey);\n if (list) {\n list.push(deepCopy(input.turn_done_event));\n }\n }\n\n return deepCopy(turn);\n }\n\n async getTurn(input: GetTurnInput): Promise<TurnRecord<TTurnCustom> | undefined> {\n const turn = this.turns.get(turnKey(input));\n return turn ? deepCopy(turn) : undefined;\n }\n\n async listTurns(\n input: ListTurnsInput,\n ): Promise<{ data: TurnRecordWithoutSnapshot<TTurnCustom>[]; pagination: TokenPagination }> {\n const stored = this.sessions.get(sessionKey(input.session_id));\n if (!stored) {\n throw new SessionNotFoundError(input.session_id);\n }\n const records = stored.turnIds.map(id => {\n const turn = this.turns.get(turnKey({ session_id: input.session_id, turn_id: id }));\n if (!turn) {\n throw new TurnNotFoundError(id);\n }\n const { snapshot, ...row } = deepCopy(turn);\n void snapshot;\n return row;\n });\n return paginate(records, input.limit, input.page_token);\n }\n\n async updateTurnState(input: UpdateTurnStateInput): Promise<void> {\n // Same as createTurn: synchronous body ⇒ atomic under run-to-completion.\n const tKey = turnKey(input);\n const turn = this.requireTurn(input.session_id, input.turn_id);\n if (turn.state.status !== 'running') {\n throw new TurnNotRunningError(input.turn_id, turn.state);\n }\n turn.state = deepCopy(input.state);\n turn.updated_at = new Date();\n const list = this.events.get(tKey);\n if (list) {\n list.push(deepCopy(input.turn_done_event));\n }\n }\n\n async appendToEvents(input: AppendToEventsInput): Promise<void> {\n this.requireRunningTurn(input.session_id, input.turn_id);\n const tKey = turnKey(input);\n const list = this.events.get(tKey);\n if (!list) {\n throw new TurnNotFoundError(input.turn_id);\n }\n list.push(...deepCopy(input.events));\n return;\n }\n\n private requireTurn(sessionId: string, turnId: string): TurnRecord<TTurnCustom> {\n const turn = this.turns.get(turnKey({ session_id: sessionId, turn_id: turnId }));\n if (!turn) {\n throw new TurnNotFoundError(turnId);\n }\n return turn;\n }\n\n private requireRunningTurn(sessionId: string, turnId: string): TurnRecord<TTurnCustom> {\n const turn = this.requireTurn(sessionId, turnId);\n if (turn.state.status !== 'running') {\n throw new TurnNotRunningError(turnId, turn.state);\n }\n return turn;\n }\n\n async addThreads(input: AddThreadsInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n for (const thread of input.threads) {\n turn.snapshot.threads[thread.thread_id] = deepCopy(thread);\n }\n turn.updated_at = new Date();\n return;\n }\n\n async removeThreads(input: RemoveThreadsInput): Promise<void> {\n if (input.thread_ids.length === 0) {\n return;\n }\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n for (const id of input.thread_ids) {\n Reflect.deleteProperty(turn.snapshot.threads, id);\n }\n turn.updated_at = new Date();\n return;\n }\n\n async appendToThreadContext(input: AppendToThreadContextInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n const thread = turn.snapshot.threads[input.thread_id];\n if (!thread) {\n throw new SessionStoreInvariantError(`Thread not found: ${input.thread_id}`);\n }\n thread.context.push(...deepCopy(input.context));\n if (input.current_context_usage !== null) {\n thread.current_context_usage = deepCopy(input.current_context_usage);\n }\n if (input.completion !== null) {\n thread.completion = deepCopy(input.completion);\n }\n turn.updated_at = new Date();\n return;\n }\n\n async overwriteThreadContext(input: OverwriteThreadContextInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n const threadId = input.event.thread_id;\n const thread = turn.snapshot.threads[threadId];\n if (!thread) {\n throw new SessionStoreInvariantError(`Thread not found: ${threadId}`);\n }\n thread.context = deepCopy(input.event.context);\n thread.current_context_usage = deepCopy(input.event.current_context_usage);\n turn.updated_at = new Date();\n return;\n }\n\n async patchMCPServers(input: PatchMCPServersInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n turn.snapshot.mcp_servers ??= {};\n for (const server of input.mcp_servers) {\n turn.snapshot.mcp_servers[server.id] = deepCopy(server);\n }\n turn.updated_at = new Date();\n return;\n }\n\n async patchSandboxInfo(input: PatchSandboxInfoInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n turn.snapshot.sandbox_info = deepCopy(input.sandbox_info);\n turn.updated_at = new Date();\n return;\n }\n\n async patchThreadCapabilityState(input: PatchThreadCapabilityStateInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n const thread = turn.snapshot.threads[input.thread_id];\n if (!thread) {\n throw new SessionStoreInvariantError(`Thread not found: ${input.thread_id}`);\n }\n thread.capability_state ??= {};\n if (input.state === null) {\n Reflect.deleteProperty(thread.capability_state, input.key);\n if (Object.keys(thread.capability_state).length === 0) {\n thread.capability_state = null;\n }\n } else {\n thread.capability_state[input.key] = deepCopy(input.state);\n }\n turn.updated_at = new Date();\n return;\n }\n\n async listTurnEvents(input: ListTurnEventsInput): Promise<{\n data: PersistedTurnEvent[];\n pagination: TokenPagination;\n }> {\n this.requireTurn(input.session_id, input.turn_id);\n const list = this.events.get(turnKey(input));\n if (!list) {\n throw new TurnNotFoundError(input.turn_id);\n }\n const ordered = [...list].sort((a, b) =>\n input.order === 'desc' ? b.id.localeCompare(a.id) : a.id.localeCompare(b.id),\n );\n const page = paginate(ordered, input.limit, input.page_token);\n return { data: deepCopy(page.data), pagination: page.pagination };\n }\n\n async listSessionEvents(input: ListSessionEventsInput): Promise<{\n data: SessionEventItem[];\n pagination: TokenPagination;\n }> {\n const stored = this.sessions.get(sessionKey(input.session_id));\n if (!stored) {\n throw new SessionNotFoundError(input.session_id);\n }\n\n const decodedCursor = input.page_token === undefined ? undefined : decodeSessionEventPageToken(input.page_token);\n const lastTurnId = decodedCursor?.last_turn_id ?? input.last_turn_id ?? stored.record.last_turn_id;\n if (lastTurnId === null) {\n return { data: [], pagination: { limit: input.limit } };\n }\n const cursor: SessionEventPageCursor = {\n last_turn_id: lastTurnId,\n offset: decodedCursor?.offset ?? 0,\n };\n\n const anchor = this.turns.get(turnKey({ session_id: input.session_id, turn_id: cursor.last_turn_id }));\n if (!anchor) {\n throw new TurnNotFoundError(cursor.last_turn_id);\n }\n const turnIds = this.resolveAncestorChain(input.session_id, anchor);\n const flattened: SessionEventItem[] = [];\n for (const turnId of [...turnIds].reverse()) {\n const evts = this.events.get(turnKey({ session_id: input.session_id, turn_id: turnId })) ?? [];\n for (const event of [...evts].sort((a, b) => b.id.localeCompare(a.id))) {\n flattened.push({ turn_id: turnId, event });\n }\n }\n const page = paginateSessionEventRows(\n flattened.slice(cursor.offset, cursor.offset + input.limit + 1),\n input.limit,\n cursor,\n );\n return { data: deepCopy(page.data), pagination: page.pagination };\n }\n\n /**\n * Full chain (oldest first, anchor last). `ancestor_ids` may be only the\n * previous N ancestors, so spill through the oldest ancestor's own window\n * until a root or gap. A missing turn or repeated id ends the walk.\n */\n private resolveAncestorChain(sessionId: string, anchor: TurnRecord<TTurnCustom>): string[] {\n const chain = [...anchor.ancestor_ids, anchor.turn_id];\n const seen = new Set(chain);\n let oldestId = chain[0];\n while (oldestId && oldestId !== anchor.turn_id) {\n const oldest = this.turns.get(turnKey({ session_id: sessionId, turn_id: oldestId }));\n if (!oldest) {\n break;\n }\n const older = oldest.ancestor_ids.filter(id => !seen.has(id));\n if (older.length === 0) {\n break;\n }\n chain.unshift(...older);\n for (const id of older) {\n seen.add(id);\n }\n oldestId = older[0];\n }\n return chain;\n }\n}\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"OffsetPageToken.d.ts","sourceRoot":"","sources":["../../../src/agent-session/store/OffsetPageToken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,eAAO,MAAM,sBAAsB;;kBAIxB,CAAC;AAEZ,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGvE;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,IAAI,EAAE,CAAC,EAAE,EACT,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb;IAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAAC,UAAU,EAAE,eAAe,CAAA;CAAE,CAW5C"}
1
+ {"version":3,"file":"OffsetPageToken.d.ts","sourceRoot":"","sources":["../../../src/agent-session/store/OffsetPageToken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,eAAO,MAAM,sBAAsB;;kBAIxB,CAAC;AAEZ,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAKvE;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,IAAI,EAAE,CAAC,EAAE,EACT,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb;IAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAAC,UAAU,EAAE,eAAe,CAAA;CAAE,CAW5C"}
@@ -35,7 +35,9 @@ function encodeOffsetPageToken(offset) {
35
35
  return (0, import_PageToken.encodePageToken)(OffsetPageCursorSchema, { offset });
36
36
  }
37
37
  function decodeOffsetPageToken(token) {
38
- if (token === void 0 || token === "") return 0;
38
+ if (token === void 0 || token === "") {
39
+ return 0;
40
+ }
39
41
  return (0, import_PageToken.decodePageToken)(OffsetPageCursorSchema, token).offset;
40
42
  }
41
43
  function paginateOffsetRows(rows, limit, offset) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/agent-session/store/OffsetPageToken.ts"],"sourcesContent":["import { z } from 'zod';\nimport type { TokenPagination } from '../schemas/pagination';\nimport { decodePageToken, encodePageToken } from './PageToken';\n\nexport const OffsetPageCursorSchema = z\n .object({\n offset: z.number().int().nonnegative(),\n })\n .strict();\n\nexport type OffsetPageCursor = z.infer<typeof OffsetPageCursorSchema>;\n\nexport function encodeOffsetPageToken(offset: number): string {\n return encodePageToken(OffsetPageCursorSchema, { offset });\n}\n\nexport function decodeOffsetPageToken(token: string | undefined): number {\n if (token === undefined || token === '') return 0;\n return decodePageToken(OffsetPageCursorSchema, token).offset;\n}\n\nexport function paginateOffsetRows<T>(\n rows: T[],\n limit: number,\n offset: number,\n): { data: T[]; pagination: TokenPagination } {\n const hasMore = rows.length > limit;\n const data = hasMore ? rows.slice(0, limit) : rows;\n return {\n data,\n pagination: {\n limit,\n ...(hasMore ? { next_page_token: encodeOffsetPageToken(offset + limit) } : {}),\n ...(offset > 0 ? { previous_page_token: encodeOffsetPageToken(Math.max(0, offset - limit)) } : {}),\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAkB;AAElB,uBAAiD;AAE1C,IAAM,yBAAyB,aACnC,OAAO;AAAA,EACN,QAAQ,aAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AACvC,CAAC,EACA,OAAO;AAIH,SAAS,sBAAsB,QAAwB;AAC5D,aAAO,kCAAgB,wBAAwB,EAAE,OAAO,CAAC;AAC3D;AAEO,SAAS,sBAAsB,OAAmC;AACvE,MAAI,UAAU,UAAa,UAAU,GAAI,QAAO;AAChD,aAAO,kCAAgB,wBAAwB,KAAK,EAAE;AACxD;AAEO,SAAS,mBACd,MACA,OACA,QAC4C;AAC5C,QAAM,UAAU,KAAK,SAAS;AAC9B,QAAM,OAAO,UAAU,KAAK,MAAM,GAAG,KAAK,IAAI;AAC9C,SAAO;AAAA,IACL;AAAA,IACA,YAAY;AAAA,MACV;AAAA,MACA,GAAI,UAAU,EAAE,iBAAiB,sBAAsB,SAAS,KAAK,EAAE,IAAI,CAAC;AAAA,MAC5E,GAAI,SAAS,IAAI,EAAE,qBAAqB,sBAAsB,KAAK,IAAI,GAAG,SAAS,KAAK,CAAC,EAAE,IAAI,CAAC;AAAA,IAClG;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/agent-session/store/OffsetPageToken.ts"],"sourcesContent":["import { z } from 'zod';\nimport type { TokenPagination } from '../schemas/pagination';\nimport { decodePageToken, encodePageToken } from './PageToken';\n\nexport const OffsetPageCursorSchema = z\n .object({\n offset: z.number().int().nonnegative(),\n })\n .strict();\n\nexport type OffsetPageCursor = z.infer<typeof OffsetPageCursorSchema>;\n\nexport function encodeOffsetPageToken(offset: number): string {\n return encodePageToken(OffsetPageCursorSchema, { offset });\n}\n\nexport function decodeOffsetPageToken(token: string | undefined): number {\n if (token === undefined || token === '') {\n return 0;\n }\n return decodePageToken(OffsetPageCursorSchema, token).offset;\n}\n\nexport function paginateOffsetRows<T>(\n rows: T[],\n limit: number,\n offset: number,\n): { data: T[]; pagination: TokenPagination } {\n const hasMore = rows.length > limit;\n const data = hasMore ? rows.slice(0, limit) : rows;\n return {\n data,\n pagination: {\n limit,\n ...(hasMore ? { next_page_token: encodeOffsetPageToken(offset + limit) } : {}),\n ...(offset > 0 ? { previous_page_token: encodeOffsetPageToken(Math.max(0, offset - limit)) } : {}),\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAkB;AAElB,uBAAiD;AAE1C,IAAM,yBAAyB,aACnC,OAAO;AAAA,EACN,QAAQ,aAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AACvC,CAAC,EACA,OAAO;AAIH,SAAS,sBAAsB,QAAwB;AAC5D,aAAO,kCAAgB,wBAAwB,EAAE,OAAO,CAAC;AAC3D;AAEO,SAAS,sBAAsB,OAAmC;AACvE,MAAI,UAAU,UAAa,UAAU,IAAI;AACvC,WAAO;AAAA,EACT;AACA,aAAO,kCAAgB,wBAAwB,KAAK,EAAE;AACxD;AAEO,SAAS,mBACd,MACA,OACA,QAC4C;AAC5C,QAAM,UAAU,KAAK,SAAS;AAC9B,QAAM,OAAO,UAAU,KAAK,MAAM,GAAG,KAAK,IAAI;AAC9C,SAAO;AAAA,IACL;AAAA,IACA,YAAY;AAAA,MACV;AAAA,MACA,GAAI,UAAU,EAAE,iBAAiB,sBAAsB,SAAS,KAAK,EAAE,IAAI,CAAC;AAAA,MAC5E,GAAI,SAAS,IAAI,EAAE,qBAAqB,sBAAsB,KAAK,IAAI,GAAG,SAAS,KAAK,CAAC,EAAE,IAAI,CAAC;AAAA,IAClG;AAAA,EACF;AACF;","names":[]}
@@ -8,7 +8,9 @@ function encodeOffsetPageToken(offset) {
8
8
  return encodePageToken(OffsetPageCursorSchema, { offset });
9
9
  }
10
10
  function decodeOffsetPageToken(token) {
11
- if (token === void 0 || token === "") return 0;
11
+ if (token === void 0 || token === "") {
12
+ return 0;
13
+ }
12
14
  return decodePageToken(OffsetPageCursorSchema, token).offset;
13
15
  }
14
16
  function paginateOffsetRows(rows, limit, offset) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/agent-session/store/OffsetPageToken.ts"],"sourcesContent":["import { z } from 'zod';\nimport type { TokenPagination } from '../schemas/pagination';\nimport { decodePageToken, encodePageToken } from './PageToken';\n\nexport const OffsetPageCursorSchema = z\n .object({\n offset: z.number().int().nonnegative(),\n })\n .strict();\n\nexport type OffsetPageCursor = z.infer<typeof OffsetPageCursorSchema>;\n\nexport function encodeOffsetPageToken(offset: number): string {\n return encodePageToken(OffsetPageCursorSchema, { offset });\n}\n\nexport function decodeOffsetPageToken(token: string | undefined): number {\n if (token === undefined || token === '') return 0;\n return decodePageToken(OffsetPageCursorSchema, token).offset;\n}\n\nexport function paginateOffsetRows<T>(\n rows: T[],\n limit: number,\n offset: number,\n): { data: T[]; pagination: TokenPagination } {\n const hasMore = rows.length > limit;\n const data = hasMore ? rows.slice(0, limit) : rows;\n return {\n data,\n pagination: {\n limit,\n ...(hasMore ? { next_page_token: encodeOffsetPageToken(offset + limit) } : {}),\n ...(offset > 0 ? { previous_page_token: encodeOffsetPageToken(Math.max(0, offset - limit)) } : {}),\n },\n };\n}\n"],"mappings":";AAAA,SAAS,SAAS;AAElB,SAAS,iBAAiB,uBAAuB;AAE1C,IAAM,yBAAyB,EACnC,OAAO;AAAA,EACN,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AACvC,CAAC,EACA,OAAO;AAIH,SAAS,sBAAsB,QAAwB;AAC5D,SAAO,gBAAgB,wBAAwB,EAAE,OAAO,CAAC;AAC3D;AAEO,SAAS,sBAAsB,OAAmC;AACvE,MAAI,UAAU,UAAa,UAAU,GAAI,QAAO;AAChD,SAAO,gBAAgB,wBAAwB,KAAK,EAAE;AACxD;AAEO,SAAS,mBACd,MACA,OACA,QAC4C;AAC5C,QAAM,UAAU,KAAK,SAAS;AAC9B,QAAM,OAAO,UAAU,KAAK,MAAM,GAAG,KAAK,IAAI;AAC9C,SAAO;AAAA,IACL;AAAA,IACA,YAAY;AAAA,MACV;AAAA,MACA,GAAI,UAAU,EAAE,iBAAiB,sBAAsB,SAAS,KAAK,EAAE,IAAI,CAAC;AAAA,MAC5E,GAAI,SAAS,IAAI,EAAE,qBAAqB,sBAAsB,KAAK,IAAI,GAAG,SAAS,KAAK,CAAC,EAAE,IAAI,CAAC;AAAA,IAClG;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/agent-session/store/OffsetPageToken.ts"],"sourcesContent":["import { z } from 'zod';\nimport type { TokenPagination } from '../schemas/pagination';\nimport { decodePageToken, encodePageToken } from './PageToken';\n\nexport const OffsetPageCursorSchema = z\n .object({\n offset: z.number().int().nonnegative(),\n })\n .strict();\n\nexport type OffsetPageCursor = z.infer<typeof OffsetPageCursorSchema>;\n\nexport function encodeOffsetPageToken(offset: number): string {\n return encodePageToken(OffsetPageCursorSchema, { offset });\n}\n\nexport function decodeOffsetPageToken(token: string | undefined): number {\n if (token === undefined || token === '') {\n return 0;\n }\n return decodePageToken(OffsetPageCursorSchema, token).offset;\n}\n\nexport function paginateOffsetRows<T>(\n rows: T[],\n limit: number,\n offset: number,\n): { data: T[]; pagination: TokenPagination } {\n const hasMore = rows.length > limit;\n const data = hasMore ? rows.slice(0, limit) : rows;\n return {\n data,\n pagination: {\n limit,\n ...(hasMore ? { next_page_token: encodeOffsetPageToken(offset + limit) } : {}),\n ...(offset > 0 ? { previous_page_token: encodeOffsetPageToken(Math.max(0, offset - limit)) } : {}),\n },\n };\n}\n"],"mappings":";AAAA,SAAS,SAAS;AAElB,SAAS,iBAAiB,uBAAuB;AAE1C,IAAM,yBAAyB,EACnC,OAAO;AAAA,EACN,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AACvC,CAAC,EACA,OAAO;AAIH,SAAS,sBAAsB,QAAwB;AAC5D,SAAO,gBAAgB,wBAAwB,EAAE,OAAO,CAAC;AAC3D;AAEO,SAAS,sBAAsB,OAAmC;AACvE,MAAI,UAAU,UAAa,UAAU,IAAI;AACvC,WAAO;AAAA,EACT;AACA,SAAO,gBAAgB,wBAAwB,KAAK,EAAE;AACxD;AAEO,SAAS,mBACd,MACA,OACA,QAC4C;AAC5C,QAAM,UAAU,KAAK,SAAS;AAC9B,QAAM,OAAO,UAAU,KAAK,MAAM,GAAG,KAAK,IAAI;AAC9C,SAAO;AAAA,IACL;AAAA,IACA,YAAY;AAAA,MACV;AAAA,MACA,GAAI,UAAU,EAAE,iBAAiB,sBAAsB,SAAS,KAAK,EAAE,IAAI,CAAC;AAAA,MAC5E,GAAI,SAAS,IAAI,EAAE,qBAAqB,sBAAsB,KAAK,IAAI,GAAG,SAAS,KAAK,CAAC,EAAE,IAAI,CAAC;AAAA,IAClG;AAAA,EACF;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"SessionListPageToken.d.ts","sourceRoot":"","sources":["../../../src/agent-session/store/SessionListPageToken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B;;;kBAK7B,CAAC;AAEZ,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CAEhF;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,qBAAqB,GAAG,SAAS,CAGvG;AAED,wBAAgB,uBAAuB,CAAC,CAAC,SAAS;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,EACtE,IAAI,EAAE,CAAC,EAAE,EACT,KAAK,EAAE,MAAM,EACb,kBAAkB,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,GACrC;IAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAAC,UAAU,EAAE,eAAe,CAAA;CAAE,CAkB5C"}
1
+ {"version":3,"file":"SessionListPageToken.d.ts","sourceRoot":"","sources":["../../../src/agent-session/store/SessionListPageToken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B;;;kBAK7B,CAAC;AAEZ,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CAEhF;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,qBAAqB,GAAG,SAAS,CAKvG;AAED,wBAAgB,uBAAuB,CAAC,CAAC,SAAS;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,EACtE,IAAI,EAAE,CAAC,EAAE,EACT,KAAK,EAAE,MAAM,EACb,kBAAkB,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,GACrC;IAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAAC,UAAU,EAAE,eAAe,CAAA;CAAE,CAkB5C"}
@@ -36,7 +36,9 @@ function encodeSessionListPageToken(cursor) {
36
36
  return (0, import_PageToken.encodePageToken)(SessionListPageCursorSchema, cursor);
37
37
  }
38
38
  function decodeSessionListPageToken(token) {
39
- if (token === void 0) return void 0;
39
+ if (token === void 0) {
40
+ return void 0;
41
+ }
40
42
  return (0, import_PageToken.decodePageToken)(SessionListPageCursorSchema, token);
41
43
  }
42
44
  function paginateSessionListRows(rows, limit, getUpdatedAtCursor) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/agent-session/store/SessionListPageToken.ts"],"sourcesContent":["import { z } from 'zod';\nimport type { TokenPagination } from '../schemas/pagination';\nimport { decodePageToken, encodePageToken } from './PageToken';\n\n/**\n * Keyset cursor for `listSessions` (`updated_at`, `session_id`).\n * Opaque on the wire; replaces offset tokens for this list only.\n *\n * `updated_at` must retain the store's full precision (Postgres: microseconds via\n * `to_char`; JS Date / SQLite ISO text: milliseconds). Do not round through\n * `Date` before encode/compare — equality on the cursor must match the DB value.\n */\nexport const SessionListPageCursorSchema = z\n .object({\n updated_at: z.iso.datetime({ offset: true }),\n session_id: z.string().min(1),\n })\n .strict();\n\nexport type SessionListPageCursor = z.infer<typeof SessionListPageCursorSchema>;\n\nexport function encodeSessionListPageToken(cursor: SessionListPageCursor): string {\n return encodePageToken(SessionListPageCursorSchema, cursor);\n}\n\nexport function decodeSessionListPageToken(token: string | undefined): SessionListPageCursor | undefined {\n if (token === undefined) return undefined;\n return decodePageToken(SessionListPageCursorSchema, token);\n}\n\nexport function paginateSessionListRows<T extends { session_id: string }>(\n rows: T[],\n limit: number,\n getUpdatedAtCursor: (row: T) => string,\n): { data: T[]; pagination: TokenPagination } {\n const hasMore = rows.length > limit;\n const data = hasMore ? rows.slice(0, limit) : rows;\n const last = data.at(-1);\n return {\n data,\n pagination: {\n limit,\n ...(hasMore && last !== undefined\n ? {\n next_page_token: encodeSessionListPageToken({\n updated_at: getUpdatedAtCursor(last),\n session_id: last.session_id,\n }),\n }\n : {}),\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAkB;AAElB,uBAAiD;AAU1C,IAAM,8BAA8B,aACxC,OAAO;AAAA,EACN,YAAY,aAAE,IAAI,SAAS,EAAE,QAAQ,KAAK,CAAC;AAAA,EAC3C,YAAY,aAAE,OAAO,EAAE,IAAI,CAAC;AAC9B,CAAC,EACA,OAAO;AAIH,SAAS,2BAA2B,QAAuC;AAChF,aAAO,kCAAgB,6BAA6B,MAAM;AAC5D;AAEO,SAAS,2BAA2B,OAA8D;AACvG,MAAI,UAAU,OAAW,QAAO;AAChC,aAAO,kCAAgB,6BAA6B,KAAK;AAC3D;AAEO,SAAS,wBACd,MACA,OACA,oBAC4C;AAC5C,QAAM,UAAU,KAAK,SAAS;AAC9B,QAAM,OAAO,UAAU,KAAK,MAAM,GAAG,KAAK,IAAI;AAC9C,QAAM,OAAO,KAAK,GAAG,EAAE;AACvB,SAAO;AAAA,IACL;AAAA,IACA,YAAY;AAAA,MACV;AAAA,MACA,GAAI,WAAW,SAAS,SACpB;AAAA,QACE,iBAAiB,2BAA2B;AAAA,UAC1C,YAAY,mBAAmB,IAAI;AAAA,UACnC,YAAY,KAAK;AAAA,QACnB,CAAC;AAAA,MACH,IACA,CAAC;AAAA,IACP;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/agent-session/store/SessionListPageToken.ts"],"sourcesContent":["import { z } from 'zod';\nimport type { TokenPagination } from '../schemas/pagination';\nimport { decodePageToken, encodePageToken } from './PageToken';\n\n/**\n * Keyset cursor for `listSessions` (`updated_at`, `session_id`).\n * Opaque on the wire; replaces offset tokens for this list only.\n *\n * `updated_at` must retain the store's full precision (Postgres: microseconds via\n * `to_char`; JS Date / SQLite ISO text: milliseconds). Do not round through\n * `Date` before encode/compare — equality on the cursor must match the DB value.\n */\nexport const SessionListPageCursorSchema = z\n .object({\n updated_at: z.iso.datetime({ offset: true }),\n session_id: z.string().min(1),\n })\n .strict();\n\nexport type SessionListPageCursor = z.infer<typeof SessionListPageCursorSchema>;\n\nexport function encodeSessionListPageToken(cursor: SessionListPageCursor): string {\n return encodePageToken(SessionListPageCursorSchema, cursor);\n}\n\nexport function decodeSessionListPageToken(token: string | undefined): SessionListPageCursor | undefined {\n if (token === undefined) {\n return undefined;\n }\n return decodePageToken(SessionListPageCursorSchema, token);\n}\n\nexport function paginateSessionListRows<T extends { session_id: string }>(\n rows: T[],\n limit: number,\n getUpdatedAtCursor: (row: T) => string,\n): { data: T[]; pagination: TokenPagination } {\n const hasMore = rows.length > limit;\n const data = hasMore ? rows.slice(0, limit) : rows;\n const last = data.at(-1);\n return {\n data,\n pagination: {\n limit,\n ...(hasMore && last !== undefined\n ? {\n next_page_token: encodeSessionListPageToken({\n updated_at: getUpdatedAtCursor(last),\n session_id: last.session_id,\n }),\n }\n : {}),\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAkB;AAElB,uBAAiD;AAU1C,IAAM,8BAA8B,aACxC,OAAO;AAAA,EACN,YAAY,aAAE,IAAI,SAAS,EAAE,QAAQ,KAAK,CAAC;AAAA,EAC3C,YAAY,aAAE,OAAO,EAAE,IAAI,CAAC;AAC9B,CAAC,EACA,OAAO;AAIH,SAAS,2BAA2B,QAAuC;AAChF,aAAO,kCAAgB,6BAA6B,MAAM;AAC5D;AAEO,SAAS,2BAA2B,OAA8D;AACvG,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AACA,aAAO,kCAAgB,6BAA6B,KAAK;AAC3D;AAEO,SAAS,wBACd,MACA,OACA,oBAC4C;AAC5C,QAAM,UAAU,KAAK,SAAS;AAC9B,QAAM,OAAO,UAAU,KAAK,MAAM,GAAG,KAAK,IAAI;AAC9C,QAAM,OAAO,KAAK,GAAG,EAAE;AACvB,SAAO;AAAA,IACL;AAAA,IACA,YAAY;AAAA,MACV;AAAA,MACA,GAAI,WAAW,SAAS,SACpB;AAAA,QACE,iBAAiB,2BAA2B;AAAA,UAC1C,YAAY,mBAAmB,IAAI;AAAA,UACnC,YAAY,KAAK;AAAA,QACnB,CAAC;AAAA,MACH,IACA,CAAC;AAAA,IACP;AAAA,EACF;AACF;","names":[]}
@@ -9,7 +9,9 @@ function encodeSessionListPageToken(cursor) {
9
9
  return encodePageToken(SessionListPageCursorSchema, cursor);
10
10
  }
11
11
  function decodeSessionListPageToken(token) {
12
- if (token === void 0) return void 0;
12
+ if (token === void 0) {
13
+ return void 0;
14
+ }
13
15
  return decodePageToken(SessionListPageCursorSchema, token);
14
16
  }
15
17
  function paginateSessionListRows(rows, limit, getUpdatedAtCursor) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/agent-session/store/SessionListPageToken.ts"],"sourcesContent":["import { z } from 'zod';\nimport type { TokenPagination } from '../schemas/pagination';\nimport { decodePageToken, encodePageToken } from './PageToken';\n\n/**\n * Keyset cursor for `listSessions` (`updated_at`, `session_id`).\n * Opaque on the wire; replaces offset tokens for this list only.\n *\n * `updated_at` must retain the store's full precision (Postgres: microseconds via\n * `to_char`; JS Date / SQLite ISO text: milliseconds). Do not round through\n * `Date` before encode/compare — equality on the cursor must match the DB value.\n */\nexport const SessionListPageCursorSchema = z\n .object({\n updated_at: z.iso.datetime({ offset: true }),\n session_id: z.string().min(1),\n })\n .strict();\n\nexport type SessionListPageCursor = z.infer<typeof SessionListPageCursorSchema>;\n\nexport function encodeSessionListPageToken(cursor: SessionListPageCursor): string {\n return encodePageToken(SessionListPageCursorSchema, cursor);\n}\n\nexport function decodeSessionListPageToken(token: string | undefined): SessionListPageCursor | undefined {\n if (token === undefined) return undefined;\n return decodePageToken(SessionListPageCursorSchema, token);\n}\n\nexport function paginateSessionListRows<T extends { session_id: string }>(\n rows: T[],\n limit: number,\n getUpdatedAtCursor: (row: T) => string,\n): { data: T[]; pagination: TokenPagination } {\n const hasMore = rows.length > limit;\n const data = hasMore ? rows.slice(0, limit) : rows;\n const last = data.at(-1);\n return {\n data,\n pagination: {\n limit,\n ...(hasMore && last !== undefined\n ? {\n next_page_token: encodeSessionListPageToken({\n updated_at: getUpdatedAtCursor(last),\n session_id: last.session_id,\n }),\n }\n : {}),\n },\n };\n}\n"],"mappings":";AAAA,SAAS,SAAS;AAElB,SAAS,iBAAiB,uBAAuB;AAU1C,IAAM,8BAA8B,EACxC,OAAO;AAAA,EACN,YAAY,EAAE,IAAI,SAAS,EAAE,QAAQ,KAAK,CAAC;AAAA,EAC3C,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAC9B,CAAC,EACA,OAAO;AAIH,SAAS,2BAA2B,QAAuC;AAChF,SAAO,gBAAgB,6BAA6B,MAAM;AAC5D;AAEO,SAAS,2BAA2B,OAA8D;AACvG,MAAI,UAAU,OAAW,QAAO;AAChC,SAAO,gBAAgB,6BAA6B,KAAK;AAC3D;AAEO,SAAS,wBACd,MACA,OACA,oBAC4C;AAC5C,QAAM,UAAU,KAAK,SAAS;AAC9B,QAAM,OAAO,UAAU,KAAK,MAAM,GAAG,KAAK,IAAI;AAC9C,QAAM,OAAO,KAAK,GAAG,EAAE;AACvB,SAAO;AAAA,IACL;AAAA,IACA,YAAY;AAAA,MACV;AAAA,MACA,GAAI,WAAW,SAAS,SACpB;AAAA,QACE,iBAAiB,2BAA2B;AAAA,UAC1C,YAAY,mBAAmB,IAAI;AAAA,UACnC,YAAY,KAAK;AAAA,QACnB,CAAC;AAAA,MACH,IACA,CAAC;AAAA,IACP;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/agent-session/store/SessionListPageToken.ts"],"sourcesContent":["import { z } from 'zod';\nimport type { TokenPagination } from '../schemas/pagination';\nimport { decodePageToken, encodePageToken } from './PageToken';\n\n/**\n * Keyset cursor for `listSessions` (`updated_at`, `session_id`).\n * Opaque on the wire; replaces offset tokens for this list only.\n *\n * `updated_at` must retain the store's full precision (Postgres: microseconds via\n * `to_char`; JS Date / SQLite ISO text: milliseconds). Do not round through\n * `Date` before encode/compare — equality on the cursor must match the DB value.\n */\nexport const SessionListPageCursorSchema = z\n .object({\n updated_at: z.iso.datetime({ offset: true }),\n session_id: z.string().min(1),\n })\n .strict();\n\nexport type SessionListPageCursor = z.infer<typeof SessionListPageCursorSchema>;\n\nexport function encodeSessionListPageToken(cursor: SessionListPageCursor): string {\n return encodePageToken(SessionListPageCursorSchema, cursor);\n}\n\nexport function decodeSessionListPageToken(token: string | undefined): SessionListPageCursor | undefined {\n if (token === undefined) {\n return undefined;\n }\n return decodePageToken(SessionListPageCursorSchema, token);\n}\n\nexport function paginateSessionListRows<T extends { session_id: string }>(\n rows: T[],\n limit: number,\n getUpdatedAtCursor: (row: T) => string,\n): { data: T[]; pagination: TokenPagination } {\n const hasMore = rows.length > limit;\n const data = hasMore ? rows.slice(0, limit) : rows;\n const last = data.at(-1);\n return {\n data,\n pagination: {\n limit,\n ...(hasMore && last !== undefined\n ? {\n next_page_token: encodeSessionListPageToken({\n updated_at: getUpdatedAtCursor(last),\n session_id: last.session_id,\n }),\n }\n : {}),\n },\n };\n}\n"],"mappings":";AAAA,SAAS,SAAS;AAElB,SAAS,iBAAiB,uBAAuB;AAU1C,IAAM,8BAA8B,EACxC,OAAO;AAAA,EACN,YAAY,EAAE,IAAI,SAAS,EAAE,QAAQ,KAAK,CAAC;AAAA,EAC3C,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAC9B,CAAC,EACA,OAAO;AAIH,SAAS,2BAA2B,QAAuC;AAChF,SAAO,gBAAgB,6BAA6B,MAAM;AAC5D;AAEO,SAAS,2BAA2B,OAA8D;AACvG,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AACA,SAAO,gBAAgB,6BAA6B,KAAK;AAC3D;AAEO,SAAS,wBACd,MACA,OACA,oBAC4C;AAC5C,QAAM,UAAU,KAAK,SAAS;AAC9B,QAAM,OAAO,UAAU,KAAK,MAAM,GAAG,KAAK,IAAI;AAC9C,QAAM,OAAO,KAAK,GAAG,EAAE;AACvB,SAAO;AAAA,IACL;AAAA,IACA,YAAY;AAAA,MACV;AAAA,MACA,GAAI,WAAW,SAAS,SACpB;AAAA,QACE,iBAAiB,2BAA2B;AAAA,UAC1C,YAAY,mBAAmB,IAAI;AAAA,UACnC,YAAY,KAAK;AAAA,QACnB,CAAC;AAAA,MACH,IACA,CAAC;AAAA,IACP;AAAA,EACF;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"InstructionBuilder.d.ts","sourceRoot":"","sources":["../../src/core/InstructionBuilder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,eAAO,MAAM,mBAAmB,yHACwF,CAAC;AAEzH,qBAAa,kBAAkB;IAC7B,8CAA8C;IAC9C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,QAAQ,CAAuC;IAEvD,YAAY,UAAU,EAAE,MAAM,EAAE,aAAa,UAAQ,EAGpD;IAED,6FAA6F;IAC7F,MAAM,CAAC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,CAI9D;IAED,kFAAkF;IAClF,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAIhC;IAED;;;OAGG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,UAAQ,GAAG,IAAI,CAOpE;IAED,6EAA6E;IAC7E,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAI5C;IAED,mFAAmF;IACnF,KAAK,IAAI,MAAM,CAkBd;CACF"}
1
+ {"version":3,"file":"InstructionBuilder.d.ts","sourceRoot":"","sources":["../../src/core/InstructionBuilder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,eAAO,MAAM,mBAAmB,yHACwF,CAAC;AAEzH,qBAAa,kBAAkB;IAC7B,8CAA8C;IAC9C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,QAAQ,CAAuC;IAEvD,YAAY,UAAU,EAAE,MAAM,EAAE,aAAa,UAAQ,EAGpD;IAED,6FAA6F;IAC7F,MAAM,CAAC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,CAI9D;IAED,kFAAkF;IAClF,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAMhC;IAED;;;OAGG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,UAAQ,GAAG,IAAI,CASpE;IAED,6EAA6E;IAC7E,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAI5C;IAED,mFAAmF;IACnF,KAAK,IAAI,MAAM,CAsBd;CACF"}
@@ -43,7 +43,9 @@ var InstructionBuilder = class _InstructionBuilder {
43
43
  /** Adds raw text (no wrapping tag) to this section. Empty strings are ignored. */
44
44
  addContent(content) {
45
45
  const trimmed = content.trim();
46
- if (trimmed) this.children.push(trimmed);
46
+ if (trimmed) {
47
+ this.children.push(trimmed);
48
+ }
47
49
  return this;
48
50
  }
49
51
  /**
@@ -52,7 +54,9 @@ var InstructionBuilder = class _InstructionBuilder {
52
54
  */
53
55
  addSection(tag, content, escapeContent = false) {
54
56
  const trimmed = content.trim();
55
- if (!trimmed) return this;
57
+ if (!trimmed) {
58
+ return this;
59
+ }
56
60
  const child = new _InstructionBuilder(tag, escapeContent);
57
61
  child.children.push(trimmed);
58
62
  this.children.push(child);
@@ -72,10 +76,14 @@ var InstructionBuilder = class _InstructionBuilder {
72
76
  inner.push(child);
73
77
  } else {
74
78
  const output = child.build();
75
- if (output) inner.push(output);
79
+ if (output) {
80
+ inner.push(output);
81
+ }
76
82
  }
77
83
  }
78
- if (inner.length === 0) return "";
84
+ if (inner.length === 0) {
85
+ return "";
86
+ }
79
87
  const body = inner.join("\n\n");
80
88
  if (this.escapeContent) {
81
89
  return `<${this.currentTag}><![CDATA[
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/InstructionBuilder.ts"],"sourcesContent":["/**\n * Builds a structured XML system prompt as a tree of named sections.\n *\n * Each node is an XML section (e.g. `<sandbox>`) that can contain\n * plain text and/or nested sections. Children are always rendered\n * in insertion order.\n *\n * @example\n * // Creating nested and sibling sections:\n *\n * const root = InstructionBuilder.createSystemPrompt(ROOT_AGENT_IDENTITY);\n *\n * // Add a leaf section (tag + text, no further nesting)\n * root.addSection('rules', 'Follow these rules...');\n *\n * // Add raw text without a wrapping tag\n * root.addContent('Some standalone text');\n *\n * // Begin a section you want to nest into — returns the child builder\n * const capabilities = root.beginSection('capabilities');\n * capabilities.addSection('tool-a', 'Tool A instructions');\n * capabilities.addSection('tool-b', 'Tool B instructions');\n *\n * // Nest deeper — beginSection on a child\n * const sandbox = capabilities.beginSection('sandbox');\n * sandbox.addContent('Sandbox overview');\n * sandbox.addSection('skill', 'Skill details');\n *\n * // Back to root level — just use the root reference again\n * root.addSection('user-instructions', userInput, true); // escapeContent = true\n *\n * console.log(root.build());\n *\n * // Output:\n * // <system-prompt>\n * // <agent-identity>...</agent-identity>\n * // <rules>Follow these rules...</rules>\n * // Some standalone text\n * // <capabilities>\n * // <tool-a>Tool A instructions</tool-a>\n * // <tool-b>Tool B instructions</tool-b>\n * // <sandbox>\n * // Sandbox overview\n * // <skill>Skill details</skill>\n * // </sandbox>\n * // </capabilities>\n * // <user-instructions><![CDATA[...]]></user-instructions>\n * // </system-prompt>\n */\n\nexport const ROOT_AGENT_IDENTITY =\n 'You are the Agent, an AI assistant that helps users accomplish tasks by leveraging available tools and capabilities.';\n\nexport class InstructionBuilder {\n /** The XML tag name for this section node. */\n private currentTag: string;\n private escapeContent: boolean;\n private children: (string | InstructionBuilder)[] = [];\n\n constructor(currentTag: string, escapeContent = false) {\n this.currentTag = currentTag;\n this.escapeContent = escapeContent;\n }\n\n /** Creates the root `<system-prompt>` node with the given identity in `<agent-identity>`. */\n static createSystemPrompt(identity: string): InstructionBuilder {\n const builder = new InstructionBuilder('system-prompt');\n builder.addSection('agent-identity', identity);\n return builder;\n }\n\n /** Adds raw text (no wrapping tag) to this section. Empty strings are ignored. */\n addContent(content: string): this {\n const trimmed = content.trim();\n if (trimmed) this.children.push(trimmed);\n return this;\n }\n\n /**\n * Adds a leaf section: `<tag>content</tag>`. Empty content is ignored.\n * Set escapeContent = true to wrap content in CDATA (for arbitrary/untrusted text).\n */\n addSection(tag: string, content: string, escapeContent = false): this {\n const trimmed = content.trim();\n if (!trimmed) return this;\n const child = new InstructionBuilder(tag, escapeContent);\n child.children.push(trimmed);\n this.children.push(child);\n return this;\n }\n\n /** Creates a nested section and returns it so you can add children to it. */\n beginSection(tag: string): InstructionBuilder {\n const child = new InstructionBuilder(tag);\n this.children.push(child);\n return child;\n }\n\n /** Recursively renders the tree into an XML string. Empty sections are skipped. */\n build(): string {\n const inner: string[] = [];\n for (const child of this.children) {\n if (typeof child === 'string') {\n inner.push(child);\n } else {\n const output = child.build();\n if (output) inner.push(output);\n }\n }\n\n if (inner.length === 0) return '';\n\n const body = inner.join('\\n\\n');\n if (this.escapeContent) {\n return `<${this.currentTag}><![CDATA[\\n${body}\\n]]></${this.currentTag}>`;\n }\n return `<${this.currentTag}>\\n${body}\\n</${this.currentTag}>`;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkDO,IAAM,sBACX;AAEK,IAAM,qBAAN,MAAM,oBAAmB;AAAA;AAAA,EAEtB;AAAA,EACA;AAAA,EACA,WAA4C,CAAC;AAAA,EAErD,YAAY,YAAoB,gBAAgB,OAAO;AACrD,SAAK,aAAa;AAClB,SAAK,gBAAgB;AAAA,EACvB;AAAA;AAAA,EAGA,OAAO,mBAAmB,UAAsC;AAC9D,UAAM,UAAU,IAAI,oBAAmB,eAAe;AACtD,YAAQ,WAAW,kBAAkB,QAAQ;AAC7C,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,WAAW,SAAuB;AAChC,UAAM,UAAU,QAAQ,KAAK;AAC7B,QAAI,QAAS,MAAK,SAAS,KAAK,OAAO;AACvC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAW,KAAa,SAAiB,gBAAgB,OAAa;AACpE,UAAM,UAAU,QAAQ,KAAK;AAC7B,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,QAAQ,IAAI,oBAAmB,KAAK,aAAa;AACvD,UAAM,SAAS,KAAK,OAAO;AAC3B,SAAK,SAAS,KAAK,KAAK;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,aAAa,KAAiC;AAC5C,UAAM,QAAQ,IAAI,oBAAmB,GAAG;AACxC,SAAK,SAAS,KAAK,KAAK;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,QAAgB;AACd,UAAM,QAAkB,CAAC;AACzB,eAAW,SAAS,KAAK,UAAU;AACjC,UAAI,OAAO,UAAU,UAAU;AAC7B,cAAM,KAAK,KAAK;AAAA,MAClB,OAAO;AACL,cAAM,SAAS,MAAM,MAAM;AAC3B,YAAI,OAAQ,OAAM,KAAK,MAAM;AAAA,MAC/B;AAAA,IACF;AAEA,QAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,UAAM,OAAO,MAAM,KAAK,MAAM;AAC9B,QAAI,KAAK,eAAe;AACtB,aAAO,IAAI,KAAK,UAAU;AAAA,EAAe,IAAI;AAAA,OAAU,KAAK,UAAU;AAAA,IACxE;AACA,WAAO,IAAI,KAAK,UAAU;AAAA,EAAM,IAAI;AAAA,IAAO,KAAK,UAAU;AAAA,EAC5D;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/core/InstructionBuilder.ts"],"sourcesContent":["/**\n * Builds a structured XML system prompt as a tree of named sections.\n *\n * Each node is an XML section (e.g. `<sandbox>`) that can contain\n * plain text and/or nested sections. Children are always rendered\n * in insertion order.\n *\n * @example\n * // Creating nested and sibling sections:\n *\n * const root = InstructionBuilder.createSystemPrompt(ROOT_AGENT_IDENTITY);\n *\n * // Add a leaf section (tag + text, no further nesting)\n * root.addSection('rules', 'Follow these rules...');\n *\n * // Add raw text without a wrapping tag\n * root.addContent('Some standalone text');\n *\n * // Begin a section you want to nest into — returns the child builder\n * const capabilities = root.beginSection('capabilities');\n * capabilities.addSection('tool-a', 'Tool A instructions');\n * capabilities.addSection('tool-b', 'Tool B instructions');\n *\n * // Nest deeper — beginSection on a child\n * const sandbox = capabilities.beginSection('sandbox');\n * sandbox.addContent('Sandbox overview');\n * sandbox.addSection('skill', 'Skill details');\n *\n * // Back to root level — just use the root reference again\n * root.addSection('user-instructions', userInput, true); // escapeContent = true\n *\n * console.log(root.build());\n *\n * // Output:\n * // <system-prompt>\n * // <agent-identity>...</agent-identity>\n * // <rules>Follow these rules...</rules>\n * // Some standalone text\n * // <capabilities>\n * // <tool-a>Tool A instructions</tool-a>\n * // <tool-b>Tool B instructions</tool-b>\n * // <sandbox>\n * // Sandbox overview\n * // <skill>Skill details</skill>\n * // </sandbox>\n * // </capabilities>\n * // <user-instructions><![CDATA[...]]></user-instructions>\n * // </system-prompt>\n */\n\nexport const ROOT_AGENT_IDENTITY =\n 'You are the Agent, an AI assistant that helps users accomplish tasks by leveraging available tools and capabilities.';\n\nexport class InstructionBuilder {\n /** The XML tag name for this section node. */\n private currentTag: string;\n private escapeContent: boolean;\n private children: (string | InstructionBuilder)[] = [];\n\n constructor(currentTag: string, escapeContent = false) {\n this.currentTag = currentTag;\n this.escapeContent = escapeContent;\n }\n\n /** Creates the root `<system-prompt>` node with the given identity in `<agent-identity>`. */\n static createSystemPrompt(identity: string): InstructionBuilder {\n const builder = new InstructionBuilder('system-prompt');\n builder.addSection('agent-identity', identity);\n return builder;\n }\n\n /** Adds raw text (no wrapping tag) to this section. Empty strings are ignored. */\n addContent(content: string): this {\n const trimmed = content.trim();\n if (trimmed) {\n this.children.push(trimmed);\n }\n return this;\n }\n\n /**\n * Adds a leaf section: `<tag>content</tag>`. Empty content is ignored.\n * Set escapeContent = true to wrap content in CDATA (for arbitrary/untrusted text).\n */\n addSection(tag: string, content: string, escapeContent = false): this {\n const trimmed = content.trim();\n if (!trimmed) {\n return this;\n }\n const child = new InstructionBuilder(tag, escapeContent);\n child.children.push(trimmed);\n this.children.push(child);\n return this;\n }\n\n /** Creates a nested section and returns it so you can add children to it. */\n beginSection(tag: string): InstructionBuilder {\n const child = new InstructionBuilder(tag);\n this.children.push(child);\n return child;\n }\n\n /** Recursively renders the tree into an XML string. Empty sections are skipped. */\n build(): string {\n const inner: string[] = [];\n for (const child of this.children) {\n if (typeof child === 'string') {\n inner.push(child);\n } else {\n const output = child.build();\n if (output) {\n inner.push(output);\n }\n }\n }\n\n if (inner.length === 0) {\n return '';\n }\n\n const body = inner.join('\\n\\n');\n if (this.escapeContent) {\n return `<${this.currentTag}><![CDATA[\\n${body}\\n]]></${this.currentTag}>`;\n }\n return `<${this.currentTag}>\\n${body}\\n</${this.currentTag}>`;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkDO,IAAM,sBACX;AAEK,IAAM,qBAAN,MAAM,oBAAmB;AAAA;AAAA,EAEtB;AAAA,EACA;AAAA,EACA,WAA4C,CAAC;AAAA,EAErD,YAAY,YAAoB,gBAAgB,OAAO;AACrD,SAAK,aAAa;AAClB,SAAK,gBAAgB;AAAA,EACvB;AAAA;AAAA,EAGA,OAAO,mBAAmB,UAAsC;AAC9D,UAAM,UAAU,IAAI,oBAAmB,eAAe;AACtD,YAAQ,WAAW,kBAAkB,QAAQ;AAC7C,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,WAAW,SAAuB;AAChC,UAAM,UAAU,QAAQ,KAAK;AAC7B,QAAI,SAAS;AACX,WAAK,SAAS,KAAK,OAAO;AAAA,IAC5B;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAW,KAAa,SAAiB,gBAAgB,OAAa;AACpE,UAAM,UAAU,QAAQ,KAAK;AAC7B,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AACA,UAAM,QAAQ,IAAI,oBAAmB,KAAK,aAAa;AACvD,UAAM,SAAS,KAAK,OAAO;AAC3B,SAAK,SAAS,KAAK,KAAK;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,aAAa,KAAiC;AAC5C,UAAM,QAAQ,IAAI,oBAAmB,GAAG;AACxC,SAAK,SAAS,KAAK,KAAK;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,QAAgB;AACd,UAAM,QAAkB,CAAC;AACzB,eAAW,SAAS,KAAK,UAAU;AACjC,UAAI,OAAO,UAAU,UAAU;AAC7B,cAAM,KAAK,KAAK;AAAA,MAClB,OAAO;AACL,cAAM,SAAS,MAAM,MAAM;AAC3B,YAAI,QAAQ;AACV,gBAAM,KAAK,MAAM;AAAA,QACnB;AAAA,MACF;AAAA,IACF;AAEA,QAAI,MAAM,WAAW,GAAG;AACtB,aAAO;AAAA,IACT;AAEA,UAAM,OAAO,MAAM,KAAK,MAAM;AAC9B,QAAI,KAAK,eAAe;AACtB,aAAO,IAAI,KAAK,UAAU;AAAA,EAAe,IAAI;AAAA,OAAU,KAAK,UAAU;AAAA,IACxE;AACA,WAAO,IAAI,KAAK,UAAU;AAAA,EAAM,IAAI;AAAA,IAAO,KAAK,UAAU;AAAA,EAC5D;AACF;","names":[]}
@@ -18,7 +18,9 @@ var InstructionBuilder = class _InstructionBuilder {
18
18
  /** Adds raw text (no wrapping tag) to this section. Empty strings are ignored. */
19
19
  addContent(content) {
20
20
  const trimmed = content.trim();
21
- if (trimmed) this.children.push(trimmed);
21
+ if (trimmed) {
22
+ this.children.push(trimmed);
23
+ }
22
24
  return this;
23
25
  }
24
26
  /**
@@ -27,7 +29,9 @@ var InstructionBuilder = class _InstructionBuilder {
27
29
  */
28
30
  addSection(tag, content, escapeContent = false) {
29
31
  const trimmed = content.trim();
30
- if (!trimmed) return this;
32
+ if (!trimmed) {
33
+ return this;
34
+ }
31
35
  const child = new _InstructionBuilder(tag, escapeContent);
32
36
  child.children.push(trimmed);
33
37
  this.children.push(child);
@@ -47,10 +51,14 @@ var InstructionBuilder = class _InstructionBuilder {
47
51
  inner.push(child);
48
52
  } else {
49
53
  const output = child.build();
50
- if (output) inner.push(output);
54
+ if (output) {
55
+ inner.push(output);
56
+ }
51
57
  }
52
58
  }
53
- if (inner.length === 0) return "";
59
+ if (inner.length === 0) {
60
+ return "";
61
+ }
54
62
  const body = inner.join("\n\n");
55
63
  if (this.escapeContent) {
56
64
  return `<${this.currentTag}><![CDATA[
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/InstructionBuilder.ts"],"sourcesContent":["/**\n * Builds a structured XML system prompt as a tree of named sections.\n *\n * Each node is an XML section (e.g. `<sandbox>`) that can contain\n * plain text and/or nested sections. Children are always rendered\n * in insertion order.\n *\n * @example\n * // Creating nested and sibling sections:\n *\n * const root = InstructionBuilder.createSystemPrompt(ROOT_AGENT_IDENTITY);\n *\n * // Add a leaf section (tag + text, no further nesting)\n * root.addSection('rules', 'Follow these rules...');\n *\n * // Add raw text without a wrapping tag\n * root.addContent('Some standalone text');\n *\n * // Begin a section you want to nest into — returns the child builder\n * const capabilities = root.beginSection('capabilities');\n * capabilities.addSection('tool-a', 'Tool A instructions');\n * capabilities.addSection('tool-b', 'Tool B instructions');\n *\n * // Nest deeper — beginSection on a child\n * const sandbox = capabilities.beginSection('sandbox');\n * sandbox.addContent('Sandbox overview');\n * sandbox.addSection('skill', 'Skill details');\n *\n * // Back to root level — just use the root reference again\n * root.addSection('user-instructions', userInput, true); // escapeContent = true\n *\n * console.log(root.build());\n *\n * // Output:\n * // <system-prompt>\n * // <agent-identity>...</agent-identity>\n * // <rules>Follow these rules...</rules>\n * // Some standalone text\n * // <capabilities>\n * // <tool-a>Tool A instructions</tool-a>\n * // <tool-b>Tool B instructions</tool-b>\n * // <sandbox>\n * // Sandbox overview\n * // <skill>Skill details</skill>\n * // </sandbox>\n * // </capabilities>\n * // <user-instructions><![CDATA[...]]></user-instructions>\n * // </system-prompt>\n */\n\nexport const ROOT_AGENT_IDENTITY =\n 'You are the Agent, an AI assistant that helps users accomplish tasks by leveraging available tools and capabilities.';\n\nexport class InstructionBuilder {\n /** The XML tag name for this section node. */\n private currentTag: string;\n private escapeContent: boolean;\n private children: (string | InstructionBuilder)[] = [];\n\n constructor(currentTag: string, escapeContent = false) {\n this.currentTag = currentTag;\n this.escapeContent = escapeContent;\n }\n\n /** Creates the root `<system-prompt>` node with the given identity in `<agent-identity>`. */\n static createSystemPrompt(identity: string): InstructionBuilder {\n const builder = new InstructionBuilder('system-prompt');\n builder.addSection('agent-identity', identity);\n return builder;\n }\n\n /** Adds raw text (no wrapping tag) to this section. Empty strings are ignored. */\n addContent(content: string): this {\n const trimmed = content.trim();\n if (trimmed) this.children.push(trimmed);\n return this;\n }\n\n /**\n * Adds a leaf section: `<tag>content</tag>`. Empty content is ignored.\n * Set escapeContent = true to wrap content in CDATA (for arbitrary/untrusted text).\n */\n addSection(tag: string, content: string, escapeContent = false): this {\n const trimmed = content.trim();\n if (!trimmed) return this;\n const child = new InstructionBuilder(tag, escapeContent);\n child.children.push(trimmed);\n this.children.push(child);\n return this;\n }\n\n /** Creates a nested section and returns it so you can add children to it. */\n beginSection(tag: string): InstructionBuilder {\n const child = new InstructionBuilder(tag);\n this.children.push(child);\n return child;\n }\n\n /** Recursively renders the tree into an XML string. Empty sections are skipped. */\n build(): string {\n const inner: string[] = [];\n for (const child of this.children) {\n if (typeof child === 'string') {\n inner.push(child);\n } else {\n const output = child.build();\n if (output) inner.push(output);\n }\n }\n\n if (inner.length === 0) return '';\n\n const body = inner.join('\\n\\n');\n if (this.escapeContent) {\n return `<${this.currentTag}><![CDATA[\\n${body}\\n]]></${this.currentTag}>`;\n }\n return `<${this.currentTag}>\\n${body}\\n</${this.currentTag}>`;\n }\n}\n"],"mappings":";AAkDO,IAAM,sBACX;AAEK,IAAM,qBAAN,MAAM,oBAAmB;AAAA;AAAA,EAEtB;AAAA,EACA;AAAA,EACA,WAA4C,CAAC;AAAA,EAErD,YAAY,YAAoB,gBAAgB,OAAO;AACrD,SAAK,aAAa;AAClB,SAAK,gBAAgB;AAAA,EACvB;AAAA;AAAA,EAGA,OAAO,mBAAmB,UAAsC;AAC9D,UAAM,UAAU,IAAI,oBAAmB,eAAe;AACtD,YAAQ,WAAW,kBAAkB,QAAQ;AAC7C,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,WAAW,SAAuB;AAChC,UAAM,UAAU,QAAQ,KAAK;AAC7B,QAAI,QAAS,MAAK,SAAS,KAAK,OAAO;AACvC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAW,KAAa,SAAiB,gBAAgB,OAAa;AACpE,UAAM,UAAU,QAAQ,KAAK;AAC7B,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,QAAQ,IAAI,oBAAmB,KAAK,aAAa;AACvD,UAAM,SAAS,KAAK,OAAO;AAC3B,SAAK,SAAS,KAAK,KAAK;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,aAAa,KAAiC;AAC5C,UAAM,QAAQ,IAAI,oBAAmB,GAAG;AACxC,SAAK,SAAS,KAAK,KAAK;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,QAAgB;AACd,UAAM,QAAkB,CAAC;AACzB,eAAW,SAAS,KAAK,UAAU;AACjC,UAAI,OAAO,UAAU,UAAU;AAC7B,cAAM,KAAK,KAAK;AAAA,MAClB,OAAO;AACL,cAAM,SAAS,MAAM,MAAM;AAC3B,YAAI,OAAQ,OAAM,KAAK,MAAM;AAAA,MAC/B;AAAA,IACF;AAEA,QAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,UAAM,OAAO,MAAM,KAAK,MAAM;AAC9B,QAAI,KAAK,eAAe;AACtB,aAAO,IAAI,KAAK,UAAU;AAAA,EAAe,IAAI;AAAA,OAAU,KAAK,UAAU;AAAA,IACxE;AACA,WAAO,IAAI,KAAK,UAAU;AAAA,EAAM,IAAI;AAAA,IAAO,KAAK,UAAU;AAAA,EAC5D;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/core/InstructionBuilder.ts"],"sourcesContent":["/**\n * Builds a structured XML system prompt as a tree of named sections.\n *\n * Each node is an XML section (e.g. `<sandbox>`) that can contain\n * plain text and/or nested sections. Children are always rendered\n * in insertion order.\n *\n * @example\n * // Creating nested and sibling sections:\n *\n * const root = InstructionBuilder.createSystemPrompt(ROOT_AGENT_IDENTITY);\n *\n * // Add a leaf section (tag + text, no further nesting)\n * root.addSection('rules', 'Follow these rules...');\n *\n * // Add raw text without a wrapping tag\n * root.addContent('Some standalone text');\n *\n * // Begin a section you want to nest into — returns the child builder\n * const capabilities = root.beginSection('capabilities');\n * capabilities.addSection('tool-a', 'Tool A instructions');\n * capabilities.addSection('tool-b', 'Tool B instructions');\n *\n * // Nest deeper — beginSection on a child\n * const sandbox = capabilities.beginSection('sandbox');\n * sandbox.addContent('Sandbox overview');\n * sandbox.addSection('skill', 'Skill details');\n *\n * // Back to root level — just use the root reference again\n * root.addSection('user-instructions', userInput, true); // escapeContent = true\n *\n * console.log(root.build());\n *\n * // Output:\n * // <system-prompt>\n * // <agent-identity>...</agent-identity>\n * // <rules>Follow these rules...</rules>\n * // Some standalone text\n * // <capabilities>\n * // <tool-a>Tool A instructions</tool-a>\n * // <tool-b>Tool B instructions</tool-b>\n * // <sandbox>\n * // Sandbox overview\n * // <skill>Skill details</skill>\n * // </sandbox>\n * // </capabilities>\n * // <user-instructions><![CDATA[...]]></user-instructions>\n * // </system-prompt>\n */\n\nexport const ROOT_AGENT_IDENTITY =\n 'You are the Agent, an AI assistant that helps users accomplish tasks by leveraging available tools and capabilities.';\n\nexport class InstructionBuilder {\n /** The XML tag name for this section node. */\n private currentTag: string;\n private escapeContent: boolean;\n private children: (string | InstructionBuilder)[] = [];\n\n constructor(currentTag: string, escapeContent = false) {\n this.currentTag = currentTag;\n this.escapeContent = escapeContent;\n }\n\n /** Creates the root `<system-prompt>` node with the given identity in `<agent-identity>`. */\n static createSystemPrompt(identity: string): InstructionBuilder {\n const builder = new InstructionBuilder('system-prompt');\n builder.addSection('agent-identity', identity);\n return builder;\n }\n\n /** Adds raw text (no wrapping tag) to this section. Empty strings are ignored. */\n addContent(content: string): this {\n const trimmed = content.trim();\n if (trimmed) {\n this.children.push(trimmed);\n }\n return this;\n }\n\n /**\n * Adds a leaf section: `<tag>content</tag>`. Empty content is ignored.\n * Set escapeContent = true to wrap content in CDATA (for arbitrary/untrusted text).\n */\n addSection(tag: string, content: string, escapeContent = false): this {\n const trimmed = content.trim();\n if (!trimmed) {\n return this;\n }\n const child = new InstructionBuilder(tag, escapeContent);\n child.children.push(trimmed);\n this.children.push(child);\n return this;\n }\n\n /** Creates a nested section and returns it so you can add children to it. */\n beginSection(tag: string): InstructionBuilder {\n const child = new InstructionBuilder(tag);\n this.children.push(child);\n return child;\n }\n\n /** Recursively renders the tree into an XML string. Empty sections are skipped. */\n build(): string {\n const inner: string[] = [];\n for (const child of this.children) {\n if (typeof child === 'string') {\n inner.push(child);\n } else {\n const output = child.build();\n if (output) {\n inner.push(output);\n }\n }\n }\n\n if (inner.length === 0) {\n return '';\n }\n\n const body = inner.join('\\n\\n');\n if (this.escapeContent) {\n return `<${this.currentTag}><![CDATA[\\n${body}\\n]]></${this.currentTag}>`;\n }\n return `<${this.currentTag}>\\n${body}\\n</${this.currentTag}>`;\n }\n}\n"],"mappings":";AAkDO,IAAM,sBACX;AAEK,IAAM,qBAAN,MAAM,oBAAmB;AAAA;AAAA,EAEtB;AAAA,EACA;AAAA,EACA,WAA4C,CAAC;AAAA,EAErD,YAAY,YAAoB,gBAAgB,OAAO;AACrD,SAAK,aAAa;AAClB,SAAK,gBAAgB;AAAA,EACvB;AAAA;AAAA,EAGA,OAAO,mBAAmB,UAAsC;AAC9D,UAAM,UAAU,IAAI,oBAAmB,eAAe;AACtD,YAAQ,WAAW,kBAAkB,QAAQ;AAC7C,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,WAAW,SAAuB;AAChC,UAAM,UAAU,QAAQ,KAAK;AAC7B,QAAI,SAAS;AACX,WAAK,SAAS,KAAK,OAAO;AAAA,IAC5B;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAW,KAAa,SAAiB,gBAAgB,OAAa;AACpE,UAAM,UAAU,QAAQ,KAAK;AAC7B,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AACA,UAAM,QAAQ,IAAI,oBAAmB,KAAK,aAAa;AACvD,UAAM,SAAS,KAAK,OAAO;AAC3B,SAAK,SAAS,KAAK,KAAK;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,aAAa,KAAiC;AAC5C,UAAM,QAAQ,IAAI,oBAAmB,GAAG;AACxC,SAAK,SAAS,KAAK,KAAK;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,QAAgB;AACd,UAAM,QAAkB,CAAC;AACzB,eAAW,SAAS,KAAK,UAAU;AACjC,UAAI,OAAO,UAAU,UAAU;AAC7B,cAAM,KAAK,KAAK;AAAA,MAClB,OAAO;AACL,cAAM,SAAS,MAAM,MAAM;AAC3B,YAAI,QAAQ;AACV,gBAAM,KAAK,MAAM;AAAA,QACnB;AAAA,MACF;AAAA,IACF;AAEA,QAAI,MAAM,WAAW,GAAG;AACtB,aAAO;AAAA,IACT;AAEA,UAAM,OAAO,MAAM,KAAK,MAAM;AAC9B,QAAI,KAAK,eAAe;AACtB,aAAO,IAAI,KAAK,UAAU;AAAA,EAAe,IAAI;AAAA,OAAU,KAAK,UAAU;AAAA,IACxE;AACA,WAAO,IAAI,KAAK,UAAU;AAAA,EAAM,IAAI;AAAA,IAAO,KAAK,UAAU;AAAA,EAC5D;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"AskUserQuestion.d.ts","sourceRoot":"","sources":["../../../../src/core/capabilities/builtins/AskUserQuestion.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAiB1D,qBAAa,eAAgB,SAAQ,cAAc;IACjD,QAAQ,CAAC,IAAI,uBAA+B;IAC5C,QAAQ,CAAC,WAAW,qBAAqB;IACzC,SAAkB,cAAc,SAAS;IAEzC,SAAS,CAAC,QAAQ,IAAI,cAAc,EAAE,CAmCrC;CACF;AAED,wBAAgB,eAAe,IAAI,eAAe,CAIjD"}
1
+ {"version":3,"file":"AskUserQuestion.d.ts","sourceRoot":"","sources":["../../../../src/core/capabilities/builtins/AskUserQuestion.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAiB1D,qBAAa,eAAgB,SAAQ,cAAc;IACjD,QAAQ,CAAC,IAAI,uBAA+B;IAC5C,QAAQ,CAAC,WAAW,qBAAqB;IACzC,SAAkB,cAAc,SAAS;IAEzC,SAAS,CAAC,QAAQ,IAAI,cAAc,EAAE,CAwCrC;CACF;AAED,wBAAgB,eAAe,IAAI,eAAe,CAIjD"}
@@ -54,6 +54,7 @@ var AskUserQuestion = class extends import_ClientSideTool.ClientSideTool {
54
54
  "- The user picks exactly one option \u2014 multi-select is not available.",
55
55
  "- Options must be mutually exclusive. If a valid choice is a combination of other options, include it as a separate option with the combined data.",
56
56
  '- Every option must commit the user to a specific outcome. Do not add an option whose purpose is to let the user describe, specify, or type their own answer. Do not add an option like "Other" or "Something else".',
57
+ '- If you have enough context to confidently recommend one option, put it first with the exact suffix " (Recommended)" \u2014 no other wording. If no option clearly stands out, mark nothing.',
57
58
  "",
58
59
  "Example (distinct options):",
59
60
  'question: "<your question>"',
@@ -63,6 +64,10 @@ var AskUserQuestion = class extends import_ClientSideTool.ClientSideTool {
63
64
  'question: "<your question>"',
64
65
  'options: ["<Option A>", "<Option B>", "<Option A and B \u2014 combined details>"]',
65
66
  "",
67
+ "Example (context clearly favors A):",
68
+ 'question: "<your question>"',
69
+ 'options: ["<Option A> (Recommended)", "<Option B>", "<Option C>"]',
70
+ "",
66
71
  "Avoid:",
67
72
  'options: ["<Option A>", "<Option B>", "Other"]'
68
73
  ].join("\n"),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/core/capabilities/builtins/AskUserQuestion.ts"],"sourcesContent":["import { z } from 'zod';\nimport { ClientSideTool } from '../../mcp/ClientSideTool';\nimport { toolResultResponse } from '../../mcp/IMCPServer';\nimport { defineTool, type ToolDefinition } from '../../mcp/LocalToolMCP';\nimport type { AgentCapability } from '../AgentCapability';\nimport { OPENUI_SECTION_TAG } from './OpenUI';\n\nconst ASK_USER_QUESTION_SERVER_ID = 'ask-user-question';\nconst ASK_USER_QUESTION_TOOL_NAME = 'ask_user_question';\n\nconst askUserQuestionInputSchema = z.object({\n question: z.string().describe('The question to ask the user.'),\n options: z\n .array(z.string())\n .min(0)\n .max(5)\n .describe(\n '0-5 mutually exclusive choices, each mapping to a distinct outcome. A free-text input is always rendered alongside.',\n ),\n});\n\nexport class AskUserQuestion extends ClientSideTool {\n readonly name = ASK_USER_QUESTION_SERVER_ID;\n readonly displayName = 'AskUserQuestion';\n override readonly tracingEnabled = false;\n\n protected getTools(): ToolDefinition[] {\n return [\n defineTool({\n name: ASK_USER_QUESTION_TOOL_NAME,\n description: [\n 'Ask the user a question when clarification or a decision is needed before proceeding. Only ask when the answer meaningfully changes what you do next.',\n '',\n 'Rules:',\n '- Provide as many options as the question needs (0-5). When you include options, each must be a genuinely distinct, mutually exclusive outcome that meaningfully changes what you do next.',\n `- MUST NOT use <${OPENUI_SECTION_TAG}> for asking the user a question.`,\n '- The user picks exactly one option — multi-select is not available.',\n '- Options must be mutually exclusive. If a valid choice is a combination of other options, include it as a separate option with the combined data.',\n '- Every option must commit the user to a specific outcome. Do not add an option whose purpose is to let the user describe, specify, or type their own answer. Do not add an option like \"Other\" or \"Something else\".',\n '',\n 'Example (distinct options):',\n 'question: \"<your question>\"',\n 'options: [\"<Option A>\", \"<Option B>\", \"<Option C>\"]',\n '',\n 'Example (combined options):',\n 'question: \"<your question>\"',\n 'options: [\"<Option A>\", \"<Option B>\", \"<Option A and B — combined details>\"]',\n '',\n 'Avoid:',\n 'options: [\"<Option A>\", \"<Option B>\", \"Other\"]',\n ].join('\\n'),\n schema: askUserQuestionInputSchema,\n handler: () =>\n Promise.resolve(\n toolResultResponse({\n text: 'This tool requires client-side execution and cannot be run server-side.',\n isError: true,\n }),\n ),\n }),\n ];\n }\n}\n\nexport function askUserQuestion(): AgentCapability {\n return {\n systemToolSets: [new AskUserQuestion()],\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAkB;AAClB,4BAA+B;AAC/B,wBAAmC;AACnC,0BAAgD;AAEhD,oBAAmC;AAEnC,IAAM,8BAA8B;AACpC,IAAM,8BAA8B;AAEpC,IAAM,6BAA6B,aAAE,OAAO;AAAA,EAC1C,UAAU,aAAE,OAAO,EAAE,SAAS,+BAA+B;AAAA,EAC7D,SAAS,aACN,MAAM,aAAE,OAAO,CAAC,EAChB,IAAI,CAAC,EACL,IAAI,CAAC,EACL;AAAA,IACC;AAAA,EACF;AACJ,CAAC;AAEM,IAAM,kBAAN,cAA8B,qCAAe;AAAA,EACzC,OAAO;AAAA,EACP,cAAc;AAAA,EACL,iBAAiB;AAAA,EAEzB,WAA6B;AACrC,WAAO;AAAA,UACL,gCAAW;AAAA,QACT,MAAM;AAAA,QACN,aAAa;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,mBAAmB,gCAAkB;AAAA,UACrC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,EAAE,KAAK,IAAI;AAAA,QACX,QAAQ;AAAA,QACR,SAAS,MACP,QAAQ;AAAA,cACN,sCAAmB;AAAA,YACjB,MAAM;AAAA,YACN,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACJ,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEO,SAAS,kBAAmC;AACjD,SAAO;AAAA,IACL,gBAAgB,CAAC,IAAI,gBAAgB,CAAC;AAAA,EACxC;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../src/core/capabilities/builtins/AskUserQuestion.ts"],"sourcesContent":["import { z } from 'zod';\nimport { ClientSideTool } from '../../mcp/ClientSideTool';\nimport { toolResultResponse } from '../../mcp/IMCPServer';\nimport { defineTool, type ToolDefinition } from '../../mcp/LocalToolMCP';\nimport type { AgentCapability } from '../AgentCapability';\nimport { OPENUI_SECTION_TAG } from './OpenUI';\n\nconst ASK_USER_QUESTION_SERVER_ID = 'ask-user-question';\nconst ASK_USER_QUESTION_TOOL_NAME = 'ask_user_question';\n\nconst askUserQuestionInputSchema = z.object({\n question: z.string().describe('The question to ask the user.'),\n options: z\n .array(z.string())\n .min(0)\n .max(5)\n .describe(\n '0-5 mutually exclusive choices, each mapping to a distinct outcome. A free-text input is always rendered alongside.',\n ),\n});\n\nexport class AskUserQuestion extends ClientSideTool {\n readonly name = ASK_USER_QUESTION_SERVER_ID;\n readonly displayName = 'AskUserQuestion';\n override readonly tracingEnabled = false;\n\n protected getTools(): ToolDefinition[] {\n return [\n defineTool({\n name: ASK_USER_QUESTION_TOOL_NAME,\n description: [\n 'Ask the user a question when clarification or a decision is needed before proceeding. Only ask when the answer meaningfully changes what you do next.',\n '',\n 'Rules:',\n '- Provide as many options as the question needs (0-5). When you include options, each must be a genuinely distinct, mutually exclusive outcome that meaningfully changes what you do next.',\n `- MUST NOT use <${OPENUI_SECTION_TAG}> for asking the user a question.`,\n '- The user picks exactly one option — multi-select is not available.',\n '- Options must be mutually exclusive. If a valid choice is a combination of other options, include it as a separate option with the combined data.',\n '- Every option must commit the user to a specific outcome. Do not add an option whose purpose is to let the user describe, specify, or type their own answer. Do not add an option like \"Other\" or \"Something else\".',\n '- If you have enough context to confidently recommend one option, put it first with the exact suffix \" (Recommended)\" — no other wording. If no option clearly stands out, mark nothing.',\n '',\n 'Example (distinct options):',\n 'question: \"<your question>\"',\n 'options: [\"<Option A>\", \"<Option B>\", \"<Option C>\"]',\n '',\n 'Example (combined options):',\n 'question: \"<your question>\"',\n 'options: [\"<Option A>\", \"<Option B>\", \"<Option A and B — combined details>\"]',\n '',\n 'Example (context clearly favors A):',\n 'question: \"<your question>\"',\n 'options: [\"<Option A> (Recommended)\", \"<Option B>\", \"<Option C>\"]',\n '',\n 'Avoid:',\n 'options: [\"<Option A>\", \"<Option B>\", \"Other\"]',\n ].join('\\n'),\n schema: askUserQuestionInputSchema,\n handler: () =>\n Promise.resolve(\n toolResultResponse({\n text: 'This tool requires client-side execution and cannot be run server-side.',\n isError: true,\n }),\n ),\n }),\n ];\n }\n}\n\nexport function askUserQuestion(): AgentCapability {\n return {\n systemToolSets: [new AskUserQuestion()],\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAkB;AAClB,4BAA+B;AAC/B,wBAAmC;AACnC,0BAAgD;AAEhD,oBAAmC;AAEnC,IAAM,8BAA8B;AACpC,IAAM,8BAA8B;AAEpC,IAAM,6BAA6B,aAAE,OAAO;AAAA,EAC1C,UAAU,aAAE,OAAO,EAAE,SAAS,+BAA+B;AAAA,EAC7D,SAAS,aACN,MAAM,aAAE,OAAO,CAAC,EAChB,IAAI,CAAC,EACL,IAAI,CAAC,EACL;AAAA,IACC;AAAA,EACF;AACJ,CAAC;AAEM,IAAM,kBAAN,cAA8B,qCAAe;AAAA,EACzC,OAAO;AAAA,EACP,cAAc;AAAA,EACL,iBAAiB;AAAA,EAEzB,WAA6B;AACrC,WAAO;AAAA,UACL,gCAAW;AAAA,QACT,MAAM;AAAA,QACN,aAAa;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,mBAAmB,gCAAkB;AAAA,UACrC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,EAAE,KAAK,IAAI;AAAA,QACX,QAAQ;AAAA,QACR,SAAS,MACP,QAAQ;AAAA,cACN,sCAAmB;AAAA,YACjB,MAAM;AAAA,YACN,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACJ,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEO,SAAS,kBAAmC;AACjD,SAAO;AAAA,IACL,gBAAgB,CAAC,IAAI,gBAAgB,CAAC;AAAA,EACxC;AACF;","names":[]}
@@ -29,6 +29,7 @@ var AskUserQuestion = class extends ClientSideTool {
29
29
  "- The user picks exactly one option \u2014 multi-select is not available.",
30
30
  "- Options must be mutually exclusive. If a valid choice is a combination of other options, include it as a separate option with the combined data.",
31
31
  '- Every option must commit the user to a specific outcome. Do not add an option whose purpose is to let the user describe, specify, or type their own answer. Do not add an option like "Other" or "Something else".',
32
+ '- If you have enough context to confidently recommend one option, put it first with the exact suffix " (Recommended)" \u2014 no other wording. If no option clearly stands out, mark nothing.',
32
33
  "",
33
34
  "Example (distinct options):",
34
35
  'question: "<your question>"',
@@ -38,6 +39,10 @@ var AskUserQuestion = class extends ClientSideTool {
38
39
  'question: "<your question>"',
39
40
  'options: ["<Option A>", "<Option B>", "<Option A and B \u2014 combined details>"]',
40
41
  "",
42
+ "Example (context clearly favors A):",
43
+ 'question: "<your question>"',
44
+ 'options: ["<Option A> (Recommended)", "<Option B>", "<Option C>"]',
45
+ "",
41
46
  "Avoid:",
42
47
  'options: ["<Option A>", "<Option B>", "Other"]'
43
48
  ].join("\n"),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/core/capabilities/builtins/AskUserQuestion.ts"],"sourcesContent":["import { z } from 'zod';\nimport { ClientSideTool } from '../../mcp/ClientSideTool';\nimport { toolResultResponse } from '../../mcp/IMCPServer';\nimport { defineTool, type ToolDefinition } from '../../mcp/LocalToolMCP';\nimport type { AgentCapability } from '../AgentCapability';\nimport { OPENUI_SECTION_TAG } from './OpenUI';\n\nconst ASK_USER_QUESTION_SERVER_ID = 'ask-user-question';\nconst ASK_USER_QUESTION_TOOL_NAME = 'ask_user_question';\n\nconst askUserQuestionInputSchema = z.object({\n question: z.string().describe('The question to ask the user.'),\n options: z\n .array(z.string())\n .min(0)\n .max(5)\n .describe(\n '0-5 mutually exclusive choices, each mapping to a distinct outcome. A free-text input is always rendered alongside.',\n ),\n});\n\nexport class AskUserQuestion extends ClientSideTool {\n readonly name = ASK_USER_QUESTION_SERVER_ID;\n readonly displayName = 'AskUserQuestion';\n override readonly tracingEnabled = false;\n\n protected getTools(): ToolDefinition[] {\n return [\n defineTool({\n name: ASK_USER_QUESTION_TOOL_NAME,\n description: [\n 'Ask the user a question when clarification or a decision is needed before proceeding. Only ask when the answer meaningfully changes what you do next.',\n '',\n 'Rules:',\n '- Provide as many options as the question needs (0-5). When you include options, each must be a genuinely distinct, mutually exclusive outcome that meaningfully changes what you do next.',\n `- MUST NOT use <${OPENUI_SECTION_TAG}> for asking the user a question.`,\n '- The user picks exactly one option — multi-select is not available.',\n '- Options must be mutually exclusive. If a valid choice is a combination of other options, include it as a separate option with the combined data.',\n '- Every option must commit the user to a specific outcome. Do not add an option whose purpose is to let the user describe, specify, or type their own answer. Do not add an option like \"Other\" or \"Something else\".',\n '',\n 'Example (distinct options):',\n 'question: \"<your question>\"',\n 'options: [\"<Option A>\", \"<Option B>\", \"<Option C>\"]',\n '',\n 'Example (combined options):',\n 'question: \"<your question>\"',\n 'options: [\"<Option A>\", \"<Option B>\", \"<Option A and B — combined details>\"]',\n '',\n 'Avoid:',\n 'options: [\"<Option A>\", \"<Option B>\", \"Other\"]',\n ].join('\\n'),\n schema: askUserQuestionInputSchema,\n handler: () =>\n Promise.resolve(\n toolResultResponse({\n text: 'This tool requires client-side execution and cannot be run server-side.',\n isError: true,\n }),\n ),\n }),\n ];\n }\n}\n\nexport function askUserQuestion(): AgentCapability {\n return {\n systemToolSets: [new AskUserQuestion()],\n };\n}\n"],"mappings":";AAAA,SAAS,SAAS;AAClB,SAAS,sBAAsB;AAC/B,SAAS,0BAA0B;AACnC,SAAS,kBAAuC;AAEhD,SAAS,0BAA0B;AAEnC,IAAM,8BAA8B;AACpC,IAAM,8BAA8B;AAEpC,IAAM,6BAA6B,EAAE,OAAO;AAAA,EAC1C,UAAU,EAAE,OAAO,EAAE,SAAS,+BAA+B;AAAA,EAC7D,SAAS,EACN,MAAM,EAAE,OAAO,CAAC,EAChB,IAAI,CAAC,EACL,IAAI,CAAC,EACL;AAAA,IACC;AAAA,EACF;AACJ,CAAC;AAEM,IAAM,kBAAN,cAA8B,eAAe;AAAA,EACzC,OAAO;AAAA,EACP,cAAc;AAAA,EACL,iBAAiB;AAAA,EAEzB,WAA6B;AACrC,WAAO;AAAA,MACL,WAAW;AAAA,QACT,MAAM;AAAA,QACN,aAAa;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,mBAAmB,kBAAkB;AAAA,UACrC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,EAAE,KAAK,IAAI;AAAA,QACX,QAAQ;AAAA,QACR,SAAS,MACP,QAAQ;AAAA,UACN,mBAAmB;AAAA,YACjB,MAAM;AAAA,YACN,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACJ,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEO,SAAS,kBAAmC;AACjD,SAAO;AAAA,IACL,gBAAgB,CAAC,IAAI,gBAAgB,CAAC;AAAA,EACxC;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../src/core/capabilities/builtins/AskUserQuestion.ts"],"sourcesContent":["import { z } from 'zod';\nimport { ClientSideTool } from '../../mcp/ClientSideTool';\nimport { toolResultResponse } from '../../mcp/IMCPServer';\nimport { defineTool, type ToolDefinition } from '../../mcp/LocalToolMCP';\nimport type { AgentCapability } from '../AgentCapability';\nimport { OPENUI_SECTION_TAG } from './OpenUI';\n\nconst ASK_USER_QUESTION_SERVER_ID = 'ask-user-question';\nconst ASK_USER_QUESTION_TOOL_NAME = 'ask_user_question';\n\nconst askUserQuestionInputSchema = z.object({\n question: z.string().describe('The question to ask the user.'),\n options: z\n .array(z.string())\n .min(0)\n .max(5)\n .describe(\n '0-5 mutually exclusive choices, each mapping to a distinct outcome. A free-text input is always rendered alongside.',\n ),\n});\n\nexport class AskUserQuestion extends ClientSideTool {\n readonly name = ASK_USER_QUESTION_SERVER_ID;\n readonly displayName = 'AskUserQuestion';\n override readonly tracingEnabled = false;\n\n protected getTools(): ToolDefinition[] {\n return [\n defineTool({\n name: ASK_USER_QUESTION_TOOL_NAME,\n description: [\n 'Ask the user a question when clarification or a decision is needed before proceeding. Only ask when the answer meaningfully changes what you do next.',\n '',\n 'Rules:',\n '- Provide as many options as the question needs (0-5). When you include options, each must be a genuinely distinct, mutually exclusive outcome that meaningfully changes what you do next.',\n `- MUST NOT use <${OPENUI_SECTION_TAG}> for asking the user a question.`,\n '- The user picks exactly one option — multi-select is not available.',\n '- Options must be mutually exclusive. If a valid choice is a combination of other options, include it as a separate option with the combined data.',\n '- Every option must commit the user to a specific outcome. Do not add an option whose purpose is to let the user describe, specify, or type their own answer. Do not add an option like \"Other\" or \"Something else\".',\n '- If you have enough context to confidently recommend one option, put it first with the exact suffix \" (Recommended)\" — no other wording. If no option clearly stands out, mark nothing.',\n '',\n 'Example (distinct options):',\n 'question: \"<your question>\"',\n 'options: [\"<Option A>\", \"<Option B>\", \"<Option C>\"]',\n '',\n 'Example (combined options):',\n 'question: \"<your question>\"',\n 'options: [\"<Option A>\", \"<Option B>\", \"<Option A and B — combined details>\"]',\n '',\n 'Example (context clearly favors A):',\n 'question: \"<your question>\"',\n 'options: [\"<Option A> (Recommended)\", \"<Option B>\", \"<Option C>\"]',\n '',\n 'Avoid:',\n 'options: [\"<Option A>\", \"<Option B>\", \"Other\"]',\n ].join('\\n'),\n schema: askUserQuestionInputSchema,\n handler: () =>\n Promise.resolve(\n toolResultResponse({\n text: 'This tool requires client-side execution and cannot be run server-side.',\n isError: true,\n }),\n ),\n }),\n ];\n }\n}\n\nexport function askUserQuestion(): AgentCapability {\n return {\n systemToolSets: [new AskUserQuestion()],\n };\n}\n"],"mappings":";AAAA,SAAS,SAAS;AAClB,SAAS,sBAAsB;AAC/B,SAAS,0BAA0B;AACnC,SAAS,kBAAuC;AAEhD,SAAS,0BAA0B;AAEnC,IAAM,8BAA8B;AACpC,IAAM,8BAA8B;AAEpC,IAAM,6BAA6B,EAAE,OAAO;AAAA,EAC1C,UAAU,EAAE,OAAO,EAAE,SAAS,+BAA+B;AAAA,EAC7D,SAAS,EACN,MAAM,EAAE,OAAO,CAAC,EAChB,IAAI,CAAC,EACL,IAAI,CAAC,EACL;AAAA,IACC;AAAA,EACF;AACJ,CAAC;AAEM,IAAM,kBAAN,cAA8B,eAAe;AAAA,EACzC,OAAO;AAAA,EACP,cAAc;AAAA,EACL,iBAAiB;AAAA,EAEzB,WAA6B;AACrC,WAAO;AAAA,MACL,WAAW;AAAA,QACT,MAAM;AAAA,QACN,aAAa;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,mBAAmB,kBAAkB;AAAA,UACrC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,EAAE,KAAK,IAAI;AAAA,QACX,QAAQ;AAAA,QACR,SAAS,MACP,QAAQ;AAAA,UACN,mBAAmB;AAAA,YACjB,MAAM;AAAA,YACN,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACJ,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEO,SAAS,kBAAmC;AACjD,SAAO;AAAA,IACL,gBAAgB,CAAC,IAAI,gBAAgB,CAAC;AAAA,EACxC;AACF;","names":[]}