@ponythewhite/base-context 1.0.7 → 1.0.8

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 (133) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/base-context-runtime/pyproject.toml +1 -1
  3. package/dist/base-context-runtime/src/rlm/__init__.py +3 -0
  4. package/dist/base-context-runtime/src/rlm/harness.py +86 -48
  5. package/dist/base-context-runtime/test/test_harness.py +215 -140
  6. package/dist/base-context-runtime/uv.lock +1 -1
  7. package/dist/build-info.json +1 -1
  8. package/dist/bundle/amazon-bedrock.js +3 -3
  9. package/dist/bundle/{anthropic-UV5GZDGU.js → anthropic-5PSCZEER.js} +2 -7
  10. package/dist/bundle/{azure-openai-responses-WSNPXLYC.js → azure-openai-responses-AYTLJR33.js} +2 -2
  11. package/dist/bundle/{bundled-modules-PS66L3IT.js → bundled-modules-IGMJH2MU.js} +5 -5
  12. package/dist/bundle/{chunk-UPVDERMD.js → chunk-2IPDSTDR.js} +11 -9
  13. package/dist/bundle/chunk-D3KOF57W.js +22040 -0
  14. package/dist/bundle/{chunk-VCW3YDFF.js → chunk-EXEFSSF4.js} +1475 -562
  15. package/dist/bundle/{chunk-VSIYFWYI.js → chunk-KT2BNEPE.js} +21 -8
  16. package/dist/bundle/{chunk-KTNETTHI.js → chunk-Q3MBSBEB.js} +3 -101
  17. package/dist/bundle/{chunk-LFPWHI42.js → chunk-QKIFBA7N.js} +2 -2
  18. package/dist/bundle/{chunk-PFROC4EV.js → chunk-RVJVXZCS.js} +12 -9
  19. package/dist/bundle/{cli-main-MMHTK7EB.js → cli-main-BUK7QTHO.js} +4 -4
  20. package/dist/bundle/cli.js +1 -1
  21. package/dist/bundle/{google-T32FMD4G.js → google-HTMCUJ7X.js} +2 -2
  22. package/dist/bundle/{google-vertex-56KP6I3B.js → google-vertex-ZQO65AXF.js} +2 -2
  23. package/dist/bundle/{main-XAIVH4Y7.js → main-2FWHT2WZ.js} +5 -5
  24. package/dist/bundle/{mistral-WGBMYIVU.js → mistral-SB7LU56G.js} +1 -1
  25. package/dist/bundle/{openai-codex-responses-PIV2RQ3G.js → openai-codex-responses-5CEW4VN3.js} +53 -27
  26. package/dist/bundle/{openai-completions-64C3JPR4.js → openai-completions-BAZJQSS2.js} +1 -1
  27. package/dist/bundle/{openai-responses-UI7RSTDV.js → openai-responses-VHOE427P.js} +48 -5
  28. package/dist/core/agent-session.d.ts +6 -1
  29. package/dist/core/agent-session.d.ts.map +1 -1
  30. package/dist/core/agent-session.js +177 -24
  31. package/dist/core/agent-session.js.map +1 -1
  32. package/dist/core/canonical-context.d.ts +8 -0
  33. package/dist/core/canonical-context.d.ts.map +1 -1
  34. package/dist/core/canonical-context.js +37 -5
  35. package/dist/core/canonical-context.js.map +1 -1
  36. package/dist/core/compaction/compaction.d.ts +2 -2
  37. package/dist/core/compaction/compaction.d.ts.map +1 -1
  38. package/dist/core/compaction/compaction.js +31 -13
  39. package/dist/core/compaction/compaction.js.map +1 -1
  40. package/dist/core/context-epoch.d.ts +1 -1
  41. package/dist/core/context-epoch.d.ts.map +1 -1
  42. package/dist/core/context-epoch.js +2 -1
  43. package/dist/core/context-epoch.js.map +1 -1
  44. package/dist/core/extensions/types.d.ts +2 -2
  45. package/dist/core/extensions/types.d.ts.map +1 -1
  46. package/dist/core/extensions/types.js.map +1 -1
  47. package/dist/core/history-index-worker.d.ts.map +1 -1
  48. package/dist/core/history-index-worker.js +29 -8
  49. package/dist/core/history-index-worker.js.map +1 -1
  50. package/dist/core/history-index.d.ts +11 -1
  51. package/dist/core/history-index.d.ts.map +1 -1
  52. package/dist/core/history-index.js +2 -1
  53. package/dist/core/history-index.js.map +1 -1
  54. package/dist/core/inference-coordinator.d.ts.map +1 -1
  55. package/dist/core/inference-coordinator.js +108 -13
  56. package/dist/core/inference-coordinator.js.map +1 -1
  57. package/dist/core/kernel/bootstrap.d.ts.map +1 -1
  58. package/dist/core/kernel/bootstrap.js +97 -107
  59. package/dist/core/kernel/bootstrap.js.map +1 -1
  60. package/dist/core/kernel/repl-manager.d.ts.map +1 -1
  61. package/dist/core/kernel/repl-manager.js +11 -0
  62. package/dist/core/kernel/repl-manager.js.map +1 -1
  63. package/dist/core/kernel/shared.d.ts +2 -0
  64. package/dist/core/kernel/shared.d.ts.map +1 -1
  65. package/dist/core/kernel/shared.js.map +1 -1
  66. package/dist/core/messages.d.ts.map +1 -1
  67. package/dist/core/messages.js +4 -1
  68. package/dist/core/messages.js.map +1 -1
  69. package/dist/core/prompts/rlm.d.ts.map +1 -1
  70. package/dist/core/prompts/rlm.js +4 -2
  71. package/dist/core/prompts/rlm.js.map +1 -1
  72. package/dist/core/public-context.d.ts.map +1 -1
  73. package/dist/core/public-context.js +16 -0
  74. package/dist/core/public-context.js.map +1 -1
  75. package/dist/core/refinement/refinement.d.ts +19 -5
  76. package/dist/core/refinement/refinement.d.ts.map +1 -1
  77. package/dist/core/refinement/refinement.js +90 -35
  78. package/dist/core/refinement/refinement.js.map +1 -1
  79. package/dist/core/request-view-selection.d.ts +10 -2
  80. package/dist/core/request-view-selection.d.ts.map +1 -1
  81. package/dist/core/request-view-selection.js +235 -100
  82. package/dist/core/request-view-selection.js.map +1 -1
  83. package/dist/core/retained-tool-output.d.ts +28 -0
  84. package/dist/core/retained-tool-output.d.ts.map +1 -0
  85. package/dist/core/retained-tool-output.js +102 -0
  86. package/dist/core/retained-tool-output.js.map +1 -0
  87. package/dist/core/selective-recovery.d.ts +47 -3
  88. package/dist/core/selective-recovery.d.ts.map +1 -1
  89. package/dist/core/selective-recovery.js +428 -109
  90. package/dist/core/selective-recovery.js.map +1 -1
  91. package/dist/core/session-history-index.d.ts +3 -1
  92. package/dist/core/session-history-index.d.ts.map +1 -1
  93. package/dist/core/session-history-index.js +1 -1
  94. package/dist/core/session-history-index.js.map +1 -1
  95. package/dist/core/settings-manager.d.ts +5 -0
  96. package/dist/core/settings-manager.d.ts.map +1 -1
  97. package/dist/core/settings-manager.js +3 -0
  98. package/dist/core/settings-manager.js.map +1 -1
  99. package/dist/core/system-prompt.d.ts +3 -1
  100. package/dist/core/system-prompt.d.ts.map +1 -1
  101. package/dist/core/system-prompt.js +3 -3
  102. package/dist/core/system-prompt.js.map +1 -1
  103. package/dist/core/task-frame.d.ts +1 -1
  104. package/dist/core/task-frame.d.ts.map +1 -1
  105. package/dist/core/task-frame.js +21 -1
  106. package/dist/core/task-frame.js.map +1 -1
  107. package/dist/core/task-state-reader.d.ts +10 -2
  108. package/dist/core/task-state-reader.d.ts.map +1 -1
  109. package/dist/core/task-state-reader.js +75 -9
  110. package/dist/core/task-state-reader.js.map +1 -1
  111. package/dist/core/tools/ipython.d.ts +5 -0
  112. package/dist/core/tools/ipython.d.ts.map +1 -1
  113. package/dist/core/tools/ipython.js +59 -17
  114. package/dist/core/tools/ipython.js.map +1 -1
  115. package/dist/core/tools/prime-context.d.ts.map +1 -1
  116. package/dist/core/tools/prime-context.js +1 -1
  117. package/dist/core/tools/prime-context.js.map +1 -1
  118. package/dist/core/view-units.d.ts +4 -0
  119. package/dist/core/view-units.d.ts.map +1 -1
  120. package/dist/core/view-units.js +28 -19
  121. package/dist/core/view-units.js.map +1 -1
  122. package/dist/installer.mjs +98 -77
  123. package/dist/modes/interactive/components/refinement-outcome-message.d.ts.map +1 -1
  124. package/dist/modes/interactive/components/refinement-outcome-message.js.map +1 -1
  125. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  126. package/dist/modes/interactive/interactive-mode.js +5 -5
  127. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  128. package/dist/skills/skill-creator/SKILL.md +18 -1
  129. package/docs/settings.md +45 -0
  130. package/docs/skills.md +77 -2
  131. package/package.json +4 -4
  132. package/skills/skill-creator/SKILL.md +18 -1
  133. package/dist/bundle/chunk-W46VZFI6.js +0 -21681
@@ -117,6 +117,8 @@ export interface KernelSentAgentMessage {
117
117
  };
118
118
  }
119
119
  export interface ExecuteResult {
120
+ /** Whether the finalized textual output was captured without host truncation or interruption. */
121
+ outputComplete?: boolean;
120
122
  /** Host-selected public data transferred once to the normal finalized ipython result. */
121
123
  nativeRecoveries?: NativeRecoveryResponse[];
122
124
  stdout: string;
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/core/kernel/shared.ts"],"names":[],"mappings":"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","sourcesContent":["import { registerSessionResourceCleanup } from \"@ponythewhite/base-context-ai\";\nimport type { NativeRecoveryResponse } from \"../selective-recovery.js\";\nimport type { KernelBootstrapProgressHandler, KernelPythonSkill } from \"./bootstrap.js\";\nimport type { RestoreResult, SnapshotResult } from \"./state-snapshot.js\";\n\nexport const DEFAULT_MAX_OUTPUT_CHARS = 65536;\nexport const HOST_REQUEST_SHUTDOWN_TIMEOUT_MS = 5000;\nexport const KERNEL_SHUTDOWN_TIMEOUT_MS = 5000;\nexport const DEFAULT_SNAPSHOT_DEBOUNCE_MS = 1500;\nexport const SNAPSHOT_EXECUTION_TIMEOUT_MS = 5000;\nexport const KERNEL_ABORT_GRACE_MS = 1000;\nexport const KERNEL_BUSY_REUSE_WAIT_MS = 5000;\nexport const KERNEL_BUSY_INTERRUPT_INTERVAL_MS = 500;\nexport const MAX_LATE_SENT_AGENT_MESSAGE_HANDLERS = 256;\nconst KERNEL_BUSY_AFTER_INTERRUPT_MESSAGE =\n\t\"The Python kernel is still running the previously interrupted cell. Wait and try again, or kill the kernel to start fresh.\";\n\nexport class KernelBusyAfterInterruptError extends Error {\n\tconstructor() {\n\t\tsuper(KERNEL_BUSY_AFTER_INTERRUPT_MESSAGE);\n\t\tthis.name = \"KernelBusyAfterInterruptError\";\n\t}\n}\n\n/**\n * Handles one typed request from Python code running in the kernel.\n * The returned record is delivered verbatim to the Python caller.\n */\nexport interface HostRequestContext {\n\t/** Actual active tool/cell cancellation; never read from the Python payload. */\n\tsignal?: AbortSignal;\n\t/** A host-reserved share of this cell's aggregate recovery response budget. */\n\tnativeRecovery?: { maxBytes: number };\n}\n\nexport type HostRequestHandler = (\n\tpayload: Record<string, unknown>,\n\tcontext?: HostRequestContext,\n) => Promise<Record<string, unknown>>;\n\n/** Host request handlers keyed by request type (e.g. \"rlm.run\", \"goal.complete\"). */\nexport type HostRequestHandlers = Record<string, HostRequestHandler>;\n\n/** Where and how to persist the kernel's user namespace so it survives resume. */\nexport interface KernelSnapshotConfig {\n\t/** Absolute path for the dill payload. */\n\tpath: string;\n\t/** Absolute path for the JSON manifest written alongside the payload. */\n\tmanifestPath: string;\n\t/** Maximum aggregate snapshot size. Default 256 MiB. */\n\tmaxBytes?: number;\n\t/** Maximum serialized size of one variable. Default 16 MiB. */\n\tmaxVariableBytes?: number;\n\t/** Debounce window for the auto-snapshot after a successful execution. Default 1500 ms. */\n\tdebounceMs?: number;\n}\n\nexport interface KernelManagerOptions {\n\t/** Python interpreter with the kernel runtime available. Defaults to the auto-bootstrapped kernel. */\n\tpython?: string;\n\tcwd?: string;\n\tenv?: Record<string, string>;\n\tsessionId?: string;\n\thostHandlers?: HostRequestHandlers;\n\tpythonSkills?: readonly KernelPythonSkill[];\n\t/** Persist/revive the user namespace across kernel restarts and session resume. */\n\tsnapshot?: KernelSnapshotConfig;\n\t/** Runtime bootstrap re-run on a protocol-repaired kernel so live handles (rlm, bash, skills) exist again. */\n\tbootstrapCode?: string;\n\t/** File receiving the kernel process's stderr, rotated once at each spawn. */\n\tstderrLogPath?: string;\n}\n\nexport interface KernelStartOptions {\n\tonBootstrapProgress?: KernelBootstrapProgressHandler;\n\tsignal?: AbortSignal;\n}\n\nexport interface ExecuteOptions {\n\t/** Only a finalized ipython tool call can retain recovery output; not bootstrap/state cells. */\n\tnativeRecovery?: boolean;\n\t/** @internal Host-only closure captured by the admitted owned executor; never sent to Python. */\n\trunNativeRecovery?: <T>(read: () => Promise<T>) => Promise<T>;\n\t/** Aborting interrupts the kernel out-of-band. */\n\tsignal?: AbortSignal;\n\tonStream?: (chunk: string, name: \"stdout\" | \"stderr\") => void;\n\tonLateSentAgentMessage?: (message: KernelSentAgentMessage) => void;\n\t/** Cap stdout / stderr / result at this many characters. Default 65536. */\n\tmaxOutputChars?: number;\n\t/** Synthetic host cell (snapshot/restore/list); excluded from lastCellCode attribution. */\n\tinternal?: boolean;\n\t/** The protocol repair's own restore; exempt from waiting on the repair it belongs to. */\n\tprotocolRepair?: boolean;\n}\n\n/** MIME tag the `edit` skill emits diff payloads under. */\nexport const DIFF_DISPLAY_MIME = \"application/vnd.prime-agent.diff+json\";\n\n/** MIME tag the `attach-image` skill emits media payloads under. */\nexport const ATTACHMENT_DISPLAY_MIME = \"application/vnd.prime-agent.attachment+json\";\n\n/** MIME tag the `agent-message` skill emits after sending a message. */\nexport const AGENT_MESSAGE_DISPLAY_MIME = \"application/vnd.prime-agent.agent-message+json\";\n\n/**\n * Hard ceiling on a single attachment's base64 payload, a defensive guard\n * against a runaway direct display emit. The `attach-image` skill caps\n * its own images well under this (see `_MAX_IMAGE_BYTES`), so a skill-produced\n * attachment is never dropped here — only a non-skill emit can hit this.\n */\nexport const MAX_ATTACHMENT_DATA_CHARS = 10_000_000;\n\n/** One file edit, captured from a {@link DIFF_DISPLAY_MIME} display payload. */\nexport interface KernelDiffDisplay {\n\tpath: string;\n\toldStr: string;\n\tnewStr: string;\n\t/** 1-based line where `oldStr` begins in the file, for absolute line numbers. */\n\tstartLine?: number;\n}\n\n/** One media attachment, captured from an {@link ATTACHMENT_DISPLAY_MIME} display payload. */\nexport interface KernelAttachment {\n\tmimeType: string;\n\t/** base64-encoded bytes. */\n\tdata: string;\n\t/** Source path, surfaced to the TUI renderer. */\n\tpath?: string;\n}\n\nexport interface KernelSentAgentMessage {\n\tid: string;\n\tmessage: string;\n\tdeliveryStatus: \"delivered\" | \"queued\";\n\treceiverRole?: \"parent\" | \"sibling\" | \"child\";\n\ttarget: {\n\t\tactiveSessionId: string;\n\t\tsessionId: string;\n\t\tsessionName?: string;\n\t};\n}\n\nexport interface ExecuteResult {\n\t/** Host-selected public data transferred once to the normal finalized ipython result. */\n\tnativeRecoveries?: NativeRecoveryResponse[];\n\tstdout: string;\n\tstderr: string;\n\t/** Text of the cell's trailing expression value, if the cell produced one. */\n\tresult?: string;\n\t/** Diffs emitted via display events, in order. */\n\tdiffs?: KernelDiffDisplay[];\n\t/** Media attachments emitted via display events, in order. */\n\tattachments?: KernelAttachment[];\n\t/** Agent messages sent from this cell, in order. */\n\tsentAgentMessages?: KernelSentAgentMessage[];\n\t/** Output that arrived without this cell's id (user threads, other cells' leftovers, raw fd writes). */\n\tbackgroundOutput?: string;\n\tstatus: \"ok\" | \"error\" | \"aborted\";\n\terror?: { ename: string; evalue: string; traceback: string[] };\n\tdurationMs: number;\n}\n\n/** Parse a {@link DIFF_DISPLAY_MIME} payload, tolerating malformed input. */\nexport function parseDiffDisplay(payload: unknown): KernelDiffDisplay | undefined {\n\tif (!isRecord(payload)) {\n\t\treturn undefined;\n\t}\n\tconst { path, old_str: oldStr, new_str: newStr, start_line: startLine } = payload;\n\tif (typeof path !== \"string\" || typeof oldStr !== \"string\" || typeof newStr !== \"string\") {\n\t\treturn undefined;\n\t}\n\treturn { path, oldStr, newStr, startLine: typeof startLine === \"number\" ? startLine : undefined };\n}\n\n/**\n * Parse an {@link ATTACHMENT_DISPLAY_MIME} payload. Malformed payloads are\n * tolerantly ignored (`undefined`); a well-formed payload exceeding\n * {@link MAX_ATTACHMENT_DATA_CHARS} is reported as `\"oversized\"` so the caller\n * can fail the cell loudly rather than silently dropping the image.\n */\nexport function parseAttachmentDisplay(payload: unknown): KernelAttachment | \"oversized\" | undefined {\n\tif (!isRecord(payload)) {\n\t\treturn undefined;\n\t}\n\tconst { mime_type: mimeType, data, path } = payload;\n\tif (typeof mimeType !== \"string\" || typeof data !== \"string\") {\n\t\treturn undefined;\n\t}\n\tif (data.length > MAX_ATTACHMENT_DATA_CHARS) {\n\t\treturn \"oversized\";\n\t}\n\treturn { mimeType, data, path: typeof path === \"string\" ? path : undefined };\n}\n\nexport function parseSentAgentMessage(payload: unknown): KernelSentAgentMessage | undefined {\n\tif (!isRecord(payload) || !isRecord(payload.target)) {\n\t\treturn undefined;\n\t}\n\tconst { id, message, deliveryStatus, receiverRole, target } = payload;\n\tconst { activeSessionId, sessionId, sessionName } = target;\n\tif (\n\t\ttypeof id !== \"string\" ||\n\t\ttypeof message !== \"string\" ||\n\t\t(deliveryStatus !== \"delivered\" && deliveryStatus !== \"queued\") ||\n\t\ttypeof activeSessionId !== \"string\" ||\n\t\ttypeof sessionId !== \"string\"\n\t) {\n\t\treturn undefined;\n\t}\n\treturn {\n\t\tid,\n\t\tmessage,\n\t\tdeliveryStatus,\n\t\t...(receiverRole === \"parent\" || receiverRole === \"sibling\" || receiverRole === \"child\" ? { receiverRole } : {}),\n\t\ttarget: {\n\t\t\tactiveSessionId,\n\t\t\tsessionId,\n\t\t\t...(typeof sessionName === \"string\" ? { sessionName } : {}),\n\t\t},\n\t};\n}\n\nexport function createKernelStartupAbortError(): Error {\n\treturn new Error(\"Kernel startup aborted\");\n}\n\nexport function raceStartupWithAbort<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T> {\n\tif (!signal) {\n\t\treturn promise;\n\t}\n\tif (signal.aborted) {\n\t\treturn Promise.reject(createKernelStartupAbortError());\n\t}\n\treturn new Promise<T>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tconst cleanup = () => signal.removeEventListener(\"abort\", abort);\n\t\tconst abort = () => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tcleanup();\n\t\t\treject(createKernelStartupAbortError());\n\t\t};\n\t\tsignal.addEventListener(\"abort\", abort, { once: true });\n\t\tpromise.then(\n\t\t\t(value) => {\n\t\t\t\tif (settled) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsettled = true;\n\t\t\t\tcleanup();\n\t\t\t\tresolve(value);\n\t\t\t},\n\t\t\t(error: unknown) => {\n\t\t\t\tif (settled) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsettled = true;\n\t\t\t\tcleanup();\n\t\t\t\treject(error);\n\t\t\t},\n\t\t);\n\t});\n}\n\nexport interface Deferred<T> {\n\tpromise: Promise<T>;\n\tresolve: (value: T) => void;\n\treject: (error: Error) => void;\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function errorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nexport function createDeferred<T>(): Deferred<T> {\n\tlet resolve!: (value: T) => void;\n\tlet reject!: (error: Error) => void;\n\tconst promise = new Promise<T>((promiseResolve, promiseReject) => {\n\t\tresolve = promiseResolve;\n\t\treject = promiseReject;\n\t});\n\treturn { promise, resolve, reject };\n}\n\nexport interface KernelShutdownOptions {\n\tsnapshot?: boolean;\n\tdrainHostRequests?: boolean;\n}\n\n/** A bounded owned lifecycle observation, not a namespace, restore, or live-health assertion. */\nexport interface KernelLifecycleState {\n\treadonly source: \"repl-manager\" | \"ipython-provisioner\" | \"unobserved\";\n\treadonly owner: string | null;\n\treadonly generation: number | null;\n\treadonly state: \"idle\" | \"starting\" | \"running\" | \"shutdown\" | \"provisioning\" | \"disposed\" | \"unobserved\";\n}\n\nexport interface CapturedKernelLifecycle {\n\treadonly snapshot: Readonly<KernelLifecycleState>;\n\t/** Checks the original observation; it never probes or substitutes a newer snapshot. */\n\tisCurrent(): boolean;\n}\n\n/** Public surface every kernel client exposes to the provisioner and session layer. */\nexport interface KernelClient {\n\treadonly ownerSessionId: string | undefined;\n\treadonly isRunning: boolean;\n\tstart(options?: KernelStartOptions): Promise<void>;\n\texecute(code: string, opts?: ExecuteOptions): Promise<ExecuteResult>;\n\tshutdown(opts?: KernelShutdownOptions): Promise<boolean>;\n\trestart(): Promise<void>;\n\tkill(): Promise<void>;\n\tdisposeSync(): void;\n\tsnapshotState(): Promise<SnapshotResult | null>;\n\tpruneOversizedVariables(): Promise<SnapshotResult | null>;\n\trestoreState(): Promise<RestoreResult | null>;\n\tlistNamespaceNames(signal?: AbortSignal): Promise<string[] | null>;\n}\n\n// One registry serves every client kind; two parallel registries would\n// double-install process signal handlers.\nexport const liveKernels = new Set<KernelClient>();\nlet signalHandlersInstalled = false;\n\nregisterSessionResourceCleanup((sessionId) => {\n\tfor (const k of liveKernels) {\n\t\tif (!sessionId || k.ownerSessionId === sessionId) {\n\t\t\tvoid k.shutdown({ snapshot: true, drainHostRequests: true });\n\t\t}\n\t}\n});\n\nexport function installSignalHandlersOnce(): void {\n\tif (signalHandlersInstalled) return;\n\tsignalHandlersInstalled = true;\n\n\tconst asyncShutdown = async (): Promise<void> => {\n\t\t// These paths can await, so flush the namespace snapshot before tearing down.\n\t\tawait Promise.allSettled([...liveKernels].map((k) => k.shutdown({ snapshot: true })));\n\t};\n\n\t// `beforeExit` and signal handlers can await async cleanup. `exit`\n\t// can only do sync work (Node won't run pending microtasks past it),\n\t// so it falls back to `disposeSync()` which kills the child synchronously.\n\tprocess.on(\"beforeExit\", () => {\n\t\tvoid asyncShutdown();\n\t});\n\tprocess.on(\"SIGINT\", () => {\n\t\tvoid asyncShutdown().finally(() => process.exit(130));\n\t});\n\tprocess.on(\"SIGTERM\", () => {\n\t\tvoid asyncShutdown().finally(() => process.exit(143));\n\t});\n\tprocess.on(\"exit\", () => {\n\t\tfor (const k of liveKernels) k.disposeSync();\n\t});\n}\n"]}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/core/kernel/shared.ts"],"names":[],"mappings":"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","sourcesContent":["import { registerSessionResourceCleanup } from \"@ponythewhite/base-context-ai\";\nimport type { NativeRecoveryResponse } from \"../selective-recovery.js\";\nimport type { KernelBootstrapProgressHandler, KernelPythonSkill } from \"./bootstrap.js\";\nimport type { RestoreResult, SnapshotResult } from \"./state-snapshot.js\";\n\nexport const DEFAULT_MAX_OUTPUT_CHARS = 65536;\nexport const HOST_REQUEST_SHUTDOWN_TIMEOUT_MS = 5000;\nexport const KERNEL_SHUTDOWN_TIMEOUT_MS = 5000;\nexport const DEFAULT_SNAPSHOT_DEBOUNCE_MS = 1500;\nexport const SNAPSHOT_EXECUTION_TIMEOUT_MS = 5000;\nexport const KERNEL_ABORT_GRACE_MS = 1000;\nexport const KERNEL_BUSY_REUSE_WAIT_MS = 5000;\nexport const KERNEL_BUSY_INTERRUPT_INTERVAL_MS = 500;\nexport const MAX_LATE_SENT_AGENT_MESSAGE_HANDLERS = 256;\nconst KERNEL_BUSY_AFTER_INTERRUPT_MESSAGE =\n\t\"The Python kernel is still running the previously interrupted cell. Wait and try again, or kill the kernel to start fresh.\";\n\nexport class KernelBusyAfterInterruptError extends Error {\n\tconstructor() {\n\t\tsuper(KERNEL_BUSY_AFTER_INTERRUPT_MESSAGE);\n\t\tthis.name = \"KernelBusyAfterInterruptError\";\n\t}\n}\n\n/**\n * Handles one typed request from Python code running in the kernel.\n * The returned record is delivered verbatim to the Python caller.\n */\nexport interface HostRequestContext {\n\t/** Actual active tool/cell cancellation; never read from the Python payload. */\n\tsignal?: AbortSignal;\n\t/** A host-reserved share of this cell's aggregate recovery response budget. */\n\tnativeRecovery?: { maxBytes: number };\n}\n\nexport type HostRequestHandler = (\n\tpayload: Record<string, unknown>,\n\tcontext?: HostRequestContext,\n) => Promise<Record<string, unknown>>;\n\n/** Host request handlers keyed by request type (e.g. \"rlm.run\", \"goal.complete\"). */\nexport type HostRequestHandlers = Record<string, HostRequestHandler>;\n\n/** Where and how to persist the kernel's user namespace so it survives resume. */\nexport interface KernelSnapshotConfig {\n\t/** Absolute path for the dill payload. */\n\tpath: string;\n\t/** Absolute path for the JSON manifest written alongside the payload. */\n\tmanifestPath: string;\n\t/** Maximum aggregate snapshot size. Default 256 MiB. */\n\tmaxBytes?: number;\n\t/** Maximum serialized size of one variable. Default 16 MiB. */\n\tmaxVariableBytes?: number;\n\t/** Debounce window for the auto-snapshot after a successful execution. Default 1500 ms. */\n\tdebounceMs?: number;\n}\n\nexport interface KernelManagerOptions {\n\t/** Python interpreter with the kernel runtime available. Defaults to the auto-bootstrapped kernel. */\n\tpython?: string;\n\tcwd?: string;\n\tenv?: Record<string, string>;\n\tsessionId?: string;\n\thostHandlers?: HostRequestHandlers;\n\tpythonSkills?: readonly KernelPythonSkill[];\n\t/** Persist/revive the user namespace across kernel restarts and session resume. */\n\tsnapshot?: KernelSnapshotConfig;\n\t/** Runtime bootstrap re-run on a protocol-repaired kernel so live handles (rlm, bash, skills) exist again. */\n\tbootstrapCode?: string;\n\t/** File receiving the kernel process's stderr, rotated once at each spawn. */\n\tstderrLogPath?: string;\n}\n\nexport interface KernelStartOptions {\n\tonBootstrapProgress?: KernelBootstrapProgressHandler;\n\tsignal?: AbortSignal;\n}\n\nexport interface ExecuteOptions {\n\t/** Only a finalized ipython tool call can retain recovery output; not bootstrap/state cells. */\n\tnativeRecovery?: boolean;\n\t/** @internal Host-only closure captured by the admitted owned executor; never sent to Python. */\n\trunNativeRecovery?: <T>(read: () => Promise<T>) => Promise<T>;\n\t/** Aborting interrupts the kernel out-of-band. */\n\tsignal?: AbortSignal;\n\tonStream?: (chunk: string, name: \"stdout\" | \"stderr\") => void;\n\tonLateSentAgentMessage?: (message: KernelSentAgentMessage) => void;\n\t/** Cap stdout / stderr / result at this many characters. Default 65536. */\n\tmaxOutputChars?: number;\n\t/** Synthetic host cell (snapshot/restore/list); excluded from lastCellCode attribution. */\n\tinternal?: boolean;\n\t/** The protocol repair's own restore; exempt from waiting on the repair it belongs to. */\n\tprotocolRepair?: boolean;\n}\n\n/** MIME tag the `edit` skill emits diff payloads under. */\nexport const DIFF_DISPLAY_MIME = \"application/vnd.prime-agent.diff+json\";\n\n/** MIME tag the `attach-image` skill emits media payloads under. */\nexport const ATTACHMENT_DISPLAY_MIME = \"application/vnd.prime-agent.attachment+json\";\n\n/** MIME tag the `agent-message` skill emits after sending a message. */\nexport const AGENT_MESSAGE_DISPLAY_MIME = \"application/vnd.prime-agent.agent-message+json\";\n\n/**\n * Hard ceiling on a single attachment's base64 payload, a defensive guard\n * against a runaway direct display emit. The `attach-image` skill caps\n * its own images well under this (see `_MAX_IMAGE_BYTES`), so a skill-produced\n * attachment is never dropped here — only a non-skill emit can hit this.\n */\nexport const MAX_ATTACHMENT_DATA_CHARS = 10_000_000;\n\n/** One file edit, captured from a {@link DIFF_DISPLAY_MIME} display payload. */\nexport interface KernelDiffDisplay {\n\tpath: string;\n\toldStr: string;\n\tnewStr: string;\n\t/** 1-based line where `oldStr` begins in the file, for absolute line numbers. */\n\tstartLine?: number;\n}\n\n/** One media attachment, captured from an {@link ATTACHMENT_DISPLAY_MIME} display payload. */\nexport interface KernelAttachment {\n\tmimeType: string;\n\t/** base64-encoded bytes. */\n\tdata: string;\n\t/** Source path, surfaced to the TUI renderer. */\n\tpath?: string;\n}\n\nexport interface KernelSentAgentMessage {\n\tid: string;\n\tmessage: string;\n\tdeliveryStatus: \"delivered\" | \"queued\";\n\treceiverRole?: \"parent\" | \"sibling\" | \"child\";\n\ttarget: {\n\t\tactiveSessionId: string;\n\t\tsessionId: string;\n\t\tsessionName?: string;\n\t};\n}\n\nexport interface ExecuteResult {\n\t/** Whether the finalized textual output was captured without host truncation or interruption. */\n\toutputComplete?: boolean;\n\t/** Host-selected public data transferred once to the normal finalized ipython result. */\n\tnativeRecoveries?: NativeRecoveryResponse[];\n\tstdout: string;\n\tstderr: string;\n\t/** Text of the cell's trailing expression value, if the cell produced one. */\n\tresult?: string;\n\t/** Diffs emitted via display events, in order. */\n\tdiffs?: KernelDiffDisplay[];\n\t/** Media attachments emitted via display events, in order. */\n\tattachments?: KernelAttachment[];\n\t/** Agent messages sent from this cell, in order. */\n\tsentAgentMessages?: KernelSentAgentMessage[];\n\t/** Output that arrived without this cell's id (user threads, other cells' leftovers, raw fd writes). */\n\tbackgroundOutput?: string;\n\tstatus: \"ok\" | \"error\" | \"aborted\";\n\terror?: { ename: string; evalue: string; traceback: string[] };\n\tdurationMs: number;\n}\n\n/** Parse a {@link DIFF_DISPLAY_MIME} payload, tolerating malformed input. */\nexport function parseDiffDisplay(payload: unknown): KernelDiffDisplay | undefined {\n\tif (!isRecord(payload)) {\n\t\treturn undefined;\n\t}\n\tconst { path, old_str: oldStr, new_str: newStr, start_line: startLine } = payload;\n\tif (typeof path !== \"string\" || typeof oldStr !== \"string\" || typeof newStr !== \"string\") {\n\t\treturn undefined;\n\t}\n\treturn { path, oldStr, newStr, startLine: typeof startLine === \"number\" ? startLine : undefined };\n}\n\n/**\n * Parse an {@link ATTACHMENT_DISPLAY_MIME} payload. Malformed payloads are\n * tolerantly ignored (`undefined`); a well-formed payload exceeding\n * {@link MAX_ATTACHMENT_DATA_CHARS} is reported as `\"oversized\"` so the caller\n * can fail the cell loudly rather than silently dropping the image.\n */\nexport function parseAttachmentDisplay(payload: unknown): KernelAttachment | \"oversized\" | undefined {\n\tif (!isRecord(payload)) {\n\t\treturn undefined;\n\t}\n\tconst { mime_type: mimeType, data, path } = payload;\n\tif (typeof mimeType !== \"string\" || typeof data !== \"string\") {\n\t\treturn undefined;\n\t}\n\tif (data.length > MAX_ATTACHMENT_DATA_CHARS) {\n\t\treturn \"oversized\";\n\t}\n\treturn { mimeType, data, path: typeof path === \"string\" ? path : undefined };\n}\n\nexport function parseSentAgentMessage(payload: unknown): KernelSentAgentMessage | undefined {\n\tif (!isRecord(payload) || !isRecord(payload.target)) {\n\t\treturn undefined;\n\t}\n\tconst { id, message, deliveryStatus, receiverRole, target } = payload;\n\tconst { activeSessionId, sessionId, sessionName } = target;\n\tif (\n\t\ttypeof id !== \"string\" ||\n\t\ttypeof message !== \"string\" ||\n\t\t(deliveryStatus !== \"delivered\" && deliveryStatus !== \"queued\") ||\n\t\ttypeof activeSessionId !== \"string\" ||\n\t\ttypeof sessionId !== \"string\"\n\t) {\n\t\treturn undefined;\n\t}\n\treturn {\n\t\tid,\n\t\tmessage,\n\t\tdeliveryStatus,\n\t\t...(receiverRole === \"parent\" || receiverRole === \"sibling\" || receiverRole === \"child\" ? { receiverRole } : {}),\n\t\ttarget: {\n\t\t\tactiveSessionId,\n\t\t\tsessionId,\n\t\t\t...(typeof sessionName === \"string\" ? { sessionName } : {}),\n\t\t},\n\t};\n}\n\nexport function createKernelStartupAbortError(): Error {\n\treturn new Error(\"Kernel startup aborted\");\n}\n\nexport function raceStartupWithAbort<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T> {\n\tif (!signal) {\n\t\treturn promise;\n\t}\n\tif (signal.aborted) {\n\t\treturn Promise.reject(createKernelStartupAbortError());\n\t}\n\treturn new Promise<T>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tconst cleanup = () => signal.removeEventListener(\"abort\", abort);\n\t\tconst abort = () => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tcleanup();\n\t\t\treject(createKernelStartupAbortError());\n\t\t};\n\t\tsignal.addEventListener(\"abort\", abort, { once: true });\n\t\tpromise.then(\n\t\t\t(value) => {\n\t\t\t\tif (settled) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsettled = true;\n\t\t\t\tcleanup();\n\t\t\t\tresolve(value);\n\t\t\t},\n\t\t\t(error: unknown) => {\n\t\t\t\tif (settled) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsettled = true;\n\t\t\t\tcleanup();\n\t\t\t\treject(error);\n\t\t\t},\n\t\t);\n\t});\n}\n\nexport interface Deferred<T> {\n\tpromise: Promise<T>;\n\tresolve: (value: T) => void;\n\treject: (error: Error) => void;\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function errorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nexport function createDeferred<T>(): Deferred<T> {\n\tlet resolve!: (value: T) => void;\n\tlet reject!: (error: Error) => void;\n\tconst promise = new Promise<T>((promiseResolve, promiseReject) => {\n\t\tresolve = promiseResolve;\n\t\treject = promiseReject;\n\t});\n\treturn { promise, resolve, reject };\n}\n\nexport interface KernelShutdownOptions {\n\tsnapshot?: boolean;\n\tdrainHostRequests?: boolean;\n}\n\n/** A bounded owned lifecycle observation, not a namespace, restore, or live-health assertion. */\nexport interface KernelLifecycleState {\n\treadonly source: \"repl-manager\" | \"ipython-provisioner\" | \"unobserved\";\n\treadonly owner: string | null;\n\treadonly generation: number | null;\n\treadonly state: \"idle\" | \"starting\" | \"running\" | \"shutdown\" | \"provisioning\" | \"disposed\" | \"unobserved\";\n}\n\nexport interface CapturedKernelLifecycle {\n\treadonly snapshot: Readonly<KernelLifecycleState>;\n\t/** Checks the original observation; it never probes or substitutes a newer snapshot. */\n\tisCurrent(): boolean;\n}\n\n/** Public surface every kernel client exposes to the provisioner and session layer. */\nexport interface KernelClient {\n\treadonly ownerSessionId: string | undefined;\n\treadonly isRunning: boolean;\n\tstart(options?: KernelStartOptions): Promise<void>;\n\texecute(code: string, opts?: ExecuteOptions): Promise<ExecuteResult>;\n\tshutdown(opts?: KernelShutdownOptions): Promise<boolean>;\n\trestart(): Promise<void>;\n\tkill(): Promise<void>;\n\tdisposeSync(): void;\n\tsnapshotState(): Promise<SnapshotResult | null>;\n\tpruneOversizedVariables(): Promise<SnapshotResult | null>;\n\trestoreState(): Promise<RestoreResult | null>;\n\tlistNamespaceNames(signal?: AbortSignal): Promise<string[] | null>;\n}\n\n// One registry serves every client kind; two parallel registries would\n// double-install process signal handlers.\nexport const liveKernels = new Set<KernelClient>();\nlet signalHandlersInstalled = false;\n\nregisterSessionResourceCleanup((sessionId) => {\n\tfor (const k of liveKernels) {\n\t\tif (!sessionId || k.ownerSessionId === sessionId) {\n\t\t\tvoid k.shutdown({ snapshot: true, drainHostRequests: true });\n\t\t}\n\t}\n});\n\nexport function installSignalHandlersOnce(): void {\n\tif (signalHandlersInstalled) return;\n\tsignalHandlersInstalled = true;\n\n\tconst asyncShutdown = async (): Promise<void> => {\n\t\t// These paths can await, so flush the namespace snapshot before tearing down.\n\t\tawait Promise.allSettled([...liveKernels].map((k) => k.shutdown({ snapshot: true })));\n\t};\n\n\t// `beforeExit` and signal handlers can await async cleanup. `exit`\n\t// can only do sync work (Node won't run pending microtasks past it),\n\t// so it falls back to `disposeSync()` which kills the child synchronously.\n\tprocess.on(\"beforeExit\", () => {\n\t\tvoid asyncShutdown();\n\t});\n\tprocess.on(\"SIGINT\", () => {\n\t\tvoid asyncShutdown().finally(() => process.exit(130));\n\t});\n\tprocess.on(\"SIGTERM\", () => {\n\t\tvoid asyncShutdown().finally(() => process.exit(143));\n\t});\n\tprocess.on(\"exit\", () => {\n\t\tfor (const k of liveKernels) k.disposeSync();\n\t});\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/core/kernel/shared.ts"],"names":[],"mappings":"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","sourcesContent":["import { registerSessionResourceCleanup } from \"@ponythewhite/base-context-ai\";\nimport type { NativeRecoveryResponse } from \"../selective-recovery.js\";\nimport type { KernelBootstrapProgressHandler, KernelPythonSkill } from \"./bootstrap.js\";\nimport type { RestoreResult, SnapshotResult } from \"./state-snapshot.js\";\n\nexport const DEFAULT_MAX_OUTPUT_CHARS = 65536;\nexport const HOST_REQUEST_SHUTDOWN_TIMEOUT_MS = 5000;\nexport const KERNEL_SHUTDOWN_TIMEOUT_MS = 5000;\nexport const DEFAULT_SNAPSHOT_DEBOUNCE_MS = 1500;\nexport const SNAPSHOT_EXECUTION_TIMEOUT_MS = 5000;\nexport const KERNEL_ABORT_GRACE_MS = 1000;\nexport const KERNEL_BUSY_REUSE_WAIT_MS = 5000;\nexport const KERNEL_BUSY_INTERRUPT_INTERVAL_MS = 500;\nexport const MAX_LATE_SENT_AGENT_MESSAGE_HANDLERS = 256;\nconst KERNEL_BUSY_AFTER_INTERRUPT_MESSAGE =\n\t\"The Python kernel is still running the previously interrupted cell. Wait and try again, or kill the kernel to start fresh.\";\n\nexport class KernelBusyAfterInterruptError extends Error {\n\tconstructor() {\n\t\tsuper(KERNEL_BUSY_AFTER_INTERRUPT_MESSAGE);\n\t\tthis.name = \"KernelBusyAfterInterruptError\";\n\t}\n}\n\n/**\n * Handles one typed request from Python code running in the kernel.\n * The returned record is delivered verbatim to the Python caller.\n */\nexport interface HostRequestContext {\n\t/** Actual active tool/cell cancellation; never read from the Python payload. */\n\tsignal?: AbortSignal;\n\t/** A host-reserved share of this cell's aggregate recovery response budget. */\n\tnativeRecovery?: { maxBytes: number };\n}\n\nexport type HostRequestHandler = (\n\tpayload: Record<string, unknown>,\n\tcontext?: HostRequestContext,\n) => Promise<Record<string, unknown>>;\n\n/** Host request handlers keyed by request type (e.g. \"rlm.run\", \"goal.complete\"). */\nexport type HostRequestHandlers = Record<string, HostRequestHandler>;\n\n/** Where and how to persist the kernel's user namespace so it survives resume. */\nexport interface KernelSnapshotConfig {\n\t/** Absolute path for the dill payload. */\n\tpath: string;\n\t/** Absolute path for the JSON manifest written alongside the payload. */\n\tmanifestPath: string;\n\t/** Maximum aggregate snapshot size. Default 256 MiB. */\n\tmaxBytes?: number;\n\t/** Maximum serialized size of one variable. Default 16 MiB. */\n\tmaxVariableBytes?: number;\n\t/** Debounce window for the auto-snapshot after a successful execution. Default 1500 ms. */\n\tdebounceMs?: number;\n}\n\nexport interface KernelManagerOptions {\n\t/** Python interpreter with the kernel runtime available. Defaults to the auto-bootstrapped kernel. */\n\tpython?: string;\n\tcwd?: string;\n\tenv?: Record<string, string>;\n\tsessionId?: string;\n\thostHandlers?: HostRequestHandlers;\n\tpythonSkills?: readonly KernelPythonSkill[];\n\t/** Persist/revive the user namespace across kernel restarts and session resume. */\n\tsnapshot?: KernelSnapshotConfig;\n\t/** Runtime bootstrap re-run on a protocol-repaired kernel so live handles (rlm, bash, skills) exist again. */\n\tbootstrapCode?: string;\n\t/** File receiving the kernel process's stderr, rotated once at each spawn. */\n\tstderrLogPath?: string;\n}\n\nexport interface KernelStartOptions {\n\tonBootstrapProgress?: KernelBootstrapProgressHandler;\n\tsignal?: AbortSignal;\n}\n\nexport interface ExecuteOptions {\n\t/** Only a finalized ipython tool call can retain recovery output; not bootstrap/state cells. */\n\tnativeRecovery?: boolean;\n\t/** @internal Host-only closure captured by the admitted owned executor; never sent to Python. */\n\trunNativeRecovery?: <T>(read: () => Promise<T>) => Promise<T>;\n\t/** Aborting interrupts the kernel out-of-band. */\n\tsignal?: AbortSignal;\n\tonStream?: (chunk: string, name: \"stdout\" | \"stderr\") => void;\n\tonLateSentAgentMessage?: (message: KernelSentAgentMessage) => void;\n\t/** Cap stdout / stderr / result at this many characters. Default 65536. */\n\tmaxOutputChars?: number;\n\t/** Synthetic host cell (snapshot/restore/list); excluded from lastCellCode attribution. */\n\tinternal?: boolean;\n\t/** The protocol repair's own restore; exempt from waiting on the repair it belongs to. */\n\tprotocolRepair?: boolean;\n}\n\n/** MIME tag the `edit` skill emits diff payloads under. */\nexport const DIFF_DISPLAY_MIME = \"application/vnd.prime-agent.diff+json\";\n\n/** MIME tag the `attach-image` skill emits media payloads under. */\nexport const ATTACHMENT_DISPLAY_MIME = \"application/vnd.prime-agent.attachment+json\";\n\n/** MIME tag the `agent-message` skill emits after sending a message. */\nexport const AGENT_MESSAGE_DISPLAY_MIME = \"application/vnd.prime-agent.agent-message+json\";\n\n/**\n * Hard ceiling on a single attachment's base64 payload, a defensive guard\n * against a runaway direct display emit. The `attach-image` skill caps\n * its own images well under this (see `_MAX_IMAGE_BYTES`), so a skill-produced\n * attachment is never dropped here — only a non-skill emit can hit this.\n */\nexport const MAX_ATTACHMENT_DATA_CHARS = 10_000_000;\n\n/** One file edit, captured from a {@link DIFF_DISPLAY_MIME} display payload. */\nexport interface KernelDiffDisplay {\n\tpath: string;\n\toldStr: string;\n\tnewStr: string;\n\t/** 1-based line where `oldStr` begins in the file, for absolute line numbers. */\n\tstartLine?: number;\n}\n\n/** One media attachment, captured from an {@link ATTACHMENT_DISPLAY_MIME} display payload. */\nexport interface KernelAttachment {\n\tmimeType: string;\n\t/** base64-encoded bytes. */\n\tdata: string;\n\t/** Source path, surfaced to the TUI renderer. */\n\tpath?: string;\n}\n\nexport interface KernelSentAgentMessage {\n\tid: string;\n\tmessage: string;\n\tdeliveryStatus: \"delivered\" | \"queued\";\n\treceiverRole?: \"parent\" | \"sibling\" | \"child\";\n\ttarget: {\n\t\tactiveSessionId: string;\n\t\tsessionId: string;\n\t\tsessionName?: string;\n\t};\n}\n\nexport interface ExecuteResult {\n\t/** Host-selected public data transferred once to the normal finalized ipython result. */\n\tnativeRecoveries?: NativeRecoveryResponse[];\n\tstdout: string;\n\tstderr: string;\n\t/** Text of the cell's trailing expression value, if the cell produced one. */\n\tresult?: string;\n\t/** Diffs emitted via display events, in order. */\n\tdiffs?: KernelDiffDisplay[];\n\t/** Media attachments emitted via display events, in order. */\n\tattachments?: KernelAttachment[];\n\t/** Agent messages sent from this cell, in order. */\n\tsentAgentMessages?: KernelSentAgentMessage[];\n\t/** Output that arrived without this cell's id (user threads, other cells' leftovers, raw fd writes). */\n\tbackgroundOutput?: string;\n\tstatus: \"ok\" | \"error\" | \"aborted\";\n\terror?: { ename: string; evalue: string; traceback: string[] };\n\tdurationMs: number;\n}\n\n/** Parse a {@link DIFF_DISPLAY_MIME} payload, tolerating malformed input. */\nexport function parseDiffDisplay(payload: unknown): KernelDiffDisplay | undefined {\n\tif (!isRecord(payload)) {\n\t\treturn undefined;\n\t}\n\tconst { path, old_str: oldStr, new_str: newStr, start_line: startLine } = payload;\n\tif (typeof path !== \"string\" || typeof oldStr !== \"string\" || typeof newStr !== \"string\") {\n\t\treturn undefined;\n\t}\n\treturn { path, oldStr, newStr, startLine: typeof startLine === \"number\" ? startLine : undefined };\n}\n\n/**\n * Parse an {@link ATTACHMENT_DISPLAY_MIME} payload. Malformed payloads are\n * tolerantly ignored (`undefined`); a well-formed payload exceeding\n * {@link MAX_ATTACHMENT_DATA_CHARS} is reported as `\"oversized\"` so the caller\n * can fail the cell loudly rather than silently dropping the image.\n */\nexport function parseAttachmentDisplay(payload: unknown): KernelAttachment | \"oversized\" | undefined {\n\tif (!isRecord(payload)) {\n\t\treturn undefined;\n\t}\n\tconst { mime_type: mimeType, data, path } = payload;\n\tif (typeof mimeType !== \"string\" || typeof data !== \"string\") {\n\t\treturn undefined;\n\t}\n\tif (data.length > MAX_ATTACHMENT_DATA_CHARS) {\n\t\treturn \"oversized\";\n\t}\n\treturn { mimeType, data, path: typeof path === \"string\" ? path : undefined };\n}\n\nexport function parseSentAgentMessage(payload: unknown): KernelSentAgentMessage | undefined {\n\tif (!isRecord(payload) || !isRecord(payload.target)) {\n\t\treturn undefined;\n\t}\n\tconst { id, message, deliveryStatus, receiverRole, target } = payload;\n\tconst { activeSessionId, sessionId, sessionName } = target;\n\tif (\n\t\ttypeof id !== \"string\" ||\n\t\ttypeof message !== \"string\" ||\n\t\t(deliveryStatus !== \"delivered\" && deliveryStatus !== \"queued\") ||\n\t\ttypeof activeSessionId !== \"string\" ||\n\t\ttypeof sessionId !== \"string\"\n\t) {\n\t\treturn undefined;\n\t}\n\treturn {\n\t\tid,\n\t\tmessage,\n\t\tdeliveryStatus,\n\t\t...(receiverRole === \"parent\" || receiverRole === \"sibling\" || receiverRole === \"child\" ? { receiverRole } : {}),\n\t\ttarget: {\n\t\t\tactiveSessionId,\n\t\t\tsessionId,\n\t\t\t...(typeof sessionName === \"string\" ? { sessionName } : {}),\n\t\t},\n\t};\n}\n\nexport function createKernelStartupAbortError(): Error {\n\treturn new Error(\"Kernel startup aborted\");\n}\n\nexport function raceStartupWithAbort<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T> {\n\tif (!signal) {\n\t\treturn promise;\n\t}\n\tif (signal.aborted) {\n\t\treturn Promise.reject(createKernelStartupAbortError());\n\t}\n\treturn new Promise<T>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tconst cleanup = () => signal.removeEventListener(\"abort\", abort);\n\t\tconst abort = () => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tcleanup();\n\t\t\treject(createKernelStartupAbortError());\n\t\t};\n\t\tsignal.addEventListener(\"abort\", abort, { once: true });\n\t\tpromise.then(\n\t\t\t(value) => {\n\t\t\t\tif (settled) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsettled = true;\n\t\t\t\tcleanup();\n\t\t\t\tresolve(value);\n\t\t\t},\n\t\t\t(error: unknown) => {\n\t\t\t\tif (settled) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsettled = true;\n\t\t\t\tcleanup();\n\t\t\t\treject(error);\n\t\t\t},\n\t\t);\n\t});\n}\n\nexport interface Deferred<T> {\n\tpromise: Promise<T>;\n\tresolve: (value: T) => void;\n\treject: (error: Error) => void;\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function errorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nexport function createDeferred<T>(): Deferred<T> {\n\tlet resolve!: (value: T) => void;\n\tlet reject!: (error: Error) => void;\n\tconst promise = new Promise<T>((promiseResolve, promiseReject) => {\n\t\tresolve = promiseResolve;\n\t\treject = promiseReject;\n\t});\n\treturn { promise, resolve, reject };\n}\n\nexport interface KernelShutdownOptions {\n\tsnapshot?: boolean;\n\tdrainHostRequests?: boolean;\n}\n\n/** A bounded owned lifecycle observation, not a namespace, restore, or live-health assertion. */\nexport interface KernelLifecycleState {\n\treadonly source: \"repl-manager\" | \"ipython-provisioner\" | \"unobserved\";\n\treadonly owner: string | null;\n\treadonly generation: number | null;\n\treadonly state: \"idle\" | \"starting\" | \"running\" | \"shutdown\" | \"provisioning\" | \"disposed\" | \"unobserved\";\n}\n\nexport interface CapturedKernelLifecycle {\n\treadonly snapshot: Readonly<KernelLifecycleState>;\n\t/** Checks the original observation; it never probes or substitutes a newer snapshot. */\n\tisCurrent(): boolean;\n}\n\n/** Public surface every kernel client exposes to the provisioner and session layer. */\nexport interface KernelClient {\n\treadonly ownerSessionId: string | undefined;\n\treadonly isRunning: boolean;\n\tstart(options?: KernelStartOptions): Promise<void>;\n\texecute(code: string, opts?: ExecuteOptions): Promise<ExecuteResult>;\n\tshutdown(opts?: KernelShutdownOptions): Promise<boolean>;\n\trestart(): Promise<void>;\n\tkill(): Promise<void>;\n\tdisposeSync(): void;\n\tsnapshotState(): Promise<SnapshotResult | null>;\n\tpruneOversizedVariables(): Promise<SnapshotResult | null>;\n\trestoreState(): Promise<RestoreResult | null>;\n\tlistNamespaceNames(signal?: AbortSignal): Promise<string[] | null>;\n}\n\n// One registry serves every client kind; two parallel registries would\n// double-install process signal handlers.\nexport const liveKernels = new Set<KernelClient>();\nlet signalHandlersInstalled = false;\n\nregisterSessionResourceCleanup((sessionId) => {\n\tfor (const k of liveKernels) {\n\t\tif (!sessionId || k.ownerSessionId === sessionId) {\n\t\t\tvoid k.shutdown({ snapshot: true, drainHostRequests: true });\n\t\t}\n\t}\n});\n\nexport function installSignalHandlersOnce(): void {\n\tif (signalHandlersInstalled) return;\n\tsignalHandlersInstalled = true;\n\n\tconst asyncShutdown = async (): Promise<void> => {\n\t\t// These paths can await, so flush the namespace snapshot before tearing down.\n\t\tawait Promise.allSettled([...liveKernels].map((k) => k.shutdown({ snapshot: true })));\n\t};\n\n\t// `beforeExit` and signal handlers can await async cleanup. `exit`\n\t// can only do sync work (Node won't run pending microtasks past it),\n\t// so it falls back to `disposeSync()` which kills the child synchronously.\n\tprocess.on(\"beforeExit\", () => {\n\t\tvoid asyncShutdown();\n\t});\n\tprocess.on(\"SIGINT\", () => {\n\t\tvoid asyncShutdown().finally(() => process.exit(130));\n\t});\n\tprocess.on(\"SIGTERM\", () => {\n\t\tvoid asyncShutdown().finally(() => process.exit(143));\n\t});\n\tprocess.on(\"exit\", () => {\n\t\tfor (const k of liveKernels) k.disposeSync();\n\t});\n}\n"]}
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/core/kernel/shared.ts"],"names":[],"mappings":"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","sourcesContent":["import { registerSessionResourceCleanup } from \"@ponythewhite/base-context-ai\";\nimport type { NativeRecoveryResponse } from \"../selective-recovery.js\";\nimport type { KernelBootstrapProgressHandler, KernelPythonSkill } from \"./bootstrap.js\";\nimport type { RestoreResult, SnapshotResult } from \"./state-snapshot.js\";\n\nexport const DEFAULT_MAX_OUTPUT_CHARS = 65536;\nexport const HOST_REQUEST_SHUTDOWN_TIMEOUT_MS = 5000;\nexport const KERNEL_SHUTDOWN_TIMEOUT_MS = 5000;\nexport const DEFAULT_SNAPSHOT_DEBOUNCE_MS = 1500;\nexport const SNAPSHOT_EXECUTION_TIMEOUT_MS = 5000;\nexport const KERNEL_ABORT_GRACE_MS = 1000;\nexport const KERNEL_BUSY_REUSE_WAIT_MS = 5000;\nexport const KERNEL_BUSY_INTERRUPT_INTERVAL_MS = 500;\nexport const MAX_LATE_SENT_AGENT_MESSAGE_HANDLERS = 256;\nconst KERNEL_BUSY_AFTER_INTERRUPT_MESSAGE =\n\t\"The Python kernel is still running the previously interrupted cell. Wait and try again, or kill the kernel to start fresh.\";\n\nexport class KernelBusyAfterInterruptError extends Error {\n\tconstructor() {\n\t\tsuper(KERNEL_BUSY_AFTER_INTERRUPT_MESSAGE);\n\t\tthis.name = \"KernelBusyAfterInterruptError\";\n\t}\n}\n\n/**\n * Handles one typed request from Python code running in the kernel.\n * The returned record is delivered verbatim to the Python caller.\n */\nexport interface HostRequestContext {\n\t/** Actual active tool/cell cancellation; never read from the Python payload. */\n\tsignal?: AbortSignal;\n\t/** A host-reserved share of this cell's aggregate recovery response budget. */\n\tnativeRecovery?: { maxBytes: number };\n}\n\nexport type HostRequestHandler = (\n\tpayload: Record<string, unknown>,\n\tcontext?: HostRequestContext,\n) => Promise<Record<string, unknown>>;\n\n/** Host request handlers keyed by request type (e.g. \"rlm.run\", \"goal.complete\"). */\nexport type HostRequestHandlers = Record<string, HostRequestHandler>;\n\n/** Where and how to persist the kernel's user namespace so it survives resume. */\nexport interface KernelSnapshotConfig {\n\t/** Absolute path for the dill payload. */\n\tpath: string;\n\t/** Absolute path for the JSON manifest written alongside the payload. */\n\tmanifestPath: string;\n\t/** Maximum aggregate snapshot size. Default 256 MiB. */\n\tmaxBytes?: number;\n\t/** Maximum serialized size of one variable. Default 16 MiB. */\n\tmaxVariableBytes?: number;\n\t/** Debounce window for the auto-snapshot after a successful execution. Default 1500 ms. */\n\tdebounceMs?: number;\n}\n\nexport interface KernelManagerOptions {\n\t/** Python interpreter with the kernel runtime available. Defaults to the auto-bootstrapped kernel. */\n\tpython?: string;\n\tcwd?: string;\n\tenv?: Record<string, string>;\n\tsessionId?: string;\n\thostHandlers?: HostRequestHandlers;\n\tpythonSkills?: readonly KernelPythonSkill[];\n\t/** Persist/revive the user namespace across kernel restarts and session resume. */\n\tsnapshot?: KernelSnapshotConfig;\n\t/** Runtime bootstrap re-run on a protocol-repaired kernel so live handles (rlm, bash, skills) exist again. */\n\tbootstrapCode?: string;\n\t/** File receiving the kernel process's stderr, rotated once at each spawn. */\n\tstderrLogPath?: string;\n}\n\nexport interface KernelStartOptions {\n\tonBootstrapProgress?: KernelBootstrapProgressHandler;\n\tsignal?: AbortSignal;\n}\n\nexport interface ExecuteOptions {\n\t/** Only a finalized ipython tool call can retain recovery output; not bootstrap/state cells. */\n\tnativeRecovery?: boolean;\n\t/** @internal Host-only closure captured by the admitted owned executor; never sent to Python. */\n\trunNativeRecovery?: <T>(read: () => Promise<T>) => Promise<T>;\n\t/** Aborting interrupts the kernel out-of-band. */\n\tsignal?: AbortSignal;\n\tonStream?: (chunk: string, name: \"stdout\" | \"stderr\") => void;\n\tonLateSentAgentMessage?: (message: KernelSentAgentMessage) => void;\n\t/** Cap stdout / stderr / result at this many characters. Default 65536. */\n\tmaxOutputChars?: number;\n\t/** Synthetic host cell (snapshot/restore/list); excluded from lastCellCode attribution. */\n\tinternal?: boolean;\n\t/** The protocol repair's own restore; exempt from waiting on the repair it belongs to. */\n\tprotocolRepair?: boolean;\n}\n\n/** MIME tag the `edit` skill emits diff payloads under. */\nexport const DIFF_DISPLAY_MIME = \"application/vnd.prime-agent.diff+json\";\n\n/** MIME tag the `attach-image` skill emits media payloads under. */\nexport const ATTACHMENT_DISPLAY_MIME = \"application/vnd.prime-agent.attachment+json\";\n\n/** MIME tag the `agent-message` skill emits after sending a message. */\nexport const AGENT_MESSAGE_DISPLAY_MIME = \"application/vnd.prime-agent.agent-message+json\";\n\n/**\n * Hard ceiling on a single attachment's base64 payload, a defensive guard\n * against a runaway direct display emit. The `attach-image` skill caps\n * its own images well under this (see `_MAX_IMAGE_BYTES`), so a skill-produced\n * attachment is never dropped here — only a non-skill emit can hit this.\n */\nexport const MAX_ATTACHMENT_DATA_CHARS = 10_000_000;\n\n/** One file edit, captured from a {@link DIFF_DISPLAY_MIME} display payload. */\nexport interface KernelDiffDisplay {\n\tpath: string;\n\toldStr: string;\n\tnewStr: string;\n\t/** 1-based line where `oldStr` begins in the file, for absolute line numbers. */\n\tstartLine?: number;\n}\n\n/** One media attachment, captured from an {@link ATTACHMENT_DISPLAY_MIME} display payload. */\nexport interface KernelAttachment {\n\tmimeType: string;\n\t/** base64-encoded bytes. */\n\tdata: string;\n\t/** Source path, surfaced to the TUI renderer. */\n\tpath?: string;\n}\n\nexport interface KernelSentAgentMessage {\n\tid: string;\n\tmessage: string;\n\tdeliveryStatus: \"delivered\" | \"queued\";\n\treceiverRole?: \"parent\" | \"sibling\" | \"child\";\n\ttarget: {\n\t\tactiveSessionId: string;\n\t\tsessionId: string;\n\t\tsessionName?: string;\n\t};\n}\n\nexport interface ExecuteResult {\n\t/** Whether the finalized textual output was captured without host truncation or interruption. */\n\toutputComplete?: boolean;\n\t/** Host-selected public data transferred once to the normal finalized ipython result. */\n\tnativeRecoveries?: NativeRecoveryResponse[];\n\tstdout: string;\n\tstderr: string;\n\t/** Text of the cell's trailing expression value, if the cell produced one. */\n\tresult?: string;\n\t/** Diffs emitted via display events, in order. */\n\tdiffs?: KernelDiffDisplay[];\n\t/** Media attachments emitted via display events, in order. */\n\tattachments?: KernelAttachment[];\n\t/** Agent messages sent from this cell, in order. */\n\tsentAgentMessages?: KernelSentAgentMessage[];\n\t/** Output that arrived without this cell's id (user threads, other cells' leftovers, raw fd writes). */\n\tbackgroundOutput?: string;\n\tstatus: \"ok\" | \"error\" | \"aborted\";\n\terror?: { ename: string; evalue: string; traceback: string[] };\n\tdurationMs: number;\n}\n\n/** Parse a {@link DIFF_DISPLAY_MIME} payload, tolerating malformed input. */\nexport function parseDiffDisplay(payload: unknown): KernelDiffDisplay | undefined {\n\tif (!isRecord(payload)) {\n\t\treturn undefined;\n\t}\n\tconst { path, old_str: oldStr, new_str: newStr, start_line: startLine } = payload;\n\tif (typeof path !== \"string\" || typeof oldStr !== \"string\" || typeof newStr !== \"string\") {\n\t\treturn undefined;\n\t}\n\treturn { path, oldStr, newStr, startLine: typeof startLine === \"number\" ? startLine : undefined };\n}\n\n/**\n * Parse an {@link ATTACHMENT_DISPLAY_MIME} payload. Malformed payloads are\n * tolerantly ignored (`undefined`); a well-formed payload exceeding\n * {@link MAX_ATTACHMENT_DATA_CHARS} is reported as `\"oversized\"` so the caller\n * can fail the cell loudly rather than silently dropping the image.\n */\nexport function parseAttachmentDisplay(payload: unknown): KernelAttachment | \"oversized\" | undefined {\n\tif (!isRecord(payload)) {\n\t\treturn undefined;\n\t}\n\tconst { mime_type: mimeType, data, path } = payload;\n\tif (typeof mimeType !== \"string\" || typeof data !== \"string\") {\n\t\treturn undefined;\n\t}\n\tif (data.length > MAX_ATTACHMENT_DATA_CHARS) {\n\t\treturn \"oversized\";\n\t}\n\treturn { mimeType, data, path: typeof path === \"string\" ? path : undefined };\n}\n\nexport function parseSentAgentMessage(payload: unknown): KernelSentAgentMessage | undefined {\n\tif (!isRecord(payload) || !isRecord(payload.target)) {\n\t\treturn undefined;\n\t}\n\tconst { id, message, deliveryStatus, receiverRole, target } = payload;\n\tconst { activeSessionId, sessionId, sessionName } = target;\n\tif (\n\t\ttypeof id !== \"string\" ||\n\t\ttypeof message !== \"string\" ||\n\t\t(deliveryStatus !== \"delivered\" && deliveryStatus !== \"queued\") ||\n\t\ttypeof activeSessionId !== \"string\" ||\n\t\ttypeof sessionId !== \"string\"\n\t) {\n\t\treturn undefined;\n\t}\n\treturn {\n\t\tid,\n\t\tmessage,\n\t\tdeliveryStatus,\n\t\t...(receiverRole === \"parent\" || receiverRole === \"sibling\" || receiverRole === \"child\" ? { receiverRole } : {}),\n\t\ttarget: {\n\t\t\tactiveSessionId,\n\t\t\tsessionId,\n\t\t\t...(typeof sessionName === \"string\" ? { sessionName } : {}),\n\t\t},\n\t};\n}\n\nexport function createKernelStartupAbortError(): Error {\n\treturn new Error(\"Kernel startup aborted\");\n}\n\nexport function raceStartupWithAbort<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T> {\n\tif (!signal) {\n\t\treturn promise;\n\t}\n\tif (signal.aborted) {\n\t\treturn Promise.reject(createKernelStartupAbortError());\n\t}\n\treturn new Promise<T>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tconst cleanup = () => signal.removeEventListener(\"abort\", abort);\n\t\tconst abort = () => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tcleanup();\n\t\t\treject(createKernelStartupAbortError());\n\t\t};\n\t\tsignal.addEventListener(\"abort\", abort, { once: true });\n\t\tpromise.then(\n\t\t\t(value) => {\n\t\t\t\tif (settled) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsettled = true;\n\t\t\t\tcleanup();\n\t\t\t\tresolve(value);\n\t\t\t},\n\t\t\t(error: unknown) => {\n\t\t\t\tif (settled) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsettled = true;\n\t\t\t\tcleanup();\n\t\t\t\treject(error);\n\t\t\t},\n\t\t);\n\t});\n}\n\nexport interface Deferred<T> {\n\tpromise: Promise<T>;\n\tresolve: (value: T) => void;\n\treject: (error: Error) => void;\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function errorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nexport function createDeferred<T>(): Deferred<T> {\n\tlet resolve!: (value: T) => void;\n\tlet reject!: (error: Error) => void;\n\tconst promise = new Promise<T>((promiseResolve, promiseReject) => {\n\t\tresolve = promiseResolve;\n\t\treject = promiseReject;\n\t});\n\treturn { promise, resolve, reject };\n}\n\nexport interface KernelShutdownOptions {\n\tsnapshot?: boolean;\n\tdrainHostRequests?: boolean;\n}\n\n/** A bounded owned lifecycle observation, not a namespace, restore, or live-health assertion. */\nexport interface KernelLifecycleState {\n\treadonly source: \"repl-manager\" | \"ipython-provisioner\" | \"unobserved\";\n\treadonly owner: string | null;\n\treadonly generation: number | null;\n\treadonly state: \"idle\" | \"starting\" | \"running\" | \"shutdown\" | \"provisioning\" | \"disposed\" | \"unobserved\";\n}\n\nexport interface CapturedKernelLifecycle {\n\treadonly snapshot: Readonly<KernelLifecycleState>;\n\t/** Checks the original observation; it never probes or substitutes a newer snapshot. */\n\tisCurrent(): boolean;\n}\n\n/** Public surface every kernel client exposes to the provisioner and session layer. */\nexport interface KernelClient {\n\treadonly ownerSessionId: string | undefined;\n\treadonly isRunning: boolean;\n\tstart(options?: KernelStartOptions): Promise<void>;\n\texecute(code: string, opts?: ExecuteOptions): Promise<ExecuteResult>;\n\tshutdown(opts?: KernelShutdownOptions): Promise<boolean>;\n\trestart(): Promise<void>;\n\tkill(): Promise<void>;\n\tdisposeSync(): void;\n\tsnapshotState(): Promise<SnapshotResult | null>;\n\tpruneOversizedVariables(): Promise<SnapshotResult | null>;\n\trestoreState(): Promise<RestoreResult | null>;\n\tlistNamespaceNames(signal?: AbortSignal): Promise<string[] | null>;\n}\n\n// One registry serves every client kind; two parallel registries would\n// double-install process signal handlers.\nexport const liveKernels = new Set<KernelClient>();\nlet signalHandlersInstalled = false;\n\nregisterSessionResourceCleanup((sessionId) => {\n\tfor (const k of liveKernels) {\n\t\tif (!sessionId || k.ownerSessionId === sessionId) {\n\t\t\tvoid k.shutdown({ snapshot: true, drainHostRequests: true });\n\t\t}\n\t}\n});\n\nexport function installSignalHandlersOnce(): void {\n\tif (signalHandlersInstalled) return;\n\tsignalHandlersInstalled = true;\n\n\tconst asyncShutdown = async (): Promise<void> => {\n\t\t// These paths can await, so flush the namespace snapshot before tearing down.\n\t\tawait Promise.allSettled([...liveKernels].map((k) => k.shutdown({ snapshot: true })));\n\t};\n\n\t// `beforeExit` and signal handlers can await async cleanup. `exit`\n\t// can only do sync work (Node won't run pending microtasks past it),\n\t// so it falls back to `disposeSync()` which kills the child synchronously.\n\tprocess.on(\"beforeExit\", () => {\n\t\tvoid asyncShutdown();\n\t});\n\tprocess.on(\"SIGINT\", () => {\n\t\tvoid asyncShutdown().finally(() => process.exit(130));\n\t});\n\tprocess.on(\"SIGTERM\", () => {\n\t\tvoid asyncShutdown().finally(() => process.exit(143));\n\t});\n\tprocess.on(\"exit\", () => {\n\t\tfor (const k of liveKernels) k.disposeSync();\n\t});\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/core/messages.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Custom message types and transformers for the coding agent.\n *\n * Extends the base AgentMessage type with coding-agent specific message types,\n * and provides a transformer to convert them to LLM-compatible messages.\n */\n\nimport type { AgentMessage } from \"@ponythewhite/base-context-agent\";\nimport type { ImageContent, Message, TextContent } from \"@ponythewhite/base-context-ai\";\nimport type { AgentCronJob } from \"./cron-jobs.js\";\nimport type { AppliedRefinementEdit, HarnessScope, RefinementResult } from \"./refinement/refinement.js\";\nimport { isSessionSlashCommandName, parseSessionSlashCommand, type SessionSlashCommand } from \"./slash-commands.js\";\n\nexport const COMPACTION_SUMMARY_PREFIX = `The conversation history before this point was compacted into the following summary:\n\n<summary>\n`;\n\nexport const COMPACTION_SUMMARY_SUFFIX = `\n</summary>`;\n\nexport const BRANCH_SUMMARY_PREFIX = `The following is a summary of a branch that this conversation came back from:\n\n<summary>\n`;\n\nexport const BRANCH_SUMMARY_SUFFIX = `</summary>`;\n\nexport const HEARTBEAT_PROMPT_CUSTOM_TYPE = \"heartbeat_prompt\";\nexport const HEARTBEAT_PROMPT_PREVIEW_LABEL = \"Heartbeat prompt\";\nexport const IPYTHON_STATE_RESTORED_CUSTOM_TYPE = \"ipython_state_restored\";\nexport const SESSION_SLASH_COMMAND_CUSTOM_TYPE = \"session_slash_command\";\nexport const SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE = \"session_slash_command_result\";\nexport const COMPACTION_OUTCOME_CUSTOM_TYPE = \"compaction_outcome\";\nexport const REFINEMENT_OUTCOME_CUSTOM_TYPE = \"refinement_outcome\";\nexport const RLM_CHILD_FAILURE_CUSTOM_TYPE = \"rlm_child_failure\";\nexport const RLM_CHILD_TERMINAL_NOTICE_CUSTOM_TYPE = \"rlm_child_terminal_notice\";\n\nexport interface SessionSlashCommandDetails {\n\tcommand: SessionSlashCommand;\n\tcommandEntryId?: string;\n}\n\nexport interface SessionSlashCommandResultDetails {\n\tcommand: SessionSlashCommand;\n\tsuccess: boolean;\n\tseverity: \"info\" | \"warning\" | \"error\";\n\terror?: string;\n\tcommandEntryId?: string;\n}\n\nexport interface SessionSlashCommandMessage extends CustomMessage<SessionSlashCommandDetails> {\n\tcustomType: typeof SESSION_SLASH_COMMAND_CUSTOM_TYPE;\n\tcontent: string;\n\tdetails: SessionSlashCommandDetails;\n}\n\nexport interface SessionSlashCommandResultMessage extends CustomMessage<SessionSlashCommandResultDetails> {\n\tcustomType: typeof SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE;\n\tcontent: string;\n\tdetails: SessionSlashCommandResultDetails;\n}\n\nexport type CompactionOutcomeReason = \"threshold\" | \"overflow\" | \"requested\";\nexport type CompactionOutcome = \"skipped\" | \"cancelled\" | \"failed\";\n\nexport interface CompactionOutcomeDetails {\n\treason: CompactionOutcomeReason;\n\toutcome: CompactionOutcome;\n}\n\nexport interface CompactionOutcomeMessage extends CustomMessage<CompactionOutcomeDetails> {\n\tcustomType: typeof COMPACTION_OUTCOME_CUSTOM_TYPE;\n\tcontent: string;\n\tdetails: CompactionOutcomeDetails;\n}\n\nexport interface RefinementOutcomeDetails {\n\trefinementId: string;\n\tsummary: string;\n\tscope: HarnessScope;\n\trollbackOf?: string;\n\tedits: AppliedRefinementEdit[];\n}\n\nexport interface RefinementOutcomeMessage extends CustomMessage<RefinementOutcomeDetails> {\n\tcustomType: typeof REFINEMENT_OUTCOME_CUSTOM_TYPE;\n\tcontent: string;\n\tdetails: RefinementOutcomeDetails;\n}\n\nexport interface RlmChildFailureDetails {\n\tchildId: string;\n\tsessionName: string;\n\terror: string;\n}\n\nexport type RlmChildTerminalNoticeDetails =\n\t| {\n\t\t\tkind: \"cancelled\";\n\t\t\tchildId: string;\n\t\t\tsessionName: string;\n\t\t\treason?: string;\n\t }\n\t| {\n\t\t\tkind: \"completed_without_reply\";\n\t\t\tchildId: string;\n\t\t\tsessionName: string;\n\t\t\tlastAssistantTextPreview?: string;\n\t };\n\nexport function createRlmChildFailureMessage(\n\tdetails: RlmChildFailureDetails,\n\ttimestamp = Date.now(),\n): CustomMessage<RlmChildFailureDetails> {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: RLM_CHILD_FAILURE_CUSTOM_TYPE,\n\t\tcontent: `RLM child ${details.sessionName} (${details.childId}) failed: ${details.error}`,\n\t\tdisplay: true,\n\t\tdetails,\n\t\ttimestamp,\n\t};\n}\n\nexport function createRlmChildTerminalNoticeMessage(\n\tdetails: RlmChildTerminalNoticeDetails,\n\ttimestamp = Date.now(),\n): CustomMessage<RlmChildTerminalNoticeDetails> {\n\tconst content =\n\t\tdetails.kind === \"cancelled\"\n\t\t\t? `RLM child ${details.sessionName} (${details.childId}) was cancelled${details.reason ? `: ${details.reason}` : \"\"}`\n\t\t\t: `RLM child ${details.sessionName} (${details.childId}) completed without sending a reply${details.lastAssistantTextPreview ? `. Last assistant text: ${details.lastAssistantTextPreview}` : \"\"}`;\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: RLM_CHILD_TERMINAL_NOTICE_CUSTOM_TYPE,\n\t\tcontent,\n\t\tdisplay: true,\n\t\tdetails,\n\t\ttimestamp,\n\t};\n}\n\n/**\n * Message type for bash executions via the ! command.\n */\nexport interface BashExecutionMessage {\n\trole: \"bashExecution\";\n\tcommand: string;\n\toutput: string;\n\texitCode: number | undefined;\n\tcancelled: boolean;\n\ttruncated: boolean;\n\tfullOutputPath?: string;\n\ttimestamp: number;\n\t/** If true, this message is excluded from LLM context (!! prefix) */\n\texcludeFromContext?: boolean;\n}\n\n/**\n * Message type for extension-injected messages via sendMessage().\n * These are custom messages that extensions can inject into the conversation.\n */\nexport interface CustomMessage<T = unknown> {\n\trole: \"custom\";\n\tcustomType: string;\n\tcontent: string | (TextContent | ImageContent)[];\n\tdisplay: boolean;\n\tdetails?: T;\n\ttimestamp: number;\n}\n\nexport interface HeartbeatPromptDetails {\n\tjobId: string;\n\tschedule: string;\n\tstatus: AgentCronJob[\"status\"];\n\trunCount: number;\n\tnextRunAt?: string;\n\tlastRunAt?: string;\n}\n\nexport interface IpythonStateRestoredDetails {\n\trestored: boolean;\n}\n\nexport interface BranchSummaryMessage {\n\trole: \"branchSummary\";\n\tsummary: string;\n\tfromId: string;\n\ttimestamp: number;\n}\n\nexport interface CompactionSummaryMessage {\n\trole: \"compactionSummary\";\n\tsummary: string;\n\t/** Prior-context estimate; null when it is unavailable. */\n\ttokensBefore: number | null;\n\t/** Number of retained messages that precede this summary in transcript presentation. */\n\tretainedMessageCount?: number;\n\t/** User instructions that guided the summary (from `/compact <instructions>`) */\n\tcustomInstructions?: string;\n\ttimestamp: number;\n}\n\ndeclare module \"@ponythewhite/base-context-agent\" {\n\tinterface CustomAgentMessages {\n\t\tbashExecution: BashExecutionMessage;\n\t\tcustom: CustomMessage;\n\t\tbranchSummary: BranchSummaryMessage;\n\t\tcompactionSummary: CompactionSummaryMessage;\n\t}\n}\n\n/**\n * Format bash output for LLM context. The fence must be longer than any\n * backtick run in the output so command output cannot terminate it early.\n */\nexport function bashOutputToText(\n\tmsg: Pick<BashExecutionMessage, \"output\" | \"exitCode\" | \"cancelled\" | \"truncated\" | \"fullOutputPath\">,\n): string {\n\tlet text = \"\";\n\tif (msg.output) {\n\t\tlet longestBacktickRun = 0;\n\t\tfor (const match of msg.output.matchAll(/`+/g)) {\n\t\t\tlongestBacktickRun = Math.max(longestBacktickRun, match[0].length);\n\t\t}\n\t\tconst fence = \"`\".repeat(Math.max(3, longestBacktickRun + 1));\n\t\ttext += `${fence}\\n${msg.output}\\n${fence}`;\n\t} else {\n\t\ttext += \"(no output)\";\n\t}\n\tif (msg.cancelled) {\n\t\ttext += \"\\n\\n(command cancelled)\";\n\t} else if (msg.exitCode !== null && msg.exitCode !== undefined && msg.exitCode !== 0) {\n\t\ttext += `\\n\\nCommand exited with code ${msg.exitCode}`;\n\t}\n\tif (msg.truncated) {\n\t\ttext += msg.fullOutputPath\n\t\t\t? `\\n\\n[Output truncated. Full output: ${msg.fullOutputPath}]`\n\t\t\t: \"\\n\\n[Output truncated.]\";\n\t}\n\treturn text;\n}\n\n/**\n * Convert a BashExecutionMessage to user message text for LLM context.\n */\nexport function bashExecutionToText(msg: BashExecutionMessage): string {\n\treturn `Ran \\`${msg.command}\\`\\n${bashOutputToText(msg)}`;\n}\n\nexport function createBranchSummaryMessage(summary: string, fromId: string, timestamp: string): BranchSummaryMessage {\n\treturn {\n\t\trole: \"branchSummary\",\n\t\tsummary,\n\t\tfromId,\n\t\ttimestamp: new Date(timestamp).getTime(),\n\t};\n}\n\nexport function createCompactionSummaryMessage(\n\tsummary: string,\n\ttokensBefore: number | null,\n\ttimestamp: string,\n\tcustomInstructions?: string,\n\tretainedMessageCount?: number,\n): CompactionSummaryMessage {\n\treturn {\n\t\trole: \"compactionSummary\",\n\t\tsummary,\n\t\ttokensBefore,\n\t\tretainedMessageCount,\n\t\tcustomInstructions,\n\t\ttimestamp: new Date(timestamp).getTime(),\n\t};\n}\n\n/** Convert CustomMessageEntry to AgentMessage format */\nexport function createCustomMessage(\n\tcustomType: string,\n\tcontent: string | (TextContent | ImageContent)[],\n\tdisplay: boolean,\n\tdetails: unknown | undefined,\n\ttimestamp: string,\n): CustomMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType,\n\t\tcontent,\n\t\tdisplay,\n\t\tdetails,\n\t\ttimestamp: new Date(timestamp).getTime(),\n\t};\n}\n\nexport function createSessionSlashCommandMessage(\n\tcommand: SessionSlashCommand,\n\tdetails: Omit<SessionSlashCommandDetails, \"command\"> = {},\n\tdisplay = true,\n\ttimestamp = Date.now(),\n): SessionSlashCommandMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: SESSION_SLASH_COMMAND_CUSTOM_TYPE,\n\t\tcontent: command.text,\n\t\tdisplay,\n\t\tdetails: { ...details, command: { ...command } },\n\t\ttimestamp,\n\t};\n}\n\nexport function createSessionSlashCommandResultMessage(\n\tcontent: string,\n\tdetails: SessionSlashCommandResultDetails,\n\tdisplay = true,\n\ttimestamp = Date.now(),\n): SessionSlashCommandResultMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE,\n\t\tcontent,\n\t\tdisplay,\n\t\tdetails: { ...details, command: { ...details.command } },\n\t\ttimestamp,\n\t};\n}\n\nexport function createCompactionOutcomeMessage(\n\tcontent: string,\n\tdetails: CompactionOutcomeDetails,\n\tdisplay = true,\n\ttimestamp = Date.now(),\n): CompactionOutcomeMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: COMPACTION_OUTCOME_CUSTOM_TYPE,\n\t\tcontent,\n\t\tdisplay,\n\t\tdetails: { ...details },\n\t\ttimestamp,\n\t};\n}\n\nexport function createRefinementOutcomeMessage(\n\tresult: RefinementResult,\n\tdisplay = true,\n\ttimestamp = Date.now(),\n): RefinementOutcomeMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: REFINEMENT_OUTCOME_CUSTOM_TYPE,\n\t\tcontent: `Refinement complete: ${result.summary}`,\n\t\tdisplay,\n\t\tdetails: {\n\t\t\trefinementId: result.id,\n\t\t\tsummary: result.summary,\n\t\t\tscope: result.scope ?? \"local\",\n\t\t\t...(result.rollbackOf ? { rollbackOf: result.rollbackOf } : {}),\n\t\t\tedits: result.appliedEdits,\n\t\t},\n\t\ttimestamp,\n\t};\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction hasValidCustomMessageEnvelope(message: Record<string, unknown>, customType: string): boolean {\n\treturn (\n\t\tmessage.role === \"custom\" &&\n\t\tmessage.customType === customType &&\n\t\ttypeof message.content === \"string\" &&\n\t\ttypeof message.display === \"boolean\" &&\n\t\ttypeof message.timestamp === \"number\" &&\n\t\tNumber.isFinite(message.timestamp)\n\t);\n}\n\nexport function isSessionSlashCommand(value: unknown): value is SessionSlashCommand {\n\tif (\n\t\t!isRecord(value) ||\n\t\t!isSessionSlashCommandName(value.name) ||\n\t\ttypeof value.args !== \"string\" ||\n\t\ttypeof value.text !== \"string\"\n\t) {\n\t\treturn false;\n\t}\n\tconst parsed = parseSessionSlashCommand(value.text);\n\treturn (\n\t\tparsed !== undefined && parsed.name === value.name && parsed.args === value.args && parsed.text === value.text\n\t);\n}\n\nfunction isValidCommandEntryId(value: unknown): value is string | undefined {\n\treturn value === undefined || (typeof value === \"string\" && value.length > 0);\n}\n\nexport function isSessionSlashCommandMessage(message: unknown): message is SessionSlashCommandMessage {\n\tif (\n\t\t!isRecord(message) ||\n\t\t!hasValidCustomMessageEnvelope(message, SESSION_SLASH_COMMAND_CUSTOM_TYPE) ||\n\t\ttypeof message.content !== \"string\"\n\t) {\n\t\treturn false;\n\t}\n\tif (!isRecord(message.details) || !isSessionSlashCommand(message.details.command)) return false;\n\treturn message.content === message.details.command.text && isValidCommandEntryId(message.details.commandEntryId);\n}\n\nexport function isSessionSlashCommandResultMessage(message: unknown): message is SessionSlashCommandResultMessage {\n\tif (!isRecord(message) || !hasValidCustomMessageEnvelope(message, SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE))\n\t\treturn false;\n\tif (!isRecord(message.details) || !isSessionSlashCommand(message.details.command)) return false;\n\treturn (\n\t\ttypeof message.details.success === \"boolean\" &&\n\t\t(message.details.severity === \"info\" ||\n\t\t\tmessage.details.severity === \"warning\" ||\n\t\t\tmessage.details.severity === \"error\") &&\n\t\t(message.details.error === undefined || typeof message.details.error === \"string\") &&\n\t\tisValidCommandEntryId(message.details.commandEntryId)\n\t);\n}\n\nexport function isCompactionOutcomeMessage(message: unknown): message is CompactionOutcomeMessage {\n\tif (!isRecord(message) || !hasValidCustomMessageEnvelope(message, COMPACTION_OUTCOME_CUSTOM_TYPE)) return false;\n\tif (!isRecord(message.details)) return false;\n\treturn (\n\t\t(message.details.reason === \"threshold\" ||\n\t\t\tmessage.details.reason === \"overflow\" ||\n\t\t\tmessage.details.reason === \"requested\") &&\n\t\t(message.details.outcome === \"skipped\" ||\n\t\t\tmessage.details.outcome === \"cancelled\" ||\n\t\t\tmessage.details.outcome === \"failed\")\n\t);\n}\n\nfunction isAppliedRefinementEdit(value: unknown): value is AppliedRefinementEdit {\n\treturn (\n\t\tisRecord(value) &&\n\t\t(value.action === \"create\" || value.action === \"update\" || value.action === \"delete\") &&\n\t\ttypeof value.kind === \"string\" &&\n\t\ttypeof value.id === \"string\" &&\n\t\ttypeof value.applied === \"boolean\"\n\t);\n}\n\nexport function isRefinementOutcomeMessage(message: unknown): message is RefinementOutcomeMessage {\n\tif (!isRecord(message) || !hasValidCustomMessageEnvelope(message, REFINEMENT_OUTCOME_CUSTOM_TYPE)) return false;\n\tif (!isRecord(message.details)) return false;\n\treturn (\n\t\ttypeof message.details.summary === \"string\" &&\n\t\t(message.details.scope === \"local\" || message.details.scope === \"global\") &&\n\t\tArray.isArray(message.details.edits) &&\n\t\tmessage.details.edits.every(isAppliedRefinementEdit)\n\t);\n}\n\nexport function createHeartbeatPromptMessage(\n\tjob: AgentCronJob,\n\ttimestamp = Date.now(),\n): CustomMessage<HeartbeatPromptDetails> {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: HEARTBEAT_PROMPT_CUSTOM_TYPE,\n\t\tcontent: job.prompt,\n\t\tdisplay: true,\n\t\tdetails: {\n\t\t\tjobId: job.id,\n\t\t\tschedule: job.schedule.expression,\n\t\t\tstatus: job.status,\n\t\t\trunCount: job.runCount,\n\t\t\tnextRunAt: job.nextRunAt,\n\t\t\tlastRunAt: job.lastRunAt,\n\t\t},\n\t\ttimestamp,\n\t};\n}\n\n/**\n * Transform AgentMessages (including custom types) to LLM-compatible Messages.\n *\n * This is used by:\n * - Agent's transormToLlm option (for prompt calls and queued messages)\n * - Compaction's generateSummary (for summarization)\n * - Custom extensions and tools\n */\nexport function convertToLlm(messages: AgentMessage[]): Message[] {\n\treturn messages\n\t\t.map((m): Message | undefined => {\n\t\t\tswitch (m.role) {\n\t\t\t\tcase \"bashExecution\":\n\t\t\t\t\tif (m.excludeFromContext) {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: bashExecutionToText(m) }],\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\tcase \"custom\": {\n\t\t\t\t\tif (\n\t\t\t\t\t\tm.customType === SESSION_SLASH_COMMAND_CUSTOM_TYPE ||\n\t\t\t\t\t\tm.customType === SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE ||\n\t\t\t\t\t\tm.customType === COMPACTION_OUTCOME_CUSTOM_TYPE ||\n\t\t\t\t\t\tm.customType === REFINEMENT_OUTCOME_CUSTOM_TYPE\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t\tconst content = typeof m.content === \"string\" ? [{ type: \"text\" as const, text: m.content }] : m.content;\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent,\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tcase \"branchSummary\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [{ type: \"text\" as const, text: BRANCH_SUMMARY_PREFIX + m.summary + BRANCH_SUMMARY_SUFFIX }],\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\tcase \"compactionSummary\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{ type: \"text\" as const, text: COMPACTION_SUMMARY_PREFIX + m.summary + COMPACTION_SUMMARY_SUFFIX },\n\t\t\t\t\t\t],\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\tcase \"user\":\n\t\t\t\tcase \"assistant\":\n\t\t\t\tcase \"toolResult\":\n\t\t\t\t\treturn m;\n\t\t\t\tdefault:\n\t\t\t\t\t// biome-ignore lint/correctness/noSwitchDeclarations: fine\n\t\t\t\t\tconst _exhaustiveCheck: never = m;\n\t\t\t\t\treturn undefined;\n\t\t\t}\n\t\t})\n\t\t.filter((m) => m !== undefined);\n}\n"]}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/core/messages.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Custom message types and transformers for the coding agent.\n *\n * Extends the base AgentMessage type with coding-agent specific message types,\n * and provides a transformer to convert them to LLM-compatible messages.\n */\n\nimport type { AgentMessage } from \"@ponythewhite/base-context-agent\";\nimport type { ImageContent, Message, TextContent } from \"@ponythewhite/base-context-ai\";\nimport type { AgentCronJob } from \"./cron-jobs.js\";\nimport type { AppliedRefinementEdit, HarnessScope, RefinementResult } from \"./refinement/refinement.js\";\nimport { isSessionSlashCommandName, parseSessionSlashCommand, type SessionSlashCommand } from \"./slash-commands.js\";\n\nexport const COMPACTION_SUMMARY_PREFIX = `The conversation history before this point was compacted into the following summary:\n\n<summary>\n`;\n\nexport const COMPACTION_SUMMARY_SUFFIX = `\n</summary>`;\n\nexport const BRANCH_SUMMARY_PREFIX = `The following is a summary of a branch that this conversation came back from:\n\n<summary>\n`;\n\nexport const BRANCH_SUMMARY_SUFFIX = `</summary>`;\n\nexport const HEARTBEAT_PROMPT_CUSTOM_TYPE = \"heartbeat_prompt\";\nexport const HEARTBEAT_PROMPT_PREVIEW_LABEL = \"Heartbeat prompt\";\nexport const IPYTHON_STATE_RESTORED_CUSTOM_TYPE = \"ipython_state_restored\";\nexport const SESSION_SLASH_COMMAND_CUSTOM_TYPE = \"session_slash_command\";\nexport const SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE = \"session_slash_command_result\";\nexport const COMPACTION_OUTCOME_CUSTOM_TYPE = \"compaction_outcome\";\nexport const REFINEMENT_OUTCOME_CUSTOM_TYPE = \"refinement_outcome\";\nexport const RLM_CHILD_FAILURE_CUSTOM_TYPE = \"rlm_child_failure\";\nexport const RLM_CHILD_TERMINAL_NOTICE_CUSTOM_TYPE = \"rlm_child_terminal_notice\";\n\nexport interface SessionSlashCommandDetails {\n\tcommand: SessionSlashCommand;\n\tcommandEntryId?: string;\n}\n\nexport interface SessionSlashCommandResultDetails {\n\tcommand: SessionSlashCommand;\n\tsuccess: boolean;\n\tseverity: \"info\" | \"warning\" | \"error\";\n\terror?: string;\n\tcommandEntryId?: string;\n}\n\nexport interface SessionSlashCommandMessage extends CustomMessage<SessionSlashCommandDetails> {\n\tcustomType: typeof SESSION_SLASH_COMMAND_CUSTOM_TYPE;\n\tcontent: string;\n\tdetails: SessionSlashCommandDetails;\n}\n\nexport interface SessionSlashCommandResultMessage extends CustomMessage<SessionSlashCommandResultDetails> {\n\tcustomType: typeof SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE;\n\tcontent: string;\n\tdetails: SessionSlashCommandResultDetails;\n}\n\nexport type CompactionOutcomeReason = \"threshold\" | \"overflow\" | \"requested\";\nexport type CompactionOutcome = \"skipped\" | \"cancelled\" | \"failed\";\n\nexport interface CompactionOutcomeDetails {\n\treason: CompactionOutcomeReason;\n\toutcome: CompactionOutcome;\n}\n\nexport interface CompactionOutcomeMessage extends CustomMessage<CompactionOutcomeDetails> {\n\tcustomType: typeof COMPACTION_OUTCOME_CUSTOM_TYPE;\n\tcontent: string;\n\tdetails: CompactionOutcomeDetails;\n}\n\nexport interface RefinementOutcomeDetails {\n\trefinementId: string;\n\tsummary: string;\n\tscope: HarnessScope;\n\trollbackOf?: string;\n\tedits: AppliedRefinementEdit[];\n}\n\nexport interface RefinementOutcomeMessage extends CustomMessage<RefinementOutcomeDetails> {\n\tcustomType: typeof REFINEMENT_OUTCOME_CUSTOM_TYPE;\n\tcontent: string;\n\tdetails: RefinementOutcomeDetails;\n}\n\nexport interface RlmChildFailureDetails {\n\tchildId: string;\n\tsessionName: string;\n\terror: string;\n}\n\nexport type RlmChildTerminalNoticeDetails =\n\t| {\n\t\t\tkind: \"cancelled\";\n\t\t\tchildId: string;\n\t\t\tsessionName: string;\n\t\t\treason?: string;\n\t }\n\t| {\n\t\t\tkind: \"completed_without_reply\";\n\t\t\tchildId: string;\n\t\t\tsessionName: string;\n\t\t\tlastAssistantTextPreview?: string;\n\t };\n\nexport function createRlmChildFailureMessage(\n\tdetails: RlmChildFailureDetails,\n\ttimestamp = Date.now(),\n): CustomMessage<RlmChildFailureDetails> {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: RLM_CHILD_FAILURE_CUSTOM_TYPE,\n\t\tcontent: `RLM child ${details.sessionName} (${details.childId}) failed: ${details.error}`,\n\t\tdisplay: true,\n\t\tdetails,\n\t\ttimestamp,\n\t};\n}\n\nexport function createRlmChildTerminalNoticeMessage(\n\tdetails: RlmChildTerminalNoticeDetails,\n\ttimestamp = Date.now(),\n): CustomMessage<RlmChildTerminalNoticeDetails> {\n\tconst content =\n\t\tdetails.kind === \"cancelled\"\n\t\t\t? `RLM child ${details.sessionName} (${details.childId}) was cancelled${details.reason ? `: ${details.reason}` : \"\"}`\n\t\t\t: `RLM child ${details.sessionName} (${details.childId}) completed without sending a reply${details.lastAssistantTextPreview ? `. Last assistant text: ${details.lastAssistantTextPreview}` : \"\"}`;\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: RLM_CHILD_TERMINAL_NOTICE_CUSTOM_TYPE,\n\t\tcontent,\n\t\tdisplay: true,\n\t\tdetails,\n\t\ttimestamp,\n\t};\n}\n\n/**\n * Message type for bash executions via the ! command.\n */\nexport interface BashExecutionMessage {\n\trole: \"bashExecution\";\n\tcommand: string;\n\toutput: string;\n\texitCode: number | undefined;\n\tcancelled: boolean;\n\ttruncated: boolean;\n\tfullOutputPath?: string;\n\ttimestamp: number;\n\t/** If true, this message is excluded from LLM context (!! prefix) */\n\texcludeFromContext?: boolean;\n}\n\n/**\n * Message type for extension-injected messages via sendMessage().\n * These are custom messages that extensions can inject into the conversation.\n */\nexport interface CustomMessage<T = unknown> {\n\trole: \"custom\";\n\tcustomType: string;\n\tcontent: string | (TextContent | ImageContent)[];\n\tdisplay: boolean;\n\tdetails?: T;\n\ttimestamp: number;\n}\n\nexport interface HeartbeatPromptDetails {\n\tjobId: string;\n\tschedule: string;\n\tstatus: AgentCronJob[\"status\"];\n\trunCount: number;\n\tnextRunAt?: string;\n\tlastRunAt?: string;\n}\n\nexport interface IpythonStateRestoredDetails {\n\trestored: boolean;\n}\n\nexport interface BranchSummaryMessage {\n\trole: \"branchSummary\";\n\tsummary: string;\n\tfromId: string;\n\ttimestamp: number;\n}\n\nexport interface CompactionSummaryMessage {\n\trole: \"compactionSummary\";\n\tsummary: string;\n\t/** Prior-context estimate; null when it is unavailable. */\n\ttokensBefore: number | null;\n\t/** Number of retained messages that precede this summary in transcript presentation. */\n\tretainedMessageCount?: number;\n\t/** User instructions that guided the summary (from `/compact <instructions>`) */\n\tcustomInstructions?: string;\n\ttimestamp: number;\n}\n\ndeclare module \"@ponythewhite/base-context-agent\" {\n\tinterface CustomAgentMessages {\n\t\tbashExecution: BashExecutionMessage;\n\t\tcustom: CustomMessage;\n\t\tbranchSummary: BranchSummaryMessage;\n\t\tcompactionSummary: CompactionSummaryMessage;\n\t}\n}\n\n/**\n * Format bash output for LLM context. The fence must be longer than any\n * backtick run in the output so command output cannot terminate it early.\n */\nexport function bashOutputToText(\n\tmsg: Pick<BashExecutionMessage, \"output\" | \"exitCode\" | \"cancelled\" | \"truncated\" | \"fullOutputPath\">,\n): string {\n\tlet text = \"\";\n\tif (msg.output) {\n\t\tlet longestBacktickRun = 0;\n\t\tfor (const match of msg.output.matchAll(/`+/g)) {\n\t\t\tlongestBacktickRun = Math.max(longestBacktickRun, match[0].length);\n\t\t}\n\t\tconst fence = \"`\".repeat(Math.max(3, longestBacktickRun + 1));\n\t\ttext += `${fence}\\n${msg.output}\\n${fence}`;\n\t} else {\n\t\ttext += \"(no output)\";\n\t}\n\tif (msg.cancelled) {\n\t\ttext += \"\\n\\n(command cancelled)\";\n\t} else if (msg.exitCode !== null && msg.exitCode !== undefined && msg.exitCode !== 0) {\n\t\ttext += `\\n\\nCommand exited with code ${msg.exitCode}`;\n\t}\n\tif (msg.truncated) {\n\t\ttext += msg.fullOutputPath\n\t\t\t? `\\n\\n[Output truncated. Full output: ${msg.fullOutputPath}]`\n\t\t\t: \"\\n\\n[Output truncated.]\";\n\t}\n\treturn text;\n}\n\n/**\n * Convert a BashExecutionMessage to user message text for LLM context.\n */\nexport function bashExecutionToText(msg: BashExecutionMessage): string {\n\treturn `Ran \\`${msg.command}\\`\\n${bashOutputToText(msg)}`;\n}\n\nexport function createBranchSummaryMessage(summary: string, fromId: string, timestamp: string): BranchSummaryMessage {\n\treturn {\n\t\trole: \"branchSummary\",\n\t\tsummary,\n\t\tfromId,\n\t\ttimestamp: new Date(timestamp).getTime(),\n\t};\n}\n\nexport function createCompactionSummaryMessage(\n\tsummary: string,\n\ttokensBefore: number | null,\n\ttimestamp: string,\n\tcustomInstructions?: string,\n\tretainedMessageCount?: number,\n): CompactionSummaryMessage {\n\treturn {\n\t\trole: \"compactionSummary\",\n\t\tsummary,\n\t\ttokensBefore,\n\t\tretainedMessageCount,\n\t\tcustomInstructions,\n\t\ttimestamp: new Date(timestamp).getTime(),\n\t};\n}\n\n/** Convert CustomMessageEntry to AgentMessage format */\nexport function createCustomMessage(\n\tcustomType: string,\n\tcontent: string | (TextContent | ImageContent)[],\n\tdisplay: boolean,\n\tdetails: unknown | undefined,\n\ttimestamp: string,\n): CustomMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType,\n\t\tcontent,\n\t\tdisplay,\n\t\tdetails,\n\t\ttimestamp: new Date(timestamp).getTime(),\n\t};\n}\n\nexport function createSessionSlashCommandMessage(\n\tcommand: SessionSlashCommand,\n\tdetails: Omit<SessionSlashCommandDetails, \"command\"> = {},\n\tdisplay = true,\n\ttimestamp = Date.now(),\n): SessionSlashCommandMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: SESSION_SLASH_COMMAND_CUSTOM_TYPE,\n\t\tcontent: command.text,\n\t\tdisplay,\n\t\tdetails: { ...details, command: { ...command } },\n\t\ttimestamp,\n\t};\n}\n\nexport function createSessionSlashCommandResultMessage(\n\tcontent: string,\n\tdetails: SessionSlashCommandResultDetails,\n\tdisplay = true,\n\ttimestamp = Date.now(),\n): SessionSlashCommandResultMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE,\n\t\tcontent,\n\t\tdisplay,\n\t\tdetails: { ...details, command: { ...details.command } },\n\t\ttimestamp,\n\t};\n}\n\nexport function createCompactionOutcomeMessage(\n\tcontent: string,\n\tdetails: CompactionOutcomeDetails,\n\tdisplay = true,\n\ttimestamp = Date.now(),\n): CompactionOutcomeMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: COMPACTION_OUTCOME_CUSTOM_TYPE,\n\t\tcontent,\n\t\tdisplay,\n\t\tdetails: { ...details },\n\t\ttimestamp,\n\t};\n}\n\nexport function createRefinementOutcomeMessage(\n\tresult: RefinementResult,\n\tdisplay = true,\n\ttimestamp = Date.now(),\n): RefinementOutcomeMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: REFINEMENT_OUTCOME_CUSTOM_TYPE,\n\t\tcontent: `Refinement complete: ${result.summary}`,\n\t\tdisplay,\n\t\tdetails: {\n\t\t\trefinementId: result.id,\n\t\t\tsummary: result.summary,\n\t\t\tscope: result.scope ?? \"local\",\n\t\t\t...(result.rollbackOf ? { rollbackOf: result.rollbackOf } : {}),\n\t\t\tedits: result.appliedEdits,\n\t\t},\n\t\ttimestamp,\n\t};\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction hasValidCustomMessageEnvelope(message: Record<string, unknown>, customType: string): boolean {\n\treturn (\n\t\tmessage.role === \"custom\" &&\n\t\tmessage.customType === customType &&\n\t\ttypeof message.content === \"string\" &&\n\t\ttypeof message.display === \"boolean\" &&\n\t\ttypeof message.timestamp === \"number\" &&\n\t\tNumber.isFinite(message.timestamp)\n\t);\n}\n\nexport function isSessionSlashCommand(value: unknown): value is SessionSlashCommand {\n\tif (\n\t\t!isRecord(value) ||\n\t\t!isSessionSlashCommandName(value.name) ||\n\t\ttypeof value.args !== \"string\" ||\n\t\ttypeof value.text !== \"string\"\n\t) {\n\t\treturn false;\n\t}\n\tconst parsed = parseSessionSlashCommand(value.text);\n\treturn (\n\t\tparsed !== undefined && parsed.name === value.name && parsed.args === value.args && parsed.text === value.text\n\t);\n}\n\nfunction isValidCommandEntryId(value: unknown): value is string | undefined {\n\treturn value === undefined || (typeof value === \"string\" && value.length > 0);\n}\n\nexport function isSessionSlashCommandMessage(message: unknown): message is SessionSlashCommandMessage {\n\tif (\n\t\t!isRecord(message) ||\n\t\t!hasValidCustomMessageEnvelope(message, SESSION_SLASH_COMMAND_CUSTOM_TYPE) ||\n\t\ttypeof message.content !== \"string\"\n\t) {\n\t\treturn false;\n\t}\n\tif (!isRecord(message.details) || !isSessionSlashCommand(message.details.command)) return false;\n\treturn message.content === message.details.command.text && isValidCommandEntryId(message.details.commandEntryId);\n}\n\nexport function isSessionSlashCommandResultMessage(message: unknown): message is SessionSlashCommandResultMessage {\n\tif (!isRecord(message) || !hasValidCustomMessageEnvelope(message, SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE))\n\t\treturn false;\n\tif (!isRecord(message.details) || !isSessionSlashCommand(message.details.command)) return false;\n\treturn (\n\t\ttypeof message.details.success === \"boolean\" &&\n\t\t(message.details.severity === \"info\" ||\n\t\t\tmessage.details.severity === \"warning\" ||\n\t\t\tmessage.details.severity === \"error\") &&\n\t\t(message.details.error === undefined || typeof message.details.error === \"string\") &&\n\t\tisValidCommandEntryId(message.details.commandEntryId)\n\t);\n}\n\nexport function isCompactionOutcomeMessage(message: unknown): message is CompactionOutcomeMessage {\n\tif (!isRecord(message) || !hasValidCustomMessageEnvelope(message, COMPACTION_OUTCOME_CUSTOM_TYPE)) return false;\n\tif (!isRecord(message.details)) return false;\n\treturn (\n\t\t(message.details.reason === \"threshold\" ||\n\t\t\tmessage.details.reason === \"overflow\" ||\n\t\t\tmessage.details.reason === \"requested\") &&\n\t\t(message.details.outcome === \"skipped\" ||\n\t\t\tmessage.details.outcome === \"cancelled\" ||\n\t\t\tmessage.details.outcome === \"failed\")\n\t);\n}\n\nfunction isAppliedRefinementEdit(value: unknown): value is AppliedRefinementEdit {\n\treturn (\n\t\tisRecord(value) &&\n\t\t(value.action === \"create\" || value.action === \"update\" || value.action === \"delete\") &&\n\t\ttypeof value.kind === \"string\" &&\n\t\ttypeof value.id === \"string\" &&\n\t\ttypeof value.applied === \"boolean\"\n\t);\n}\n\nexport function isRefinementOutcomeMessage(message: unknown): message is RefinementOutcomeMessage {\n\tif (!isRecord(message) || !hasValidCustomMessageEnvelope(message, REFINEMENT_OUTCOME_CUSTOM_TYPE)) return false;\n\tif (!isRecord(message.details)) return false;\n\treturn (\n\t\ttypeof message.details.summary === \"string\" &&\n\t\t(message.details.scope === \"local\" || message.details.scope === \"global\") &&\n\t\tArray.isArray(message.details.edits) &&\n\t\tmessage.details.edits.every(isAppliedRefinementEdit)\n\t);\n}\n\nexport function createHeartbeatPromptMessage(\n\tjob: AgentCronJob,\n\ttimestamp = Date.now(),\n): CustomMessage<HeartbeatPromptDetails> {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: HEARTBEAT_PROMPT_CUSTOM_TYPE,\n\t\tcontent: job.prompt,\n\t\tdisplay: true,\n\t\tdetails: {\n\t\t\tjobId: job.id,\n\t\t\tschedule: job.schedule.expression,\n\t\t\tstatus: job.status,\n\t\t\trunCount: job.runCount,\n\t\t\tnextRunAt: job.nextRunAt,\n\t\t\tlastRunAt: job.lastRunAt,\n\t\t},\n\t\ttimestamp,\n\t};\n}\n\n/**\n * Transform AgentMessages (including custom types) to LLM-compatible Messages.\n *\n * This is used by:\n * - Agent's transormToLlm option (for prompt calls and queued messages)\n * - Compaction's generateSummary (for summarization)\n * - Custom extensions and tools\n */\nexport function convertToLlm(messages: AgentMessage[]): Message[] {\n\treturn messages\n\t\t.map((m): Message | undefined => {\n\t\t\tswitch (m.role) {\n\t\t\t\tcase \"bashExecution\":\n\t\t\t\t\tif (m.excludeFromContext) {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: bashExecutionToText(m) }],\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\tcase \"custom\": {\n\t\t\t\t\tif (\n\t\t\t\t\t\tm.customType === SESSION_SLASH_COMMAND_CUSTOM_TYPE ||\n\t\t\t\t\t\tm.customType === SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE ||\n\t\t\t\t\t\tm.customType === COMPACTION_OUTCOME_CUSTOM_TYPE ||\n\t\t\t\t\t\tm.customType === REFINEMENT_OUTCOME_CUSTOM_TYPE\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t\tconst content = typeof m.content === \"string\" ? [{ type: \"text\" as const, text: m.content }] : m.content;\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent,\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tcase \"branchSummary\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [{ type: \"text\" as const, text: BRANCH_SUMMARY_PREFIX + m.summary + BRANCH_SUMMARY_SUFFIX }],\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\tcase \"compactionSummary\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{ type: \"text\" as const, text: COMPACTION_SUMMARY_PREFIX + m.summary + COMPACTION_SUMMARY_SUFFIX },\n\t\t\t\t\t\t],\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\tcase \"assistant\":\n\t\t\t\t\t// Providers omit failed/aborted replies. Apply that same omission\n\t\t\t\t\t// before capturing the canonical-to-provider positions on resume.\n\t\t\t\t\treturn m.stopReason === \"error\" || m.stopReason === \"aborted\" ? undefined : m;\n\t\t\t\tcase \"user\":\n\t\t\t\tcase \"toolResult\":\n\t\t\t\t\treturn m;\n\t\t\t\tdefault:\n\t\t\t\t\t// biome-ignore lint/correctness/noSwitchDeclarations: fine\n\t\t\t\t\tconst _exhaustiveCheck: never = m;\n\t\t\t\t\treturn undefined;\n\t\t\t}\n\t\t})\n\t\t.filter((m) => m !== undefined);\n}\n"]}
@@ -300,8 +300,11 @@ export function convertToLlm(messages) {
300
300
  ],
301
301
  timestamp: m.timestamp,
302
302
  };
303
- case "user":
304
303
  case "assistant":
304
+ // Providers omit failed/aborted replies. Apply that same omission
305
+ // before capturing the canonical-to-provider positions on resume.
306
+ return m.stopReason === "error" || m.stopReason === "aborted" ? undefined : m;
307
+ case "user":
305
308
  case "toolResult":
306
309
  return m;
307
310
  default:
@@ -1 +1 @@
1
- {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/core/messages.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Custom message types and transformers for the coding agent.\n *\n * Extends the base AgentMessage type with coding-agent specific message types,\n * and provides a transformer to convert them to LLM-compatible messages.\n */\n\nimport type { AgentMessage } from \"@ponythewhite/base-context-agent\";\nimport type { ImageContent, Message, TextContent } from \"@ponythewhite/base-context-ai\";\nimport type { AgentCronJob } from \"./cron-jobs.js\";\nimport type { AppliedRefinementEdit, HarnessScope, RefinementResult } from \"./refinement/refinement.js\";\nimport { isSessionSlashCommandName, parseSessionSlashCommand, type SessionSlashCommand } from \"./slash-commands.js\";\n\nexport const COMPACTION_SUMMARY_PREFIX = `The conversation history before this point was compacted into the following summary:\n\n<summary>\n`;\n\nexport const COMPACTION_SUMMARY_SUFFIX = `\n</summary>`;\n\nexport const BRANCH_SUMMARY_PREFIX = `The following is a summary of a branch that this conversation came back from:\n\n<summary>\n`;\n\nexport const BRANCH_SUMMARY_SUFFIX = `</summary>`;\n\nexport const HEARTBEAT_PROMPT_CUSTOM_TYPE = \"heartbeat_prompt\";\nexport const HEARTBEAT_PROMPT_PREVIEW_LABEL = \"Heartbeat prompt\";\nexport const IPYTHON_STATE_RESTORED_CUSTOM_TYPE = \"ipython_state_restored\";\nexport const SESSION_SLASH_COMMAND_CUSTOM_TYPE = \"session_slash_command\";\nexport const SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE = \"session_slash_command_result\";\nexport const COMPACTION_OUTCOME_CUSTOM_TYPE = \"compaction_outcome\";\nexport const REFINEMENT_OUTCOME_CUSTOM_TYPE = \"refinement_outcome\";\nexport const RLM_CHILD_FAILURE_CUSTOM_TYPE = \"rlm_child_failure\";\nexport const RLM_CHILD_TERMINAL_NOTICE_CUSTOM_TYPE = \"rlm_child_terminal_notice\";\n\nexport interface SessionSlashCommandDetails {\n\tcommand: SessionSlashCommand;\n\tcommandEntryId?: string;\n}\n\nexport interface SessionSlashCommandResultDetails {\n\tcommand: SessionSlashCommand;\n\tsuccess: boolean;\n\tseverity: \"info\" | \"warning\" | \"error\";\n\terror?: string;\n\tcommandEntryId?: string;\n}\n\nexport interface SessionSlashCommandMessage extends CustomMessage<SessionSlashCommandDetails> {\n\tcustomType: typeof SESSION_SLASH_COMMAND_CUSTOM_TYPE;\n\tcontent: string;\n\tdetails: SessionSlashCommandDetails;\n}\n\nexport interface SessionSlashCommandResultMessage extends CustomMessage<SessionSlashCommandResultDetails> {\n\tcustomType: typeof SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE;\n\tcontent: string;\n\tdetails: SessionSlashCommandResultDetails;\n}\n\nexport type CompactionOutcomeReason = \"threshold\" | \"overflow\" | \"requested\";\nexport type CompactionOutcome = \"skipped\" | \"cancelled\" | \"failed\";\n\nexport interface CompactionOutcomeDetails {\n\treason: CompactionOutcomeReason;\n\toutcome: CompactionOutcome;\n}\n\nexport interface CompactionOutcomeMessage extends CustomMessage<CompactionOutcomeDetails> {\n\tcustomType: typeof COMPACTION_OUTCOME_CUSTOM_TYPE;\n\tcontent: string;\n\tdetails: CompactionOutcomeDetails;\n}\n\nexport interface RefinementOutcomeDetails {\n\trefinementId: string;\n\tsummary: string;\n\tscope: HarnessScope;\n\trollbackOf?: string;\n\tedits: AppliedRefinementEdit[];\n}\n\nexport interface RefinementOutcomeMessage extends CustomMessage<RefinementOutcomeDetails> {\n\tcustomType: typeof REFINEMENT_OUTCOME_CUSTOM_TYPE;\n\tcontent: string;\n\tdetails: RefinementOutcomeDetails;\n}\n\nexport interface RlmChildFailureDetails {\n\tchildId: string;\n\tsessionName: string;\n\terror: string;\n}\n\nexport type RlmChildTerminalNoticeDetails =\n\t| {\n\t\t\tkind: \"cancelled\";\n\t\t\tchildId: string;\n\t\t\tsessionName: string;\n\t\t\treason?: string;\n\t }\n\t| {\n\t\t\tkind: \"completed_without_reply\";\n\t\t\tchildId: string;\n\t\t\tsessionName: string;\n\t\t\tlastAssistantTextPreview?: string;\n\t };\n\nexport function createRlmChildFailureMessage(\n\tdetails: RlmChildFailureDetails,\n\ttimestamp = Date.now(),\n): CustomMessage<RlmChildFailureDetails> {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: RLM_CHILD_FAILURE_CUSTOM_TYPE,\n\t\tcontent: `RLM child ${details.sessionName} (${details.childId}) failed: ${details.error}`,\n\t\tdisplay: true,\n\t\tdetails,\n\t\ttimestamp,\n\t};\n}\n\nexport function createRlmChildTerminalNoticeMessage(\n\tdetails: RlmChildTerminalNoticeDetails,\n\ttimestamp = Date.now(),\n): CustomMessage<RlmChildTerminalNoticeDetails> {\n\tconst content =\n\t\tdetails.kind === \"cancelled\"\n\t\t\t? `RLM child ${details.sessionName} (${details.childId}) was cancelled${details.reason ? `: ${details.reason}` : \"\"}`\n\t\t\t: `RLM child ${details.sessionName} (${details.childId}) completed without sending a reply${details.lastAssistantTextPreview ? `. Last assistant text: ${details.lastAssistantTextPreview}` : \"\"}`;\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: RLM_CHILD_TERMINAL_NOTICE_CUSTOM_TYPE,\n\t\tcontent,\n\t\tdisplay: true,\n\t\tdetails,\n\t\ttimestamp,\n\t};\n}\n\n/**\n * Message type for bash executions via the ! command.\n */\nexport interface BashExecutionMessage {\n\trole: \"bashExecution\";\n\tcommand: string;\n\toutput: string;\n\texitCode: number | undefined;\n\tcancelled: boolean;\n\ttruncated: boolean;\n\tfullOutputPath?: string;\n\ttimestamp: number;\n\t/** If true, this message is excluded from LLM context (!! prefix) */\n\texcludeFromContext?: boolean;\n}\n\n/**\n * Message type for extension-injected messages via sendMessage().\n * These are custom messages that extensions can inject into the conversation.\n */\nexport interface CustomMessage<T = unknown> {\n\trole: \"custom\";\n\tcustomType: string;\n\tcontent: string | (TextContent | ImageContent)[];\n\tdisplay: boolean;\n\tdetails?: T;\n\ttimestamp: number;\n}\n\nexport interface HeartbeatPromptDetails {\n\tjobId: string;\n\tschedule: string;\n\tstatus: AgentCronJob[\"status\"];\n\trunCount: number;\n\tnextRunAt?: string;\n\tlastRunAt?: string;\n}\n\nexport interface IpythonStateRestoredDetails {\n\trestored: boolean;\n}\n\nexport interface BranchSummaryMessage {\n\trole: \"branchSummary\";\n\tsummary: string;\n\tfromId: string;\n\ttimestamp: number;\n}\n\nexport interface CompactionSummaryMessage {\n\trole: \"compactionSummary\";\n\tsummary: string;\n\t/** Prior-context estimate; null when it is unavailable. */\n\ttokensBefore: number | null;\n\t/** Number of retained messages that precede this summary in transcript presentation. */\n\tretainedMessageCount?: number;\n\t/** User instructions that guided the summary (from `/compact <instructions>`) */\n\tcustomInstructions?: string;\n\ttimestamp: number;\n}\n\ndeclare module \"@ponythewhite/base-context-agent\" {\n\tinterface CustomAgentMessages {\n\t\tbashExecution: BashExecutionMessage;\n\t\tcustom: CustomMessage;\n\t\tbranchSummary: BranchSummaryMessage;\n\t\tcompactionSummary: CompactionSummaryMessage;\n\t}\n}\n\n/**\n * Format bash output for LLM context. The fence must be longer than any\n * backtick run in the output so command output cannot terminate it early.\n */\nexport function bashOutputToText(\n\tmsg: Pick<BashExecutionMessage, \"output\" | \"exitCode\" | \"cancelled\" | \"truncated\" | \"fullOutputPath\">,\n): string {\n\tlet text = \"\";\n\tif (msg.output) {\n\t\tlet longestBacktickRun = 0;\n\t\tfor (const match of msg.output.matchAll(/`+/g)) {\n\t\t\tlongestBacktickRun = Math.max(longestBacktickRun, match[0].length);\n\t\t}\n\t\tconst fence = \"`\".repeat(Math.max(3, longestBacktickRun + 1));\n\t\ttext += `${fence}\\n${msg.output}\\n${fence}`;\n\t} else {\n\t\ttext += \"(no output)\";\n\t}\n\tif (msg.cancelled) {\n\t\ttext += \"\\n\\n(command cancelled)\";\n\t} else if (msg.exitCode !== null && msg.exitCode !== undefined && msg.exitCode !== 0) {\n\t\ttext += `\\n\\nCommand exited with code ${msg.exitCode}`;\n\t}\n\tif (msg.truncated) {\n\t\ttext += msg.fullOutputPath\n\t\t\t? `\\n\\n[Output truncated. Full output: ${msg.fullOutputPath}]`\n\t\t\t: \"\\n\\n[Output truncated.]\";\n\t}\n\treturn text;\n}\n\n/**\n * Convert a BashExecutionMessage to user message text for LLM context.\n */\nexport function bashExecutionToText(msg: BashExecutionMessage): string {\n\treturn `Ran \\`${msg.command}\\`\\n${bashOutputToText(msg)}`;\n}\n\nexport function createBranchSummaryMessage(summary: string, fromId: string, timestamp: string): BranchSummaryMessage {\n\treturn {\n\t\trole: \"branchSummary\",\n\t\tsummary,\n\t\tfromId,\n\t\ttimestamp: new Date(timestamp).getTime(),\n\t};\n}\n\nexport function createCompactionSummaryMessage(\n\tsummary: string,\n\ttokensBefore: number | null,\n\ttimestamp: string,\n\tcustomInstructions?: string,\n\tretainedMessageCount?: number,\n): CompactionSummaryMessage {\n\treturn {\n\t\trole: \"compactionSummary\",\n\t\tsummary,\n\t\ttokensBefore,\n\t\tretainedMessageCount,\n\t\tcustomInstructions,\n\t\ttimestamp: new Date(timestamp).getTime(),\n\t};\n}\n\n/** Convert CustomMessageEntry to AgentMessage format */\nexport function createCustomMessage(\n\tcustomType: string,\n\tcontent: string | (TextContent | ImageContent)[],\n\tdisplay: boolean,\n\tdetails: unknown | undefined,\n\ttimestamp: string,\n): CustomMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType,\n\t\tcontent,\n\t\tdisplay,\n\t\tdetails,\n\t\ttimestamp: new Date(timestamp).getTime(),\n\t};\n}\n\nexport function createSessionSlashCommandMessage(\n\tcommand: SessionSlashCommand,\n\tdetails: Omit<SessionSlashCommandDetails, \"command\"> = {},\n\tdisplay = true,\n\ttimestamp = Date.now(),\n): SessionSlashCommandMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: SESSION_SLASH_COMMAND_CUSTOM_TYPE,\n\t\tcontent: command.text,\n\t\tdisplay,\n\t\tdetails: { ...details, command: { ...command } },\n\t\ttimestamp,\n\t};\n}\n\nexport function createSessionSlashCommandResultMessage(\n\tcontent: string,\n\tdetails: SessionSlashCommandResultDetails,\n\tdisplay = true,\n\ttimestamp = Date.now(),\n): SessionSlashCommandResultMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE,\n\t\tcontent,\n\t\tdisplay,\n\t\tdetails: { ...details, command: { ...details.command } },\n\t\ttimestamp,\n\t};\n}\n\nexport function createCompactionOutcomeMessage(\n\tcontent: string,\n\tdetails: CompactionOutcomeDetails,\n\tdisplay = true,\n\ttimestamp = Date.now(),\n): CompactionOutcomeMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: COMPACTION_OUTCOME_CUSTOM_TYPE,\n\t\tcontent,\n\t\tdisplay,\n\t\tdetails: { ...details },\n\t\ttimestamp,\n\t};\n}\n\nexport function createRefinementOutcomeMessage(\n\tresult: RefinementResult,\n\tdisplay = true,\n\ttimestamp = Date.now(),\n): RefinementOutcomeMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: REFINEMENT_OUTCOME_CUSTOM_TYPE,\n\t\tcontent: `Refinement complete: ${result.summary}`,\n\t\tdisplay,\n\t\tdetails: {\n\t\t\trefinementId: result.id,\n\t\t\tsummary: result.summary,\n\t\t\tscope: result.scope ?? \"local\",\n\t\t\t...(result.rollbackOf ? { rollbackOf: result.rollbackOf } : {}),\n\t\t\tedits: result.appliedEdits,\n\t\t},\n\t\ttimestamp,\n\t};\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction hasValidCustomMessageEnvelope(message: Record<string, unknown>, customType: string): boolean {\n\treturn (\n\t\tmessage.role === \"custom\" &&\n\t\tmessage.customType === customType &&\n\t\ttypeof message.content === \"string\" &&\n\t\ttypeof message.display === \"boolean\" &&\n\t\ttypeof message.timestamp === \"number\" &&\n\t\tNumber.isFinite(message.timestamp)\n\t);\n}\n\nexport function isSessionSlashCommand(value: unknown): value is SessionSlashCommand {\n\tif (\n\t\t!isRecord(value) ||\n\t\t!isSessionSlashCommandName(value.name) ||\n\t\ttypeof value.args !== \"string\" ||\n\t\ttypeof value.text !== \"string\"\n\t) {\n\t\treturn false;\n\t}\n\tconst parsed = parseSessionSlashCommand(value.text);\n\treturn (\n\t\tparsed !== undefined && parsed.name === value.name && parsed.args === value.args && parsed.text === value.text\n\t);\n}\n\nfunction isValidCommandEntryId(value: unknown): value is string | undefined {\n\treturn value === undefined || (typeof value === \"string\" && value.length > 0);\n}\n\nexport function isSessionSlashCommandMessage(message: unknown): message is SessionSlashCommandMessage {\n\tif (\n\t\t!isRecord(message) ||\n\t\t!hasValidCustomMessageEnvelope(message, SESSION_SLASH_COMMAND_CUSTOM_TYPE) ||\n\t\ttypeof message.content !== \"string\"\n\t) {\n\t\treturn false;\n\t}\n\tif (!isRecord(message.details) || !isSessionSlashCommand(message.details.command)) return false;\n\treturn message.content === message.details.command.text && isValidCommandEntryId(message.details.commandEntryId);\n}\n\nexport function isSessionSlashCommandResultMessage(message: unknown): message is SessionSlashCommandResultMessage {\n\tif (!isRecord(message) || !hasValidCustomMessageEnvelope(message, SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE))\n\t\treturn false;\n\tif (!isRecord(message.details) || !isSessionSlashCommand(message.details.command)) return false;\n\treturn (\n\t\ttypeof message.details.success === \"boolean\" &&\n\t\t(message.details.severity === \"info\" ||\n\t\t\tmessage.details.severity === \"warning\" ||\n\t\t\tmessage.details.severity === \"error\") &&\n\t\t(message.details.error === undefined || typeof message.details.error === \"string\") &&\n\t\tisValidCommandEntryId(message.details.commandEntryId)\n\t);\n}\n\nexport function isCompactionOutcomeMessage(message: unknown): message is CompactionOutcomeMessage {\n\tif (!isRecord(message) || !hasValidCustomMessageEnvelope(message, COMPACTION_OUTCOME_CUSTOM_TYPE)) return false;\n\tif (!isRecord(message.details)) return false;\n\treturn (\n\t\t(message.details.reason === \"threshold\" ||\n\t\t\tmessage.details.reason === \"overflow\" ||\n\t\t\tmessage.details.reason === \"requested\") &&\n\t\t(message.details.outcome === \"skipped\" ||\n\t\t\tmessage.details.outcome === \"cancelled\" ||\n\t\t\tmessage.details.outcome === \"failed\")\n\t);\n}\n\nfunction isAppliedRefinementEdit(value: unknown): value is AppliedRefinementEdit {\n\treturn (\n\t\tisRecord(value) &&\n\t\t(value.action === \"create\" || value.action === \"update\" || value.action === \"delete\") &&\n\t\ttypeof value.kind === \"string\" &&\n\t\ttypeof value.id === \"string\" &&\n\t\ttypeof value.applied === \"boolean\"\n\t);\n}\n\nexport function isRefinementOutcomeMessage(message: unknown): message is RefinementOutcomeMessage {\n\tif (!isRecord(message) || !hasValidCustomMessageEnvelope(message, REFINEMENT_OUTCOME_CUSTOM_TYPE)) return false;\n\tif (!isRecord(message.details)) return false;\n\treturn (\n\t\ttypeof message.details.summary === \"string\" &&\n\t\t(message.details.scope === \"local\" || message.details.scope === \"global\") &&\n\t\tArray.isArray(message.details.edits) &&\n\t\tmessage.details.edits.every(isAppliedRefinementEdit)\n\t);\n}\n\nexport function createHeartbeatPromptMessage(\n\tjob: AgentCronJob,\n\ttimestamp = Date.now(),\n): CustomMessage<HeartbeatPromptDetails> {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: HEARTBEAT_PROMPT_CUSTOM_TYPE,\n\t\tcontent: job.prompt,\n\t\tdisplay: true,\n\t\tdetails: {\n\t\t\tjobId: job.id,\n\t\t\tschedule: job.schedule.expression,\n\t\t\tstatus: job.status,\n\t\t\trunCount: job.runCount,\n\t\t\tnextRunAt: job.nextRunAt,\n\t\t\tlastRunAt: job.lastRunAt,\n\t\t},\n\t\ttimestamp,\n\t};\n}\n\n/**\n * Transform AgentMessages (including custom types) to LLM-compatible Messages.\n *\n * This is used by:\n * - Agent's transormToLlm option (for prompt calls and queued messages)\n * - Compaction's generateSummary (for summarization)\n * - Custom extensions and tools\n */\nexport function convertToLlm(messages: AgentMessage[]): Message[] {\n\treturn messages\n\t\t.map((m): Message | undefined => {\n\t\t\tswitch (m.role) {\n\t\t\t\tcase \"bashExecution\":\n\t\t\t\t\tif (m.excludeFromContext) {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: bashExecutionToText(m) }],\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\tcase \"custom\": {\n\t\t\t\t\tif (\n\t\t\t\t\t\tm.customType === SESSION_SLASH_COMMAND_CUSTOM_TYPE ||\n\t\t\t\t\t\tm.customType === SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE ||\n\t\t\t\t\t\tm.customType === COMPACTION_OUTCOME_CUSTOM_TYPE ||\n\t\t\t\t\t\tm.customType === REFINEMENT_OUTCOME_CUSTOM_TYPE\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t\tconst content = typeof m.content === \"string\" ? [{ type: \"text\" as const, text: m.content }] : m.content;\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent,\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tcase \"branchSummary\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [{ type: \"text\" as const, text: BRANCH_SUMMARY_PREFIX + m.summary + BRANCH_SUMMARY_SUFFIX }],\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\tcase \"compactionSummary\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{ type: \"text\" as const, text: COMPACTION_SUMMARY_PREFIX + m.summary + COMPACTION_SUMMARY_SUFFIX },\n\t\t\t\t\t\t],\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\tcase \"user\":\n\t\t\t\tcase \"assistant\":\n\t\t\t\tcase \"toolResult\":\n\t\t\t\t\treturn m;\n\t\t\t\tdefault:\n\t\t\t\t\t// biome-ignore lint/correctness/noSwitchDeclarations: fine\n\t\t\t\t\tconst _exhaustiveCheck: never = m;\n\t\t\t\t\treturn undefined;\n\t\t\t}\n\t\t})\n\t\t.filter((m) => m !== undefined);\n}\n"]}
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/core/messages.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Custom message types and transformers for the coding agent.\n *\n * Extends the base AgentMessage type with coding-agent specific message types,\n * and provides a transformer to convert them to LLM-compatible messages.\n */\n\nimport type { AgentMessage } from \"@ponythewhite/base-context-agent\";\nimport type { ImageContent, Message, TextContent } from \"@ponythewhite/base-context-ai\";\nimport type { AgentCronJob } from \"./cron-jobs.js\";\nimport type { AppliedRefinementEdit, HarnessScope, RefinementResult } from \"./refinement/refinement.js\";\nimport { isSessionSlashCommandName, parseSessionSlashCommand, type SessionSlashCommand } from \"./slash-commands.js\";\n\nexport const COMPACTION_SUMMARY_PREFIX = `The conversation history before this point was compacted into the following summary:\n\n<summary>\n`;\n\nexport const COMPACTION_SUMMARY_SUFFIX = `\n</summary>`;\n\nexport const BRANCH_SUMMARY_PREFIX = `The following is a summary of a branch that this conversation came back from:\n\n<summary>\n`;\n\nexport const BRANCH_SUMMARY_SUFFIX = `</summary>`;\n\nexport const HEARTBEAT_PROMPT_CUSTOM_TYPE = \"heartbeat_prompt\";\nexport const HEARTBEAT_PROMPT_PREVIEW_LABEL = \"Heartbeat prompt\";\nexport const IPYTHON_STATE_RESTORED_CUSTOM_TYPE = \"ipython_state_restored\";\nexport const SESSION_SLASH_COMMAND_CUSTOM_TYPE = \"session_slash_command\";\nexport const SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE = \"session_slash_command_result\";\nexport const COMPACTION_OUTCOME_CUSTOM_TYPE = \"compaction_outcome\";\nexport const REFINEMENT_OUTCOME_CUSTOM_TYPE = \"refinement_outcome\";\nexport const RLM_CHILD_FAILURE_CUSTOM_TYPE = \"rlm_child_failure\";\nexport const RLM_CHILD_TERMINAL_NOTICE_CUSTOM_TYPE = \"rlm_child_terminal_notice\";\n\nexport interface SessionSlashCommandDetails {\n\tcommand: SessionSlashCommand;\n\tcommandEntryId?: string;\n}\n\nexport interface SessionSlashCommandResultDetails {\n\tcommand: SessionSlashCommand;\n\tsuccess: boolean;\n\tseverity: \"info\" | \"warning\" | \"error\";\n\terror?: string;\n\tcommandEntryId?: string;\n}\n\nexport interface SessionSlashCommandMessage extends CustomMessage<SessionSlashCommandDetails> {\n\tcustomType: typeof SESSION_SLASH_COMMAND_CUSTOM_TYPE;\n\tcontent: string;\n\tdetails: SessionSlashCommandDetails;\n}\n\nexport interface SessionSlashCommandResultMessage extends CustomMessage<SessionSlashCommandResultDetails> {\n\tcustomType: typeof SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE;\n\tcontent: string;\n\tdetails: SessionSlashCommandResultDetails;\n}\n\nexport type CompactionOutcomeReason = \"threshold\" | \"overflow\" | \"requested\";\nexport type CompactionOutcome = \"skipped\" | \"cancelled\" | \"failed\";\n\nexport interface CompactionOutcomeDetails {\n\treason: CompactionOutcomeReason;\n\toutcome: CompactionOutcome;\n}\n\nexport interface CompactionOutcomeMessage extends CustomMessage<CompactionOutcomeDetails> {\n\tcustomType: typeof COMPACTION_OUTCOME_CUSTOM_TYPE;\n\tcontent: string;\n\tdetails: CompactionOutcomeDetails;\n}\n\nexport interface RefinementOutcomeDetails {\n\trefinementId: string;\n\tsummary: string;\n\tscope: HarnessScope;\n\trollbackOf?: string;\n\tedits: AppliedRefinementEdit[];\n}\n\nexport interface RefinementOutcomeMessage extends CustomMessage<RefinementOutcomeDetails> {\n\tcustomType: typeof REFINEMENT_OUTCOME_CUSTOM_TYPE;\n\tcontent: string;\n\tdetails: RefinementOutcomeDetails;\n}\n\nexport interface RlmChildFailureDetails {\n\tchildId: string;\n\tsessionName: string;\n\terror: string;\n}\n\nexport type RlmChildTerminalNoticeDetails =\n\t| {\n\t\t\tkind: \"cancelled\";\n\t\t\tchildId: string;\n\t\t\tsessionName: string;\n\t\t\treason?: string;\n\t }\n\t| {\n\t\t\tkind: \"completed_without_reply\";\n\t\t\tchildId: string;\n\t\t\tsessionName: string;\n\t\t\tlastAssistantTextPreview?: string;\n\t };\n\nexport function createRlmChildFailureMessage(\n\tdetails: RlmChildFailureDetails,\n\ttimestamp = Date.now(),\n): CustomMessage<RlmChildFailureDetails> {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: RLM_CHILD_FAILURE_CUSTOM_TYPE,\n\t\tcontent: `RLM child ${details.sessionName} (${details.childId}) failed: ${details.error}`,\n\t\tdisplay: true,\n\t\tdetails,\n\t\ttimestamp,\n\t};\n}\n\nexport function createRlmChildTerminalNoticeMessage(\n\tdetails: RlmChildTerminalNoticeDetails,\n\ttimestamp = Date.now(),\n): CustomMessage<RlmChildTerminalNoticeDetails> {\n\tconst content =\n\t\tdetails.kind === \"cancelled\"\n\t\t\t? `RLM child ${details.sessionName} (${details.childId}) was cancelled${details.reason ? `: ${details.reason}` : \"\"}`\n\t\t\t: `RLM child ${details.sessionName} (${details.childId}) completed without sending a reply${details.lastAssistantTextPreview ? `. Last assistant text: ${details.lastAssistantTextPreview}` : \"\"}`;\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: RLM_CHILD_TERMINAL_NOTICE_CUSTOM_TYPE,\n\t\tcontent,\n\t\tdisplay: true,\n\t\tdetails,\n\t\ttimestamp,\n\t};\n}\n\n/**\n * Message type for bash executions via the ! command.\n */\nexport interface BashExecutionMessage {\n\trole: \"bashExecution\";\n\tcommand: string;\n\toutput: string;\n\texitCode: number | undefined;\n\tcancelled: boolean;\n\ttruncated: boolean;\n\tfullOutputPath?: string;\n\ttimestamp: number;\n\t/** If true, this message is excluded from LLM context (!! prefix) */\n\texcludeFromContext?: boolean;\n}\n\n/**\n * Message type for extension-injected messages via sendMessage().\n * These are custom messages that extensions can inject into the conversation.\n */\nexport interface CustomMessage<T = unknown> {\n\trole: \"custom\";\n\tcustomType: string;\n\tcontent: string | (TextContent | ImageContent)[];\n\tdisplay: boolean;\n\tdetails?: T;\n\ttimestamp: number;\n}\n\nexport interface HeartbeatPromptDetails {\n\tjobId: string;\n\tschedule: string;\n\tstatus: AgentCronJob[\"status\"];\n\trunCount: number;\n\tnextRunAt?: string;\n\tlastRunAt?: string;\n}\n\nexport interface IpythonStateRestoredDetails {\n\trestored: boolean;\n}\n\nexport interface BranchSummaryMessage {\n\trole: \"branchSummary\";\n\tsummary: string;\n\tfromId: string;\n\ttimestamp: number;\n}\n\nexport interface CompactionSummaryMessage {\n\trole: \"compactionSummary\";\n\tsummary: string;\n\t/** Prior-context estimate; null when it is unavailable. */\n\ttokensBefore: number | null;\n\t/** Number of retained messages that precede this summary in transcript presentation. */\n\tretainedMessageCount?: number;\n\t/** User instructions that guided the summary (from `/compact <instructions>`) */\n\tcustomInstructions?: string;\n\ttimestamp: number;\n}\n\ndeclare module \"@ponythewhite/base-context-agent\" {\n\tinterface CustomAgentMessages {\n\t\tbashExecution: BashExecutionMessage;\n\t\tcustom: CustomMessage;\n\t\tbranchSummary: BranchSummaryMessage;\n\t\tcompactionSummary: CompactionSummaryMessage;\n\t}\n}\n\n/**\n * Format bash output for LLM context. The fence must be longer than any\n * backtick run in the output so command output cannot terminate it early.\n */\nexport function bashOutputToText(\n\tmsg: Pick<BashExecutionMessage, \"output\" | \"exitCode\" | \"cancelled\" | \"truncated\" | \"fullOutputPath\">,\n): string {\n\tlet text = \"\";\n\tif (msg.output) {\n\t\tlet longestBacktickRun = 0;\n\t\tfor (const match of msg.output.matchAll(/`+/g)) {\n\t\t\tlongestBacktickRun = Math.max(longestBacktickRun, match[0].length);\n\t\t}\n\t\tconst fence = \"`\".repeat(Math.max(3, longestBacktickRun + 1));\n\t\ttext += `${fence}\\n${msg.output}\\n${fence}`;\n\t} else {\n\t\ttext += \"(no output)\";\n\t}\n\tif (msg.cancelled) {\n\t\ttext += \"\\n\\n(command cancelled)\";\n\t} else if (msg.exitCode !== null && msg.exitCode !== undefined && msg.exitCode !== 0) {\n\t\ttext += `\\n\\nCommand exited with code ${msg.exitCode}`;\n\t}\n\tif (msg.truncated) {\n\t\ttext += msg.fullOutputPath\n\t\t\t? `\\n\\n[Output truncated. Full output: ${msg.fullOutputPath}]`\n\t\t\t: \"\\n\\n[Output truncated.]\";\n\t}\n\treturn text;\n}\n\n/**\n * Convert a BashExecutionMessage to user message text for LLM context.\n */\nexport function bashExecutionToText(msg: BashExecutionMessage): string {\n\treturn `Ran \\`${msg.command}\\`\\n${bashOutputToText(msg)}`;\n}\n\nexport function createBranchSummaryMessage(summary: string, fromId: string, timestamp: string): BranchSummaryMessage {\n\treturn {\n\t\trole: \"branchSummary\",\n\t\tsummary,\n\t\tfromId,\n\t\ttimestamp: new Date(timestamp).getTime(),\n\t};\n}\n\nexport function createCompactionSummaryMessage(\n\tsummary: string,\n\ttokensBefore: number | null,\n\ttimestamp: string,\n\tcustomInstructions?: string,\n\tretainedMessageCount?: number,\n): CompactionSummaryMessage {\n\treturn {\n\t\trole: \"compactionSummary\",\n\t\tsummary,\n\t\ttokensBefore,\n\t\tretainedMessageCount,\n\t\tcustomInstructions,\n\t\ttimestamp: new Date(timestamp).getTime(),\n\t};\n}\n\n/** Convert CustomMessageEntry to AgentMessage format */\nexport function createCustomMessage(\n\tcustomType: string,\n\tcontent: string | (TextContent | ImageContent)[],\n\tdisplay: boolean,\n\tdetails: unknown | undefined,\n\ttimestamp: string,\n): CustomMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType,\n\t\tcontent,\n\t\tdisplay,\n\t\tdetails,\n\t\ttimestamp: new Date(timestamp).getTime(),\n\t};\n}\n\nexport function createSessionSlashCommandMessage(\n\tcommand: SessionSlashCommand,\n\tdetails: Omit<SessionSlashCommandDetails, \"command\"> = {},\n\tdisplay = true,\n\ttimestamp = Date.now(),\n): SessionSlashCommandMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: SESSION_SLASH_COMMAND_CUSTOM_TYPE,\n\t\tcontent: command.text,\n\t\tdisplay,\n\t\tdetails: { ...details, command: { ...command } },\n\t\ttimestamp,\n\t};\n}\n\nexport function createSessionSlashCommandResultMessage(\n\tcontent: string,\n\tdetails: SessionSlashCommandResultDetails,\n\tdisplay = true,\n\ttimestamp = Date.now(),\n): SessionSlashCommandResultMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE,\n\t\tcontent,\n\t\tdisplay,\n\t\tdetails: { ...details, command: { ...details.command } },\n\t\ttimestamp,\n\t};\n}\n\nexport function createCompactionOutcomeMessage(\n\tcontent: string,\n\tdetails: CompactionOutcomeDetails,\n\tdisplay = true,\n\ttimestamp = Date.now(),\n): CompactionOutcomeMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: COMPACTION_OUTCOME_CUSTOM_TYPE,\n\t\tcontent,\n\t\tdisplay,\n\t\tdetails: { ...details },\n\t\ttimestamp,\n\t};\n}\n\nexport function createRefinementOutcomeMessage(\n\tresult: RefinementResult,\n\tdisplay = true,\n\ttimestamp = Date.now(),\n): RefinementOutcomeMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: REFINEMENT_OUTCOME_CUSTOM_TYPE,\n\t\tcontent: `Refinement complete: ${result.summary}`,\n\t\tdisplay,\n\t\tdetails: {\n\t\t\trefinementId: result.id,\n\t\t\tsummary: result.summary,\n\t\t\tscope: result.scope ?? \"local\",\n\t\t\t...(result.rollbackOf ? { rollbackOf: result.rollbackOf } : {}),\n\t\t\tedits: result.appliedEdits,\n\t\t},\n\t\ttimestamp,\n\t};\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction hasValidCustomMessageEnvelope(message: Record<string, unknown>, customType: string): boolean {\n\treturn (\n\t\tmessage.role === \"custom\" &&\n\t\tmessage.customType === customType &&\n\t\ttypeof message.content === \"string\" &&\n\t\ttypeof message.display === \"boolean\" &&\n\t\ttypeof message.timestamp === \"number\" &&\n\t\tNumber.isFinite(message.timestamp)\n\t);\n}\n\nexport function isSessionSlashCommand(value: unknown): value is SessionSlashCommand {\n\tif (\n\t\t!isRecord(value) ||\n\t\t!isSessionSlashCommandName(value.name) ||\n\t\ttypeof value.args !== \"string\" ||\n\t\ttypeof value.text !== \"string\"\n\t) {\n\t\treturn false;\n\t}\n\tconst parsed = parseSessionSlashCommand(value.text);\n\treturn (\n\t\tparsed !== undefined && parsed.name === value.name && parsed.args === value.args && parsed.text === value.text\n\t);\n}\n\nfunction isValidCommandEntryId(value: unknown): value is string | undefined {\n\treturn value === undefined || (typeof value === \"string\" && value.length > 0);\n}\n\nexport function isSessionSlashCommandMessage(message: unknown): message is SessionSlashCommandMessage {\n\tif (\n\t\t!isRecord(message) ||\n\t\t!hasValidCustomMessageEnvelope(message, SESSION_SLASH_COMMAND_CUSTOM_TYPE) ||\n\t\ttypeof message.content !== \"string\"\n\t) {\n\t\treturn false;\n\t}\n\tif (!isRecord(message.details) || !isSessionSlashCommand(message.details.command)) return false;\n\treturn message.content === message.details.command.text && isValidCommandEntryId(message.details.commandEntryId);\n}\n\nexport function isSessionSlashCommandResultMessage(message: unknown): message is SessionSlashCommandResultMessage {\n\tif (!isRecord(message) || !hasValidCustomMessageEnvelope(message, SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE))\n\t\treturn false;\n\tif (!isRecord(message.details) || !isSessionSlashCommand(message.details.command)) return false;\n\treturn (\n\t\ttypeof message.details.success === \"boolean\" &&\n\t\t(message.details.severity === \"info\" ||\n\t\t\tmessage.details.severity === \"warning\" ||\n\t\t\tmessage.details.severity === \"error\") &&\n\t\t(message.details.error === undefined || typeof message.details.error === \"string\") &&\n\t\tisValidCommandEntryId(message.details.commandEntryId)\n\t);\n}\n\nexport function isCompactionOutcomeMessage(message: unknown): message is CompactionOutcomeMessage {\n\tif (!isRecord(message) || !hasValidCustomMessageEnvelope(message, COMPACTION_OUTCOME_CUSTOM_TYPE)) return false;\n\tif (!isRecord(message.details)) return false;\n\treturn (\n\t\t(message.details.reason === \"threshold\" ||\n\t\t\tmessage.details.reason === \"overflow\" ||\n\t\t\tmessage.details.reason === \"requested\") &&\n\t\t(message.details.outcome === \"skipped\" ||\n\t\t\tmessage.details.outcome === \"cancelled\" ||\n\t\t\tmessage.details.outcome === \"failed\")\n\t);\n}\n\nfunction isAppliedRefinementEdit(value: unknown): value is AppliedRefinementEdit {\n\treturn (\n\t\tisRecord(value) &&\n\t\t(value.action === \"create\" || value.action === \"update\" || value.action === \"delete\") &&\n\t\ttypeof value.kind === \"string\" &&\n\t\ttypeof value.id === \"string\" &&\n\t\ttypeof value.applied === \"boolean\"\n\t);\n}\n\nexport function isRefinementOutcomeMessage(message: unknown): message is RefinementOutcomeMessage {\n\tif (!isRecord(message) || !hasValidCustomMessageEnvelope(message, REFINEMENT_OUTCOME_CUSTOM_TYPE)) return false;\n\tif (!isRecord(message.details)) return false;\n\treturn (\n\t\ttypeof message.details.summary === \"string\" &&\n\t\t(message.details.scope === \"local\" || message.details.scope === \"global\") &&\n\t\tArray.isArray(message.details.edits) &&\n\t\tmessage.details.edits.every(isAppliedRefinementEdit)\n\t);\n}\n\nexport function createHeartbeatPromptMessage(\n\tjob: AgentCronJob,\n\ttimestamp = Date.now(),\n): CustomMessage<HeartbeatPromptDetails> {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: HEARTBEAT_PROMPT_CUSTOM_TYPE,\n\t\tcontent: job.prompt,\n\t\tdisplay: true,\n\t\tdetails: {\n\t\t\tjobId: job.id,\n\t\t\tschedule: job.schedule.expression,\n\t\t\tstatus: job.status,\n\t\t\trunCount: job.runCount,\n\t\t\tnextRunAt: job.nextRunAt,\n\t\t\tlastRunAt: job.lastRunAt,\n\t\t},\n\t\ttimestamp,\n\t};\n}\n\n/**\n * Transform AgentMessages (including custom types) to LLM-compatible Messages.\n *\n * This is used by:\n * - Agent's transormToLlm option (for prompt calls and queued messages)\n * - Compaction's generateSummary (for summarization)\n * - Custom extensions and tools\n */\nexport function convertToLlm(messages: AgentMessage[]): Message[] {\n\treturn messages\n\t\t.map((m): Message | undefined => {\n\t\t\tswitch (m.role) {\n\t\t\t\tcase \"bashExecution\":\n\t\t\t\t\tif (m.excludeFromContext) {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: bashExecutionToText(m) }],\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\tcase \"custom\": {\n\t\t\t\t\tif (\n\t\t\t\t\t\tm.customType === SESSION_SLASH_COMMAND_CUSTOM_TYPE ||\n\t\t\t\t\t\tm.customType === SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE ||\n\t\t\t\t\t\tm.customType === COMPACTION_OUTCOME_CUSTOM_TYPE ||\n\t\t\t\t\t\tm.customType === REFINEMENT_OUTCOME_CUSTOM_TYPE\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t\tconst content = typeof m.content === \"string\" ? [{ type: \"text\" as const, text: m.content }] : m.content;\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent,\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tcase \"branchSummary\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [{ type: \"text\" as const, text: BRANCH_SUMMARY_PREFIX + m.summary + BRANCH_SUMMARY_SUFFIX }],\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\tcase \"compactionSummary\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{ type: \"text\" as const, text: COMPACTION_SUMMARY_PREFIX + m.summary + COMPACTION_SUMMARY_SUFFIX },\n\t\t\t\t\t\t],\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\tcase \"assistant\":\n\t\t\t\t\t// Providers omit failed/aborted replies. Apply that same omission\n\t\t\t\t\t// before capturing the canonical-to-provider positions on resume.\n\t\t\t\t\treturn m.stopReason === \"error\" || m.stopReason === \"aborted\" ? undefined : m;\n\t\t\t\tcase \"user\":\n\t\t\t\tcase \"toolResult\":\n\t\t\t\t\treturn m;\n\t\t\t\tdefault:\n\t\t\t\t\t// biome-ignore lint/correctness/noSwitchDeclarations: fine\n\t\t\t\t\tconst _exhaustiveCheck: never = m;\n\t\t\t\t\treturn undefined;\n\t\t\t}\n\t\t})\n\t\t.filter((m) => m !== undefined);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"rlm.d.ts","sourceRoot":"","sources":["../../../src/core/prompts/rlm.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AA0CD,MAAM,WAAW,yBAAyB;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,yBAAyB,GAAG,MAAM,GAAG,SAAS,CAe9F;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CA6GhE;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACpC,OAAO,GAAE;IAAE,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IAAC,eAAe,CAAC,EAAE,OAAO,CAAA;CAAO,GACrG,MAAM,CAuBR","sourcesContent":["import { DEFAULT_RLM_EXTRA_IMPORT_LABELS } from \"../kernel/bootstrap.js\";\n\nexport interface RlmPromptOptions {\n\tcwd: string;\n\tskillsDir?: string;\n\tinstalledSkills?: string[];\n\tmessagesPath: string;\n\tallowRecursion?: boolean;\n\tdepth?: number;\n\tparentAgent?: string;\n\tactiveTools?: string[];\n}\n\nconst LONG_RUNNING_WORK_PROMPT = [\n\t\"For slow or independently completing work, use a nonblocking control loop: start the work, record its handle or output location, then end your turn. Read the result on a later turn or when a reply arrives.\",\n\t\"When delegation is available and useful, assign independent substantive tasks to separate workers. Start independent workers without waiting for each one sequentially, and let them run in parallel.\",\n\t\"Do not keep the turn open by polling with `time.sleep()` or shell `sleep`, and do not replace polling with a long blocking `await`. Await only the short operation needed to start work or inspect a result that is already available; otherwise end the turn.\",\n].join(\"\\n\");\n\nconst USER_PROGRESS_PROMPT =\n\t\"As the user-facing root agent, when work follows a plan, uses many subagents, or spans multiple turns, proactively give regular concise progress updates so the user does not have to ask. State the current plan, what has completed, any blockers, the proposed fixes, and the next actions. Lead with user-visible outcomes rather than internal process or gate names. Mention internal details only when they explain a blocker or decision. Send an update at meaningful milestones and before ending a turn while work is still running. Do not repeat unchanged status or interrupt short work with unnecessary updates.\";\n\nconst SIMPLIFIED_TECHNICAL_ENGLISH_PROMPT = [\n\t\"Use simplified technical English by default for user-facing prose.\",\n\t\"Prefer short sentences, common words, and concrete verbs. State one main action or fact per sentence when practical. Use lists for steps or conditions.\",\n\t\"Keep necessary technical terms, names, commands, code, paths, and exact quoted text unchanged. State uncertainty directly.\",\n\t\"Treat this as clarity guidance, not a claim of formal ASD-STE100 compliance. Preserve a user-requested format, tone, terminology, and necessary precision.\",\n].join(\"\\n\");\n\nconst REPL_CONTROL_PROMPT = [\n\t\"The `ipython` tool is a persistent Python REPL — the agent's long-lived control environment for reasoning, context management, state, tool orchestration, and recursive subcalls. Top-level `await` works directly. Use it to keep intermediate variables, inspect and transform outputs, and write small helper functions. Compaction removes individual variables whose serialized form exceeds 16 MiB; keep large source data on disk and reload it when needed.\",\n\t\"\",\n\t\"Python is the orchestration language: use Python for loops, conditionals, parsing, and state. Use `bash()` to invoke programs, not to write shell programs — no shell loops or heredocs; do those in Python.\",\n\t\"\",\n\t\"Do not assume the REPL is the native runtime of the external thing being investigated. A repository, package, service, dataset, paper, website, benchmark, or API may have its own environment and normal interface. Evaluate external systems through their own interface, then use the REPL to coordinate the process and analyze what comes back.\",\n\t\"\",\n\t\"`bash(command)` starts a shell command in the background and returns a handle immediately: `h = bash('npm test')`. Use `h.pid` / `h.running` for liveness, `h.tail(n)` / `h.output()` for combined stdout+stderr so far, `h.poll()` for a non-blocking result, `h.kill()` to terminate (SIGTERM, escalating to SIGKILL; on Windows kill() uses taskkill /T and detached or reparented descendants may survive), and `await h` (or `await bash('cmd')`) for the completed result with exit_code, output, and duration. Prefer bash() for long-running commands so the turn keeps working. Run shell commands with `bash()`, not `subprocess`/`os.system`: subprocess calls block the kernel, show the user nothing while they run, and spawn processes the harness cannot see or stop.\",\n\t\"\",\n\t\"Important: do not install dependencies into the kernel just to make an external project import or run there. If a project import, test, script, CLI, or dependency check is needed, run it through that project's own environment and normal command interface. For example, in a Python repo use its documented commands, `uv run ...`, `.venv/bin/python ...`, or the active project interpreter from the repo root. Treat failures from that native environment as the relevant result.\",\n\t\"\",\n\t\"Use Python for reading, searching, and editing files — it gives you reusable variables you can slice, filter, and act on without re-reading. Always assign read/search results to named variables so you can revisit them later.\",\n\t\"\",\n\t\"Each `bash()` call is its own process, so shell state does not persist between calls; use `os.chdir(...)` for the working directory and `os.environ[...]` for environment variables — both persist in the REPL and apply to later `bash()` calls.\",\n\t\"\",\n\t\"Python state in the kernel persists across cells: named variables, helper functions, classes, imports, notes, parsed outputs, and helper data structures all remain available in every later turn. Tool calls are themselves Python `await` expressions, so their return values can be bound to variables and composed into program logic just like any other call.\",\n\t\"\",\n\t\"Continual harness state is available as `rlm.harness` and `rlm.get_harness_state()`. CRUD calls are local to this Base Context session by default: `rlm.harness.create_memory(...)`, `rlm.harness.update_memory(...)`, `rlm.harness.delete_memory(...)`, `rlm.harness.create_skill(...)`, `rlm.harness.update_skill(...)`, `rlm.harness.delete_skill(...)`, `rlm.harness.create_subagent(...)`, `rlm.harness.update_subagent(...)`, `rlm.harness.delete_subagent(...)`, `rlm.harness.create_prompt_note(...)`, `rlm.harness.update_prompt_note(...)`, `rlm.harness.delete_prompt_note(...)`, plus `rlm.harness.record_refinement(...)` and `rlm.harness.overview()`. Use `global_=True` only for stable cross-session lessons; Python reserves `global`, so literal `global=True` is invalid syntax.\",\n\t\"\",\n\t\"Terminology: continual harness names the persisted prompt, memory, skill, and subagent layer; RLM names the runtime, Python REPL kernel, and native call interface exposed to the model.\",\n\t\"\",\n\t\"RLM-native call contract: installed Python skills are pre-imported modules. Read the matching SKILL.md and call its documented function, such as `await <skill_import>.<function>(...)`; when a CLI exists, use `<skill_import> ...` from shell. Continual harness skill entries are Python REPL skills with an explicit Python `reference` and `arguments` contract. Spawn a reusable delegation spec with `await rlm('sub-task')`; admission returns a child handle immediately. Results arrive only through an available messaging capability or files, never as an `rlm()` return value. Do not invent non-native wrappers such as `call_skill(...)` or `run_subagent(...)`.\",\n].join(\"\\n\");\n\nexport interface ChildAgentDoctrineOptions {\n\tdepth?: number;\n\tparentAgent?: string;\n\tinstalledSkills?: string[];\n\tactiveTools?: string[];\n}\n\nexport function buildChildAgentDoctrine(options: ChildAgentDoctrineOptions): string | undefined {\n\tconst depth = options.depth ?? 0;\n\tconst hasIpython = options.activeTools === undefined || options.activeTools.includes(\"ipython\");\n\tconst hasAgentMessage = options.installedSkills?.includes(\"agent_message\") ?? false;\n\tif (depth <= 0) return undefined;\n\n\tconst lines = [\n\t\t`You are a child agent spawned by ${options.parentAgent ?? \"your parent agent\"}. Task prompts are labeled \\`[task from parent]\\`.`,\n\t];\n\tif (hasAgentMessage && hasIpython) {\n\t\tlines.push(\n\t\t\t'When a task calls for an answer, reply explicitly with `await agent_message.send(message, receiver_role=\"parent\")`. Not every message or task needs a reply; continue cleanup after sending and go idle normally.',\n\t\t);\n\t}\n\treturn lines.join(\"\\n\");\n}\n\nexport function buildRlmPrompt(options: RlmPromptOptions): string {\n\tconst { cwd, skillsDir, messagesPath } = options;\n\tconst installedSkills = options.installedSkills ?? [];\n\tconst hasAgentMessage = installedSkills.includes(\"agent_message\");\n\tconst hasAgentObserve = installedSkills.includes(\"agent_observe\");\n\tconst allowRecursion = options.allowRecursion ?? true;\n\tconst depth = options.depth ?? 0;\n\tconst activeTools = options.activeTools ?? [];\n\tconst hasIpython = options.activeTools === undefined ? true : activeTools.includes(\"ipython\");\n\tconst canRunShellSkills = hasIpython || activeTools.includes(\"bash\");\n\tconst parts = [\n\t\t\"You are a general purpose agent that uses code to solve tasks.\",\n\t\t\"You solve tasks by breaking down problems into sub-tasks, writing and executing code, observing results, and iterating one step at a time.\",\n\t\t\"When you are done, stop calling tools and state your final answer.\",\n\t\t\"\",\n\t\tLONG_RUNNING_WORK_PROMPT,\n\t\t\"\",\n\t\t...(depth === 0 ? [USER_PROGRESS_PROMPT, \"\"] : []),\n\t\tSIMPLIFIED_TECHNICAL_ENGLISH_PROMPT,\n\t\t\"\",\n\t\t`Working directory: ${cwd}`,\n\t\t`Conversation log: ${messagesPath}`,\n\t\t`Recursive agent depth: ${depth}`,\n\t\t`Pre-installed Python packages: ${DEFAULT_RLM_EXTRA_IMPORT_LABELS.join(\", \")}.`,\n\t\t\"Install additional packages with `uv pip install <pkg>` (this is a uv-managed venv with no pip module).\",\n\t];\n\n\tconst childDoctrine = buildChildAgentDoctrine(options);\n\tif (childDoctrine) {\n\t\tparts.push(\"\", childDoctrine);\n\t}\n\n\tconst skillLines: string[] = [];\n\tif (skillsDir) {\n\t\tskillLines.push(`Local skills live under ${skillsDir}. Read their SKILL.md files when helpful.`);\n\t}\n\tif (installedSkills.length > 0) {\n\t\tconst installed = installedSkills.map((skill) => `\\`${skill}\\``).join(\", \");\n\t\tif (hasIpython) {\n\t\t\tskillLines.push(`Installed Python skill modules (pre-imported): ${installed}.`);\n\t\t\tskillLines.push(\n\t\t\t\t\"Read each skill's SKILL.md for its API. Inspect a module with `help(<skill>)` or `dir(<skill>)`, then inspect a documented callable with `inspect.signature(<skill>.<function>)`.\",\n\t\t\t);\n\t\t} else if (canRunShellSkills) {\n\t\t\tskillLines.push(`Installed skills available as shell commands: ${installed}.`);\n\t\t}\n\t\tif (canRunShellSkills) {\n\t\t\tskillLines.push(\n\t\t\t\t\"Each skill is also available as a shell command by the same name: `<skill> ...`. Discover its CLI usage with `<skill> --help`.\",\n\t\t\t);\n\t\t}\n\t\tif (hasIpython && installedSkills.includes(\"edit\")) {\n\t\t\tskillLines.push(\n\t\t\t\t\"For targeted existing-file edits, prefer the pre-imported async `edit` skill from the REPL: `old = '''...'''; new = '''...'''; await edit(path=\\\"pkg/file.py\\\", old_str=old, new_str=new)`. Use exact old/new strings; if the text contains triple double quotes, use triple single-quoted variables or build `old`/`new` from inspected file slices.\",\n\t\t\t);\n\t\t}\n\t}\n\tif (skillLines.length > 0) {\n\t\tparts.push(\"\", ...skillLines);\n\t}\n\tif (hasAgentMessage) {\n\t\tparts.push(\n\t\t\t\"Agent messaging is restricted to your parent, siblings, and direct children; roots are siblings, and deeper communication relays through the intermediate child.\",\n\t\t);\n\t}\n\tif (hasAgentObserve) {\n\t\tparts.push(\n\t\t\t\"Agent observation is restricted to your parent, siblings, and direct children; roots are siblings, and deeper inspection relays through the intermediate child.\",\n\t\t);\n\t}\n\n\tif (allowRecursion && hasIpython) {\n\t\tparts.push(\n\t\t\t\"\",\n\t\t\t\"A callable `rlm` is already in your global namespace. `await rlm('sub-task')` spawns a child and returns immediately after task admission with `rlm_child_id`, `name`, `session_dir`, and `model`; it never waits for or returns the child's answer.\",\n\t\t\t\"Choose a stable child name with `await rlm('sub-task', name='api-reviewer')`; names must be unique among siblings. If omitted, the host generates a readable unique name.\",\n\t\t\t\"A child inherits your model. If a different model is explicitly requested, use `await rlm.find_models(...)` and an exact returned selector. An unavailable requested model fails spawn; decide whether to retry or omit `model`. Children also inherit your thinking level; the `thinking` option overrides it with any level the resolved child model supports, and an unsupported level fails spawn.\",\n\t\t);\n\t\tif (hasAgentMessage) {\n\t\t\tparts.push(\n\t\t\t\t\"Children reply explicitly with `await agent_message.send(message, receiver_role='parent')` when an answer is needed. Replies and follow-ups arrive as ordinary agent messages; not every task requires a reply.\",\n\t\t\t\t\"Use `await agent_message.list_agents()` to discover family and `await rlm.list_subagents()` to recover direct child handles. Use `agent_message.send(..., receiver_role='child', receiver_name=child.name)` for follow-ups.\",\n\t\t\t);\n\t\t} else {\n\t\t\tparts.push(\"Use `await rlm.list_subagents()` to recover direct child handles after admission.\");\n\t\t}\n\t\tif (hasAgentObserve) {\n\t\t\tparts.push(\n\t\t\t\t\"Use `agent_observe` to inspect a child's rollout. Observation is restricted to your parent, siblings, and direct children; relay through the intermediate child for deeper descendants.\",\n\t\t\t);\n\t\t} else {\n\t\t\tparts.push(\"Inspect files a child wrote when you need to collect its work without an observation capability.\");\n\t\t}\n\t\tparts.push(\n\t\t\t\"Spawn independent children in separate calls and end your turn instead of awaiting completion. Multiple replies may arrive over multiple turns. Delete a direct child explicitly with `await rlm.delete_subagent(child)` when it is no longer needed.\",\n\t\t);\n\t}\n\n\tif (hasIpython) {\n\t\tparts.push(\"\", REPL_CONTROL_PROMPT);\n\t\tif (installedSkills.includes(\"refine\")) {\n\t\t\tparts.push(\n\t\t\t\t\"\",\n\t\t\t\t\"Treat continual harness refinement as a small, evidence-backed update after observing a repeated failure or reusable tactic: diagnose the issue, update the smallest relevant continual harness component, validate on the next action, then record the outcome. Use `await refine.run()` to turn repeated delegation patterns into reusable subagent specs, repeated procedures into skills, durable facts/preferences into memories, and narrow behavioral policies into prompt addendums. It returns immediately and runs when the current turn ends, so continue working normally after calling it. Do not rewrite the whole continual harness when a focused memory, skill, prompt note, or subagent spec is enough.\",\n\t\t\t);\n\t\t}\n\t}\n\n\treturn parts.join(\"\\n\");\n}\n\n/**\n * Supplemental sub-agent delegation guidance, appended after the base RLM\n * prompt (see system-prompt.ts). The recursion block covers the mechanics\n * (`rlm(...)` admission and handle management); this block adds the\n * when and why in the same When -> Why -> menu order Claude Code's Agent tool\n * uses. The subagent-spec menu itself renders just after this, inside the\n * harness-state block.\n */\nexport function buildSubagentGuidance(\n\toptions: { includeRefineExamples?: boolean; hasAgentMessage?: boolean; hasAgentObserve?: boolean } = {},\n): string {\n\tconst lines = [\n\t\t\"# Delegating to sub-agents\",\n\t\t\"\",\n\t\t\"Spawn independent, self-contained work with `handle = await rlm('task', name='worker')`. This returns at admission, not completion; keep the handle to stop or inspect the child later.\",\n\t];\n\tif (options.hasAgentMessage) {\n\t\tlines.push(\n\t\t\t\"Ask for an explicit reply when needed. A child replies with `await agent_message.send(message, receiver_role='parent')`; parent follow-ups use `receiver_role='child'` plus the child's name or id. Not every message needs a reply.\",\n\t\t);\n\t}\n\tlines.push(\"Use `await rlm.list_subagents()` after kernel restart or compaction.\");\n\tif (options.hasAgentObserve) {\n\t\tlines.push(\"Use `agent_observe` for bounded transcript inspection.\");\n\t}\n\tlines.push(\n\t\t\"Have children write files and read those files for fan-in.\",\n\t\t\"Delegate parallel context-heavy research or independent implementation; do a single known lookup, edit, or command inline.\",\n\t);\n\tif (options.includeRefineExamples ?? true) {\n\t\tlines.push(\"Persist genuinely reusable delegation patterns with `await refine.run()`.\");\n\t}\n\treturn lines.join(\"\\n\");\n}\n"]}
1
+ {"version":3,"file":"rlm.d.ts","sourceRoot":"","sources":["../../../src/core/prompts/rlm.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AA4CD,MAAM,WAAW,yBAAyB;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,yBAAyB,GAAG,MAAM,GAAG,SAAS,CAe9F;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CA6GhE;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACpC,OAAO,GAAE;IAAE,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IAAC,eAAe,CAAC,EAAE,OAAO,CAAA;CAAO,GACrG,MAAM,CAuBR","sourcesContent":["import { DEFAULT_RLM_EXTRA_IMPORT_LABELS } from \"../kernel/bootstrap.js\";\n\nexport interface RlmPromptOptions {\n\tcwd: string;\n\tskillsDir?: string;\n\tinstalledSkills?: string[];\n\tmessagesPath: string;\n\tallowRecursion?: boolean;\n\tdepth?: number;\n\tparentAgent?: string;\n\tactiveTools?: string[];\n}\n\nconst LONG_RUNNING_WORK_PROMPT = [\n\t\"For slow or independently completing work, use a nonblocking control loop: start the work, record its handle or output location, then end your turn. Read the result on a later turn or when a reply arrives.\",\n\t\"When delegation is available and useful, assign independent substantive tasks to separate workers. Start independent workers without waiting for each one sequentially, and let them run in parallel.\",\n\t\"Do not keep the turn open by polling with `time.sleep()` or shell `sleep`, and do not replace polling with a long blocking `await`. Await only the short operation needed to start work or inspect a result that is already available; otherwise end the turn.\",\n].join(\"\\n\");\n\nconst USER_PROGRESS_PROMPT =\n\t\"As the user-facing root agent, when work follows a plan, uses many subagents, or spans multiple turns, proactively give regular concise progress updates so the user does not have to ask. State the current plan, what has completed, any blockers, the proposed fixes, and the next actions. Lead with user-visible outcomes rather than internal process or gate names. Mention internal details only when they explain a blocker or decision. Send an update at meaningful milestones and before ending a turn while work is still running. Do not repeat unchanged status or interrupt short work with unnecessary updates.\";\n\nconst SIMPLIFIED_TECHNICAL_ENGLISH_PROMPT = [\n\t\"Use simplified technical English by default for user-facing prose.\",\n\t\"Prefer short sentences, common words, and concrete verbs. State one main action or fact per sentence when practical. Use lists for steps or conditions.\",\n\t\"Keep necessary technical terms, names, commands, code, paths, and exact quoted text unchanged. State uncertainty directly.\",\n\t\"Treat this as clarity guidance, not a claim of formal ASD-STE100 compliance. Preserve a user-requested format, tone, terminology, and necessary precision.\",\n].join(\"\\n\");\n\nconst REPL_CONTROL_PROMPT = [\n\t\"The `ipython` tool is a persistent Python REPL — the agent's long-lived control environment for reasoning, context management, state, tool orchestration, and recursive subcalls. Top-level `await` works directly. Use it to keep intermediate variables, inspect and transform outputs, and write small helper functions. Compaction removes individual variables whose serialized form exceeds 16 MiB; keep large source data on disk and reload it when needed.\",\n\t\"\",\n\t\"Reuse a named Python function for repeated multi-step work; keep one-off operations inline. Pass changing inputs explicitly and read current data each call. Save cross-task helpers as editable .py files with short project-skill instructions, without packaging them. After editing loaded code, execute its updated definition or invoke the saved file afresh.\",\n\t\"\",\n\t\"Python is the orchestration language: use Python for loops, conditionals, parsing, and state. Use `bash()` to invoke programs, not to write shell programs — no shell loops or heredocs; do those in Python.\",\n\t\"\",\n\t\"Do not assume the REPL is the native runtime of the external thing being investigated. A repository, package, service, dataset, paper, website, benchmark, or API may have its own environment and normal interface. Evaluate external systems through their own interface, then use the REPL to coordinate the process and analyze what comes back.\",\n\t\"\",\n\t\"`bash(command)` starts a shell command in the background and returns a handle immediately: `h = bash('npm test')`. Use `h.pid` / `h.running` for liveness, `h.tail(n)` / `h.output()` for combined stdout+stderr so far, `h.poll()` for a non-blocking result, `h.kill()` to terminate (SIGTERM, escalating to SIGKILL; on Windows kill() uses taskkill /T and detached or reparented descendants may survive), and `await h` (or `await bash('cmd')`) for the completed result with exit_code, output, and duration. Prefer bash() for long-running commands so the turn keeps working. Run shell commands with `bash()`, not `subprocess`/`os.system`: subprocess calls block the kernel, show the user nothing while they run, and spawn processes the harness cannot see or stop.\",\n\t\"\",\n\t\"Important: do not install dependencies into the kernel just to make an external project import or run there. If a project import, test, script, CLI, or dependency check is needed, run it through that project's own environment and normal command interface. For example, in a Python repo use its documented commands, `uv run ...`, `.venv/bin/python ...`, or the active project interpreter from the repo root. Treat failures from that native environment as the relevant result.\",\n\t\"\",\n\t\"Use Python for reading, searching, and editing files — it gives you reusable variables you can slice, filter, and act on without re-reading. Always assign read/search results to named variables so you can revisit them later.\",\n\t\"\",\n\t\"Each `bash()` call is its own process, so shell state does not persist between calls; use `os.chdir(...)` for the working directory and `os.environ[...]` for environment variables — both persist in the REPL and apply to later `bash()` calls.\",\n\t\"\",\n\t\"Python state in the kernel persists across cells: named variables, helper functions, classes, imports, notes, parsed outputs, and helper data structures all remain available in every later turn. Tool calls are themselves Python `await` expressions, so their return values can be bound to variables and composed into program logic just like any other call.\",\n\t\"\",\n\t\"Continual harness state is available as `rlm.harness` and `rlm.get_harness_state()`. CRUD calls are local to this Base Context session by default: `rlm.harness.create_memory(...)`, `rlm.harness.update_memory(...)`, `rlm.harness.delete_memory(...)`, `rlm.harness.create_skill(...)`, `rlm.harness.update_skill(...)`, `rlm.harness.delete_skill(...)`, `rlm.harness.create_subagent(...)`, `rlm.harness.update_subagent(...)`, `rlm.harness.delete_subagent(...)`, `rlm.harness.create_prompt_note(...)`, `rlm.harness.update_prompt_note(...)`, `rlm.harness.delete_prompt_note(...)`, plus `rlm.harness.record_refinement(...)` and `rlm.harness.overview()`. Use `global_=True` only for stable cross-session lessons; Python reserves `global`, so literal `global=True` is invalid syntax.\",\n\t\"\",\n\t\"Terminology: continual harness names the persisted prompt, memory, skill, and subagent layer; RLM names the runtime, Python REPL kernel, and native call interface exposed to the model.\",\n\t\"\",\n\t\"RLM-native call contract: installed Python skills are pre-imported modules. Read the matching SKILL.md and call its documented function, such as `await <skill_import>.<function>(...)`; when a CLI exists, use `<skill_import> ...` from shell. Continual harness skill entries are Python REPL skills with an explicit Python `reference` and `arguments` contract. Spawn a reusable delegation spec with `await rlm('sub-task')`; admission returns a child handle immediately. Results arrive only through an available messaging capability or files, never as an `rlm()` return value. Do not invent non-native wrappers such as `call_skill(...)` or `run_subagent(...)`.\",\n].join(\"\\n\");\n\nexport interface ChildAgentDoctrineOptions {\n\tdepth?: number;\n\tparentAgent?: string;\n\tinstalledSkills?: string[];\n\tactiveTools?: string[];\n}\n\nexport function buildChildAgentDoctrine(options: ChildAgentDoctrineOptions): string | undefined {\n\tconst depth = options.depth ?? 0;\n\tconst hasIpython = options.activeTools === undefined || options.activeTools.includes(\"ipython\");\n\tconst hasAgentMessage = options.installedSkills?.includes(\"agent_message\") ?? false;\n\tif (depth <= 0) return undefined;\n\n\tconst lines = [\n\t\t`You are a child agent spawned by ${options.parentAgent ?? \"your parent agent\"}. Task prompts are labeled \\`[task from parent]\\`.`,\n\t];\n\tif (hasAgentMessage && hasIpython) {\n\t\tlines.push(\n\t\t\t'When a task calls for an answer, reply explicitly with `await agent_message.send(message, receiver_role=\"parent\")`. Not every message or task needs a reply; continue cleanup after sending and go idle normally.',\n\t\t);\n\t}\n\treturn lines.join(\"\\n\");\n}\n\nexport function buildRlmPrompt(options: RlmPromptOptions): string {\n\tconst { cwd, skillsDir, messagesPath } = options;\n\tconst installedSkills = options.installedSkills ?? [];\n\tconst hasAgentMessage = installedSkills.includes(\"agent_message\");\n\tconst hasAgentObserve = installedSkills.includes(\"agent_observe\");\n\tconst allowRecursion = options.allowRecursion ?? true;\n\tconst depth = options.depth ?? 0;\n\tconst activeTools = options.activeTools ?? [];\n\tconst hasIpython = options.activeTools === undefined ? true : activeTools.includes(\"ipython\");\n\tconst canRunShellSkills = hasIpython || activeTools.includes(\"bash\");\n\tconst parts = [\n\t\t\"You are a general purpose agent that uses code to solve tasks.\",\n\t\t\"You solve tasks by breaking down problems into sub-tasks, writing and executing code, observing results, and iterating one step at a time.\",\n\t\t\"When you are done, stop calling tools and state your final answer.\",\n\t\t\"\",\n\t\tLONG_RUNNING_WORK_PROMPT,\n\t\t\"\",\n\t\t...(depth === 0 ? [USER_PROGRESS_PROMPT, \"\"] : []),\n\t\tSIMPLIFIED_TECHNICAL_ENGLISH_PROMPT,\n\t\t\"\",\n\t\t`Recursive agent depth: ${depth}`,\n\t\t`Pre-installed Python packages: ${DEFAULT_RLM_EXTRA_IMPORT_LABELS.join(\", \")}.`,\n\t\t\"Install additional packages with `uv pip install <pkg>` (this is a uv-managed venv with no pip module).\",\n\t];\n\n\tconst childDoctrine = buildChildAgentDoctrine(options);\n\tif (childDoctrine) {\n\t\tparts.push(\"\", childDoctrine);\n\t}\n\n\tconst skillLines: string[] = [];\n\tif (skillsDir) {\n\t\tskillLines.push(`Local skills live under ${skillsDir}. Read their SKILL.md files when helpful.`);\n\t}\n\tif (installedSkills.length > 0) {\n\t\tconst installed = installedSkills.map((skill) => `\\`${skill}\\``).join(\", \");\n\t\tif (hasIpython) {\n\t\t\tskillLines.push(`Installed Python skill modules (pre-imported): ${installed}.`);\n\t\t\tskillLines.push(\n\t\t\t\t\"Read each skill's SKILL.md for its API. Inspect a module with `help(<skill>)` or `dir(<skill>)`, then inspect a documented callable with `inspect.signature(<skill>.<function>)`.\",\n\t\t\t);\n\t\t} else if (canRunShellSkills) {\n\t\t\tskillLines.push(`Installed skills available as shell commands: ${installed}.`);\n\t\t}\n\t\tif (canRunShellSkills) {\n\t\t\tskillLines.push(\n\t\t\t\t\"Each skill is also available as a shell command by the same name: `<skill> ...`. Discover its CLI usage with `<skill> --help`.\",\n\t\t\t);\n\t\t}\n\t\tif (hasIpython && installedSkills.includes(\"edit\")) {\n\t\t\tskillLines.push(\n\t\t\t\t\"For targeted existing-file edits, prefer the pre-imported async `edit` skill from the REPL: `old = '''...'''; new = '''...'''; await edit(path=\\\"pkg/file.py\\\", old_str=old, new_str=new)`. Use exact old/new strings; if the text contains triple double quotes, use triple single-quoted variables or build `old`/`new` from inspected file slices.\",\n\t\t\t);\n\t\t}\n\t}\n\tif (skillLines.length > 0) {\n\t\tparts.push(\"\", ...skillLines);\n\t}\n\tif (hasAgentMessage) {\n\t\tparts.push(\n\t\t\t\"Agent messaging is restricted to your parent, siblings, and direct children; roots are siblings, and deeper communication relays through the intermediate child.\",\n\t\t);\n\t}\n\tif (hasAgentObserve) {\n\t\tparts.push(\n\t\t\t\"Agent observation is restricted to your parent, siblings, and direct children; roots are siblings, and deeper inspection relays through the intermediate child.\",\n\t\t);\n\t}\n\n\tif (allowRecursion && hasIpython) {\n\t\tparts.push(\n\t\t\t\"\",\n\t\t\t\"A callable `rlm` is already in your global namespace. `await rlm('sub-task')` spawns a child and returns immediately after task admission with `rlm_child_id`, `name`, `session_dir`, and `model`; it never waits for or returns the child's answer.\",\n\t\t\t\"Choose a stable child name with `await rlm('sub-task', name='api-reviewer')`; names must be unique among siblings. If omitted, the host generates a readable unique name.\",\n\t\t\t\"A child inherits your model. If a different model is explicitly requested, use `await rlm.find_models(...)` and an exact returned selector. An unavailable requested model fails spawn; decide whether to retry or omit `model`. Children also inherit your thinking level; the `thinking` option overrides it with any level the resolved child model supports, and an unsupported level fails spawn.\",\n\t\t);\n\t\tif (hasAgentMessage) {\n\t\t\tparts.push(\n\t\t\t\t\"Children reply explicitly with `await agent_message.send(message, receiver_role='parent')` when an answer is needed. Replies and follow-ups arrive as ordinary agent messages; not every task requires a reply.\",\n\t\t\t\t\"Use `await agent_message.list_agents()` to discover family and `await rlm.list_subagents()` to recover direct child handles. Use `agent_message.send(..., receiver_role='child', receiver_name=child.name)` for follow-ups.\",\n\t\t\t);\n\t\t} else {\n\t\t\tparts.push(\"Use `await rlm.list_subagents()` to recover direct child handles after admission.\");\n\t\t}\n\t\tif (hasAgentObserve) {\n\t\t\tparts.push(\n\t\t\t\t\"Use `agent_observe` to inspect a child's rollout. Observation is restricted to your parent, siblings, and direct children; relay through the intermediate child for deeper descendants.\",\n\t\t\t);\n\t\t} else {\n\t\t\tparts.push(\"Inspect files a child wrote when you need to collect its work without an observation capability.\");\n\t\t}\n\t\tparts.push(\n\t\t\t\"Spawn independent children in separate calls and end your turn instead of awaiting completion. Multiple replies may arrive over multiple turns. Delete a direct child explicitly with `await rlm.delete_subagent(child)` when it is no longer needed.\",\n\t\t);\n\t}\n\n\tif (hasIpython) {\n\t\tparts.push(\"\", REPL_CONTROL_PROMPT);\n\t\tif (installedSkills.includes(\"refine\")) {\n\t\t\tparts.push(\n\t\t\t\t\"\",\n\t\t\t\t\"Treat continual harness refinement as a small, evidence-backed update after observing a repeated failure or reusable tactic: diagnose the issue, update the smallest relevant continual harness component, validate on the next action, then record the outcome. Use `await refine.run()` to turn repeated delegation patterns into reusable subagent specs, repeated procedures into skills, durable facts/preferences into memories, and narrow behavioral policies into prompt addendums. It returns immediately and runs when the current turn ends, so continue working normally after calling it. Do not rewrite the whole continual harness when a focused memory, skill, prompt note, or subagent spec is enough.\",\n\t\t\t);\n\t\t}\n\t}\n\n\t// Runtime coordinates follow the fixed harness guidance without moving user/project instructions.\n\tparts.push(\"\", `Working directory: ${cwd}`, `Conversation log: ${messagesPath}`);\n\treturn parts.join(\"\\n\");\n}\n\n/**\n * Supplemental sub-agent delegation guidance, appended after the base RLM\n * prompt (see system-prompt.ts). The recursion block covers the mechanics\n * (`rlm(...)` admission and handle management); this block adds the\n * when and why in the same When -> Why -> menu order Claude Code's Agent tool\n * uses. The subagent-spec menu itself renders just after this, inside the\n * harness-state block.\n */\nexport function buildSubagentGuidance(\n\toptions: { includeRefineExamples?: boolean; hasAgentMessage?: boolean; hasAgentObserve?: boolean } = {},\n): string {\n\tconst lines = [\n\t\t\"# Delegating to sub-agents\",\n\t\t\"\",\n\t\t\"Spawn independent, self-contained work with `handle = await rlm('task', name='worker')`. This returns at admission, not completion; keep the handle to stop or inspect the child later.\",\n\t];\n\tif (options.hasAgentMessage) {\n\t\tlines.push(\n\t\t\t\"Ask for an explicit reply when needed. A child replies with `await agent_message.send(message, receiver_role='parent')`; parent follow-ups use `receiver_role='child'` plus the child's name or id. Not every message needs a reply.\",\n\t\t);\n\t}\n\tlines.push(\"Use `await rlm.list_subagents()` after kernel restart or compaction.\");\n\tif (options.hasAgentObserve) {\n\t\tlines.push(\"Use `agent_observe` for bounded transcript inspection.\");\n\t}\n\tlines.push(\n\t\t\"Have children write files and read those files for fan-in.\",\n\t\t\"Delegate parallel context-heavy research or independent implementation; do a single known lookup, edit, or command inline.\",\n\t);\n\tif (options.includeRefineExamples ?? true) {\n\t\tlines.push(\"Persist genuinely reusable delegation patterns with `await refine.run()`.\");\n\t}\n\treturn lines.join(\"\\n\");\n}\n"]}