@ponythewhite/base-context 1.0.6 → 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 (136) hide show
  1. package/CHANGELOG.md +25 -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-MEACET4U.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-QKI6KEGP.js → chunk-EXEFSSF4.js} +1509 -577
  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-LIZVVGHR.js → chunk-RVJVXZCS.js} +13 -10
  19. package/dist/bundle/{cli-main-ANUJY7Y4.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-4GIKOHIT.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 +189 -31
  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 +20 -12
  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 +110 -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 +12 -4
  80. package/dist/core/request-view-selection.d.ts.map +1 -1
  81. package/dist/core/request-view-selection.js +242 -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/sdk.d.ts.map +1 -1
  88. package/dist/core/sdk.js +1 -1
  89. package/dist/core/sdk.js.map +1 -1
  90. package/dist/core/selective-recovery.d.ts +47 -3
  91. package/dist/core/selective-recovery.d.ts.map +1 -1
  92. package/dist/core/selective-recovery.js +428 -109
  93. package/dist/core/selective-recovery.js.map +1 -1
  94. package/dist/core/session-history-index.d.ts +3 -1
  95. package/dist/core/session-history-index.d.ts.map +1 -1
  96. package/dist/core/session-history-index.js +1 -1
  97. package/dist/core/session-history-index.js.map +1 -1
  98. package/dist/core/settings-manager.d.ts +5 -0
  99. package/dist/core/settings-manager.d.ts.map +1 -1
  100. package/dist/core/settings-manager.js +3 -0
  101. package/dist/core/settings-manager.js.map +1 -1
  102. package/dist/core/system-prompt.d.ts +3 -1
  103. package/dist/core/system-prompt.d.ts.map +1 -1
  104. package/dist/core/system-prompt.js +3 -3
  105. package/dist/core/system-prompt.js.map +1 -1
  106. package/dist/core/task-frame.d.ts +1 -1
  107. package/dist/core/task-frame.d.ts.map +1 -1
  108. package/dist/core/task-frame.js +21 -1
  109. package/dist/core/task-frame.js.map +1 -1
  110. package/dist/core/task-state-reader.d.ts +10 -2
  111. package/dist/core/task-state-reader.d.ts.map +1 -1
  112. package/dist/core/task-state-reader.js +75 -9
  113. package/dist/core/task-state-reader.js.map +1 -1
  114. package/dist/core/tools/ipython.d.ts +5 -0
  115. package/dist/core/tools/ipython.d.ts.map +1 -1
  116. package/dist/core/tools/ipython.js +59 -17
  117. package/dist/core/tools/ipython.js.map +1 -1
  118. package/dist/core/tools/prime-context.d.ts.map +1 -1
  119. package/dist/core/tools/prime-context.js +1 -1
  120. package/dist/core/tools/prime-context.js.map +1 -1
  121. package/dist/core/view-units.d.ts +4 -0
  122. package/dist/core/view-units.d.ts.map +1 -1
  123. package/dist/core/view-units.js +28 -19
  124. package/dist/core/view-units.js.map +1 -1
  125. package/dist/installer.mjs +98 -77
  126. package/dist/modes/interactive/components/refinement-outcome-message.d.ts.map +1 -1
  127. package/dist/modes/interactive/components/refinement-outcome-message.js.map +1 -1
  128. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  129. package/dist/modes/interactive/interactive-mode.js +5 -5
  130. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  131. package/dist/skills/skill-creator/SKILL.md +18 -1
  132. package/docs/settings.md +45 -0
  133. package/docs/skills.md +77 -2
  134. package/package.json +4 -4
  135. package/skills/skill-creator/SKILL.md +18 -1
  136. package/dist/bundle/chunk-W46VZFI6.js +0 -21681
@@ -1 +1 @@
1
- {"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * System prompt construction and project context loading\n */\n\nimport { buildChildAgentDoctrine, buildRlmPrompt, buildSubagentGuidance } from \"./prompts/index.js\";\nimport { formatHarnessStateForPrompt, type HarnessState, REFINE_SKILL_NAME } from \"./refinement/index.js\";\nimport { formatSkillsForPrompt, getPythonSkillRuntimeInfo, type Skill } from \"./skills.js\";\n\n// User-approved policy shared by every main model, including custom system prompts.\nconst ABSOLUTE_PROHIBITION = [\n\t\"## Absolute Prohibition: No Verification Theater / Proof Boilerplate\",\n\t\"\",\n\t\"You are FORBIDDEN from inventing, adding, or expanding any of the following unless the user explicitly requests them in the current message:\",\n\t\"\",\n\t'- Proofs of correctness, formal verification, or \"proof harnesses\"',\n\t'- Ledgers, audit logs, provenance tracking, or event sourcing \"for safety\"',\n\t\"- Cryptographic hashes, checksums, integrity checks, or signature schemes\",\n\t'- Review loops, multi-stage validation pipelines, or \"ensure this works\" rituals',\n\t\"- Extra test suites, property-based tests, or mutation testing that go beyond the minimal happy-path + one edge case\",\n\t\"- Over-cautious guardrails, legacy-compatibility layers, or defensive code for failure modes the user did not mention\",\n\t\"\",\n\t\"### Core Rule\",\n\t\"**Build the actual thing first.** \",\n\t\"Your job is to ship working, minimal, readable code that solves the stated problem. \",\n\t\"Do **not** turn a simple feature request into a research project on correctness.\",\n\t\"\",\n\t\"### Enforcement\",\n\t\"1. If the task is a prototype, MVP, script, or simple project → write the direct implementation. Stop.\",\n\t'2. Only add verification mechanisms when the user says words like \"prove\", \"formally verify\", \"add ledger\", \"hash everything\", or \"make it bulletproof\".',\n\t\"3. If you feel the urge to add any of the banned items, rewrite the plan to remove them before writing any code.\",\n\t\"4. Prefer deleting code over adding protective boilerplate.\",\n\t\"5. When in doubt: less is more. KISS is mandatory.\",\n\t\"\",\n\t\"Violation of this rule is considered a failure. Re-plan and ship the real feature instead.\",\n].join(\"\\n\");\n\nconst IMPLEMENTATION_CONTRACT = [\n\t\"## Implementation scope\",\n\t\"\",\n\t\"Implement the full stated input domain and required outputs, not only the cases present in the supplied data. Do not invent additional input formats or compatibility branches beyond that contract.\",\n\t\"Preserve earlier requirements unless later instructions replace them. Apply stated eligibility, priorities, and decision order literally, even when a different policy seems simpler or more sensible; reevaluate later decisions when earlier actions change their inputs.\",\n\t\"The required commands must implement the stated workflow from its stated starting state, without development-only state or extra steps.\",\n\t\"During tool-based inspection of large datasets, request schemas or small samples. Process full inputs in local code instead of printing entire datasets into the conversation.\",\n\t\"Do not repeat a successful check without a concrete reason, such as changed input, an edit, or an observed failure.\",\n\t\"Choose algorithms whose time and memory costs fit the stated input limits.\",\n\t\"For constrained search, prune known-impossible partial states before expanding them; do not postpone all feasibility checks until completed candidates.\",\n\t\"Choose numeric representations and arithmetic precision for the stated domain, not sample values or library defaults. Follow supplied formulas and operation order; use exact arithmetic for discrete decisions instead of rounded intermediates. Preserve each output field’s units, precision, rounding and required text format.\",\n].join(\"\\n\");\n\nexport interface BuildSystemPromptOptions {\n\t/** Custom system prompt (replaces the default body; shared main-prompt policy remains). */\n\tcustomPrompt?: string;\n\t/** Active tools. Tool schemas carry tool descriptions outside the prompt body. */\n\tselectedTools?: string[];\n\t/** Optional one-line tool snippets keyed by tool name. Used only for custom prompts. */\n\ttoolSnippets?: Record<string, string>;\n\t/** Additional guideline bullets appended to the system prompt. */\n\tpromptGuidelines?: string[];\n\t/** Text to append to system prompt. */\n\tappendSystemPrompt?: string;\n\t/** Working directory. */\n\tcwd: string;\n\t/** Conversation log path. */\n\tmessagesPath?: string;\n\t/** Pre-loaded context files. */\n\tcontextFiles?: Array<{ path: string; content: string }>;\n\t/** Pre-loaded skills. */\n\tskills?: Skill[];\n\t/** Actual native recovery authorization at this owned prompt build. */\n\tnativeSkillSelection?: \"enabled\" | \"unavailable\";\n\t/** Whether to include the model-facing rlm recursion guidance. */\n\tallowRecursion?: boolean;\n\t/** Fixed recursive-agent depth for this session. */\n\trlmDepth?: number;\n\t/** Human-readable parent name or id for child communication doctrine. */\n\trlmParentAgent?: string;\n\t/** Global harness state to inject as compact persistent context. */\n\tharnessState?: HarnessState;\n\t/** Enabled user-configured servers available through the generic kernel MCP API. */\n\tgenericMcpServers?: string[];\n}\n\n/** Build the system prompt with tools, guidelines, and context */\nexport function buildSystemPrompt(options: BuildSystemPromptOptions): string {\n\tconst {\n\t\tcustomPrompt,\n\t\tselectedTools,\n\t\tpromptGuidelines,\n\t\tappendSystemPrompt,\n\t\tcwd,\n\t\tmessagesPath,\n\t\tcontextFiles: providedContextFiles,\n\t\tskills: providedSkills,\n\t\tallowRecursion,\n\t\tharnessState,\n\t} = options;\n\tconst promptCwd = cwd.replace(/\\\\/g, \"/\");\n\tconst promptMessagesPath = (messagesPath ?? \"not persisted\").replace(/\\\\/g, \"/\");\n\n\tconst now = new Date();\n\tconst year = now.getFullYear();\n\tconst month = String(now.getMonth() + 1).padStart(2, \"0\");\n\tconst day = String(now.getDate()).padStart(2, \"0\");\n\tconst date = `${year}-${month}-${day}`;\n\n\tconst appendSection = appendSystemPrompt ? `\\n\\n${appendSystemPrompt}` : \"\";\n\n\tconst contextFiles = providedContextFiles ?? [];\n\tconst skills = options.nativeSkillSelection === \"unavailable\" ? [] : (providedSkills ?? []);\n\tconst tools = selectedTools ?? [\"ipython\"];\n\tconst hasIpython = tools.includes(\"ipython\");\n\tconst hasBash = tools.includes(\"bash\");\n\t// Admit and capture the catalog before constructing skill-derived prompt text.\n\tconst skillCatalog =\n\t\t(options.nativeSkillSelection === \"enabled\" || hasIpython || hasBash) && skills.length > 0\n\t\t\t? formatSkillsForPrompt(skills, options.nativeSkillSelection === \"enabled\")\n\t\t\t: \"\";\n\tconst visibleSkills = skills.filter((skill) => !skill.disableModelInvocation);\n\tconst visiblePythonSkillImportNames = getPythonSkillRuntimeInfo(visibleSkills).map((skill) => skill.importName);\n\tconst hasRefineSkill = visibleSkills.some((skill) => skill.name === REFINE_SKILL_NAME);\n\tconst genericMcpSection = hasIpython ? formatGenericMcpGuidance(options.genericMcpServers) : \"\";\n\n\tif (customPrompt) {\n\t\tlet prompt = `${customPrompt}\\n\\n${ABSOLUTE_PROHIBITION}\\n\\n${IMPLEMENTATION_CONTRACT}`;\n\n\t\t// Append project context files\n\t\tif (contextFiles.length > 0) {\n\t\t\tprompt += \"\\n\\n# Project Context\\n\\n\";\n\t\t\tprompt += \"Project-specific instructions and guidelines:\\n\\n\";\n\t\t\tfor (const { path: filePath, content } of contextFiles) {\n\t\t\t\tprompt += `## ${filePath}\\n\\n${content}\\n\\n`;\n\t\t\t}\n\t\t}\n\n\t\tprompt += skillCatalog;\n\n\t\t// Add date and working directory last\n\t\tprompt += `\\nCurrent date: ${date}`;\n\t\tprompt += `\\nCurrent working directory: ${promptCwd}`;\n\n\t\tconst childDoctrine = buildChildAgentDoctrine({\n\t\t\tdepth: options.rlmDepth,\n\t\t\tparentAgent: options.rlmParentAgent,\n\t\t\tinstalledSkills: visiblePythonSkillImportNames,\n\t\t\tactiveTools: tools,\n\t\t});\n\t\tif (childDoctrine) {\n\t\t\tprompt += `\\n\\n${childDoctrine}`;\n\t\t}\n\n\t\tif (harnessState) {\n\t\t\tprompt += `\\n\\n${formatHarnessStateForPrompt(harnessState, { includeIpythonExamples: hasIpython, includeShellExamples: hasBash, includeRefineExamples: hasIpython && hasRefineSkill })}`;\n\t\t}\n\n\t\tif (genericMcpSection) {\n\t\t\tprompt += `\\n\\n${genericMcpSection}`;\n\t\t}\n\n\t\tif (appendSection) {\n\t\t\tprompt += appendSection;\n\t\t}\n\n\t\treturn prompt;\n\t}\n\n\tlet prompt = buildRlmPrompt({\n\t\tcwd: promptCwd,\n\t\tmessagesPath: promptMessagesPath,\n\t\tinstalledSkills: visiblePythonSkillImportNames,\n\t\tactiveTools: tools.filter((name) => name === \"ipython\" || name === \"bash\" || name === \"edit\"),\n\t\tallowRecursion,\n\t\tdepth: options.rlmDepth,\n\t\tparentAgent: options.rlmParentAgent,\n\t});\n\n\tprompt += `\\n\\n${ABSOLUTE_PROHIBITION}\\n\\n${IMPLEMENTATION_CONTRACT}`;\n\n\t// Appended AFTER the trained buildRlmPrompt prefix, and before the harness-state\n\t// menu, so the model reads when/why to delegate and then sees the concrete subagent\n\t// specs it can match against — the same ordering as Claude Code's Agent tool.\n\tif ((allowRecursion ?? true) && hasIpython) {\n\t\tconst visiblePythonSkillNames = new Set(\n\t\t\tgetPythonSkillRuntimeInfo(visibleSkills).map((skill) => skill.importName),\n\t\t);\n\t\tprompt += `\\n\\n${buildSubagentGuidance({\n\t\t\tincludeRefineExamples: hasRefineSkill,\n\t\t\thasAgentMessage: visiblePythonSkillNames.has(\"agent_message\"),\n\t\t\thasAgentObserve: visiblePythonSkillNames.has(\"agent_observe\"),\n\t\t})}`;\n\t}\n\n\tif (harnessState) {\n\t\tprompt += `\\n\\n${formatHarnessStateForPrompt(harnessState, { includeIpythonExamples: hasIpython, includeShellExamples: hasBash, includeRefineExamples: hasIpython && hasRefineSkill })}`;\n\t}\n\n\tif (genericMcpSection) {\n\t\tprompt += `\\n\\n${genericMcpSection}`;\n\t}\n\n\tconst guidelines = formatPromptGuidelines(promptGuidelines);\n\tif (guidelines) {\n\t\tprompt += `\\n\\n# Additional Guidance\\n\\n${guidelines}`;\n\t}\n\n\t// Append project context files\n\tif (contextFiles.length > 0) {\n\t\tprompt += \"\\n\\n# Project Context\\n\\n\";\n\t\tprompt += \"Project-specific instructions and guidelines:\\n\\n\";\n\t\tfor (const { path: filePath, content } of contextFiles) {\n\t\t\tprompt += `## ${filePath}\\n\\n${content}\\n\\n`;\n\t\t}\n\t}\n\n\tprompt += skillCatalog;\n\n\tif (appendSection) {\n\t\tprompt += appendSection;\n\t}\n\n\treturn prompt;\n}\n\nfunction formatGenericMcpGuidance(servers: string[] | undefined): string {\n\tconst enabledServers = [...new Set(servers ?? [])].sort((left, right) => left.localeCompare(right));\n\tif (enabledServers.length === 0) return \"\";\n\n\treturn [\n\t\t\"# Generic MCP Connections\",\n\t\t\"\",\n\t\t\"Generic MCP connections are accessed through the pre-imported Python `mcp` object in the Python REPL, not as top-level native tool namespaces or installed Python skills.\",\n\t\t`Enabled generic MCP servers: ${enabledServers.map((server) => `\\`${server}\\``).join(\", \")}.`,\n\t\t...enabledServers.map(\n\t\t\t(server) =>\n\t\t\t\t`For \\`${server}\\`, first discover its tools with \\`await mcp.list_tools(\"${server}\")\\`, then call one with \\`await mcp.call_tool(\"${server}\", \"<tool>\", arguments)\\`.`,\n\t\t),\n\t].join(\"\\n\");\n}\n\nfunction formatPromptGuidelines(promptGuidelines: string[] | undefined): string {\n\tconst guidelinesList: string[] = [];\n\tconst guidelinesSet = new Set<string>();\n\n\tfor (const guideline of promptGuidelines ?? []) {\n\t\tconst normalized = guideline.trim();\n\t\tif (normalized.length > 0 && !guidelinesSet.has(normalized)) {\n\t\t\tguidelinesSet.add(normalized);\n\t\t\tguidelinesList.push(normalized);\n\t\t}\n\t}\n\n\treturn guidelinesList.map((guideline) => `- ${guideline}`).join(\"\\n\");\n}\n"]}
1
+ {"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * System prompt construction and project context loading\n */\n\nimport { buildChildAgentDoctrine, buildRlmPrompt, buildSubagentGuidance } from \"./prompts/index.js\";\nimport {\n\ttype ErrorFixSelectionOptions,\n\tformatHarnessStateForPrompt,\n\ttype HarnessState,\n\tREFINE_SKILL_NAME,\n} from \"./refinement/index.js\";\nimport { formatSkillsForPrompt, getPythonSkillRuntimeInfo, type Skill } from \"./skills.js\";\n\n// User-approved policy shared by every main model, including custom system prompts.\nconst ABSOLUTE_PROHIBITION = [\n\t\"## Absolute Prohibition: No Verification Theater / Proof Boilerplate\",\n\t\"\",\n\t\"You are FORBIDDEN from inventing, adding, or expanding any of the following unless the user explicitly requests them in the current message:\",\n\t\"\",\n\t'- Proofs of correctness, formal verification, or \"proof harnesses\"',\n\t'- Ledgers, audit logs, provenance tracking, or event sourcing \"for safety\"',\n\t\"- Cryptographic hashes, checksums, integrity checks, or signature schemes\",\n\t'- Review loops, multi-stage validation pipelines, or \"ensure this works\" rituals',\n\t\"- Extra test suites, property-based tests, or mutation testing that go beyond the minimal happy-path + one edge case\",\n\t\"- Over-cautious guardrails, legacy-compatibility layers, or defensive code for failure modes the user did not mention\",\n\t\"\",\n\t\"### Core Rule\",\n\t\"**Build the actual thing first.** \",\n\t\"Your job is to ship working, minimal, readable code that solves the stated problem. \",\n\t\"Do **not** turn a simple feature request into a research project on correctness.\",\n\t\"\",\n\t\"### Enforcement\",\n\t\"1. If the task is a prototype, MVP, script, or simple project → write the direct implementation. Stop.\",\n\t'2. Only add verification mechanisms when the user says words like \"prove\", \"formally verify\", \"add ledger\", \"hash everything\", or \"make it bulletproof\".',\n\t\"3. If you feel the urge to add any of the banned items, rewrite the plan to remove them before writing any code.\",\n\t\"4. Prefer deleting code over adding protective boilerplate.\",\n\t\"5. When in doubt: less is more. KISS is mandatory.\",\n\t\"\",\n\t\"Violation of this rule is considered a failure. Re-plan and ship the real feature instead.\",\n].join(\"\\n\");\n\nconst IMPLEMENTATION_CONTRACT = [\n\t\"## Implementation scope\",\n\t\"\",\n\t\"Implement the full stated input domain and required outputs, not only the cases present in the supplied data. Do not invent additional input formats or compatibility branches beyond that contract.\",\n\t\"Preserve earlier requirements unless later instructions replace them. Apply stated eligibility, priorities, and decision order literally, even when a different policy seems simpler or more sensible; reevaluate later decisions when earlier actions change their inputs.\",\n\t\"The required commands must implement the stated workflow from its stated starting state, without development-only state or extra steps.\",\n\t\"During tool-based inspection of large datasets, request schemas or small samples. Process full inputs in local code instead of printing entire datasets into the conversation.\",\n\t\"Do not repeat a successful check without a concrete reason, such as changed input, an edit, or an observed failure.\",\n\t\"Choose algorithms whose time and memory costs fit the stated input limits.\",\n\t\"For constrained search, prune known-impossible partial states before expanding them; do not postpone all feasibility checks until completed candidates.\",\n\t\"Choose numeric representations and arithmetic precision for the stated domain, not sample values or library defaults. Follow supplied formulas and operation order; use exact arithmetic for discrete decisions instead of rounded intermediates. Preserve each output field’s units, precision, rounding and required text format.\",\n].join(\"\\n\");\n\nexport interface BuildSystemPromptOptions {\n\t/** Custom system prompt (replaces the default body; shared main-prompt policy remains). */\n\tcustomPrompt?: string;\n\t/** Active tools. Tool schemas carry tool descriptions outside the prompt body. */\n\tselectedTools?: string[];\n\t/** Optional one-line tool snippets keyed by tool name. Used only for custom prompts. */\n\ttoolSnippets?: Record<string, string>;\n\t/** Additional guideline bullets appended to the system prompt. */\n\tpromptGuidelines?: string[];\n\t/** Text to append to system prompt. */\n\tappendSystemPrompt?: string;\n\t/** Working directory. */\n\tcwd: string;\n\t/** Conversation log path. */\n\tmessagesPath?: string;\n\t/** Pre-loaded context files. */\n\tcontextFiles?: Array<{ path: string; content: string }>;\n\t/** Pre-loaded skills. */\n\tskills?: Skill[];\n\t/** Actual native recovery authorization at this owned prompt build. */\n\tnativeSkillSelection?: \"enabled\" | \"unavailable\";\n\t/** Whether to include the model-facing rlm recursion guidance. */\n\tallowRecursion?: boolean;\n\t/** Fixed recursive-agent depth for this session. */\n\trlmDepth?: number;\n\t/** Human-readable parent name or id for child communication doctrine. */\n\trlmParentAgent?: string;\n\t/** Global harness state to inject as compact persistent context. */\n\tharnessState?: HarnessState;\n\t/** Owner-captured optional advice inputs, stable with the system-prompt epoch. */\n\terrorFixSelection?: ErrorFixSelectionOptions;\n\t/** Enabled user-configured servers available through the generic kernel MCP API. */\n\tgenericMcpServers?: string[];\n}\n\n/** Build the system prompt with tools, guidelines, and context */\nexport function buildSystemPrompt(options: BuildSystemPromptOptions): string {\n\tconst {\n\t\tcustomPrompt,\n\t\tselectedTools,\n\t\tpromptGuidelines,\n\t\tappendSystemPrompt,\n\t\tcwd,\n\t\tmessagesPath,\n\t\tcontextFiles: providedContextFiles,\n\t\tskills: providedSkills,\n\t\tallowRecursion,\n\t\tharnessState,\n\t} = options;\n\tconst promptCwd = cwd.replace(/\\\\/g, \"/\");\n\tconst promptMessagesPath = (messagesPath ?? \"not persisted\").replace(/\\\\/g, \"/\");\n\n\tconst now = new Date();\n\tconst year = now.getFullYear();\n\tconst month = String(now.getMonth() + 1).padStart(2, \"0\");\n\tconst day = String(now.getDate()).padStart(2, \"0\");\n\tconst date = `${year}-${month}-${day}`;\n\n\tconst appendSection = appendSystemPrompt ? `\\n\\n${appendSystemPrompt}` : \"\";\n\n\tconst contextFiles = providedContextFiles ?? [];\n\tconst skills = options.nativeSkillSelection === \"unavailable\" ? [] : (providedSkills ?? []);\n\tconst tools = selectedTools ?? [\"ipython\"];\n\tconst hasIpython = tools.includes(\"ipython\");\n\tconst hasBash = tools.includes(\"bash\");\n\t// Admit and capture the catalog before constructing skill-derived prompt text.\n\tconst skillCatalog =\n\t\t(options.nativeSkillSelection === \"enabled\" || hasIpython || hasBash) && skills.length > 0\n\t\t\t? formatSkillsForPrompt(skills, options.nativeSkillSelection === \"enabled\")\n\t\t\t: \"\";\n\tconst visibleSkills = skills.filter((skill) => !skill.disableModelInvocation);\n\tconst visiblePythonSkillImportNames = getPythonSkillRuntimeInfo(visibleSkills).map((skill) => skill.importName);\n\tconst hasRefineSkill = visibleSkills.some((skill) => skill.name === REFINE_SKILL_NAME);\n\tconst genericMcpSection = hasIpython ? formatGenericMcpGuidance(options.genericMcpServers) : \"\";\n\n\tif (customPrompt) {\n\t\tlet prompt = `${customPrompt}\\n\\n${ABSOLUTE_PROHIBITION}\\n\\n${IMPLEMENTATION_CONTRACT}`;\n\n\t\t// Append project context files\n\t\tif (contextFiles.length > 0) {\n\t\t\tprompt += \"\\n\\n# Project Context\\n\\n\";\n\t\t\tprompt += \"Project-specific instructions and guidelines:\\n\\n\";\n\t\t\tfor (const { path: filePath, content } of contextFiles) {\n\t\t\t\tprompt += `## ${filePath}\\n\\n${content}\\n\\n`;\n\t\t\t}\n\t\t}\n\n\t\tprompt += skillCatalog;\n\n\t\t// Add date and working directory last\n\t\tprompt += `\\nCurrent date: ${date}`;\n\t\tprompt += `\\nCurrent working directory: ${promptCwd}`;\n\n\t\tconst childDoctrine = buildChildAgentDoctrine({\n\t\t\tdepth: options.rlmDepth,\n\t\t\tparentAgent: options.rlmParentAgent,\n\t\t\tinstalledSkills: visiblePythonSkillImportNames,\n\t\t\tactiveTools: tools,\n\t\t});\n\t\tif (childDoctrine) {\n\t\t\tprompt += `\\n\\n${childDoctrine}`;\n\t\t}\n\n\t\tif (harnessState) {\n\t\t\tprompt += `\\n\\n${formatHarnessStateForPrompt(harnessState, { includeIpythonExamples: hasIpython, includeShellExamples: hasBash, includeRefineExamples: hasIpython && hasRefineSkill, errorFixSelection: options.errorFixSelection })}`;\n\t\t}\n\n\t\tif (genericMcpSection) {\n\t\t\tprompt += `\\n\\n${genericMcpSection}`;\n\t\t}\n\n\t\tif (appendSection) {\n\t\t\tprompt += appendSection;\n\t\t}\n\n\t\treturn prompt;\n\t}\n\n\tlet prompt = buildRlmPrompt({\n\t\tcwd: promptCwd,\n\t\tmessagesPath: promptMessagesPath,\n\t\tinstalledSkills: visiblePythonSkillImportNames,\n\t\tactiveTools: tools.filter((name) => name === \"ipython\" || name === \"bash\" || name === \"edit\"),\n\t\tallowRecursion,\n\t\tdepth: options.rlmDepth,\n\t\tparentAgent: options.rlmParentAgent,\n\t});\n\n\tprompt += `\\n\\n${ABSOLUTE_PROHIBITION}\\n\\n${IMPLEMENTATION_CONTRACT}`;\n\n\t// Appended AFTER the trained buildRlmPrompt prefix, and before the harness-state\n\t// menu, so the model reads when/why to delegate and then sees the concrete subagent\n\t// specs it can match against — the same ordering as Claude Code's Agent tool.\n\tif ((allowRecursion ?? true) && hasIpython) {\n\t\tconst visiblePythonSkillNames = new Set(\n\t\t\tgetPythonSkillRuntimeInfo(visibleSkills).map((skill) => skill.importName),\n\t\t);\n\t\tprompt += `\\n\\n${buildSubagentGuidance({\n\t\t\tincludeRefineExamples: hasRefineSkill,\n\t\t\thasAgentMessage: visiblePythonSkillNames.has(\"agent_message\"),\n\t\t\thasAgentObserve: visiblePythonSkillNames.has(\"agent_observe\"),\n\t\t})}`;\n\t}\n\n\tif (harnessState) {\n\t\tprompt += `\\n\\n${formatHarnessStateForPrompt(harnessState, { includeIpythonExamples: hasIpython, includeShellExamples: hasBash, includeRefineExamples: hasIpython && hasRefineSkill, errorFixSelection: options.errorFixSelection })}`;\n\t}\n\n\tif (genericMcpSection) {\n\t\tprompt += `\\n\\n${genericMcpSection}`;\n\t}\n\n\tconst guidelines = formatPromptGuidelines(promptGuidelines);\n\tif (guidelines) {\n\t\tprompt += `\\n\\n# Additional Guidance\\n\\n${guidelines}`;\n\t}\n\n\t// Append project context files\n\tif (contextFiles.length > 0) {\n\t\tprompt += \"\\n\\n# Project Context\\n\\n\";\n\t\tprompt += \"Project-specific instructions and guidelines:\\n\\n\";\n\t\tfor (const { path: filePath, content } of contextFiles) {\n\t\t\tprompt += `## ${filePath}\\n\\n${content}\\n\\n`;\n\t\t}\n\t}\n\n\tprompt += skillCatalog;\n\n\tif (appendSection) {\n\t\tprompt += appendSection;\n\t}\n\n\treturn prompt;\n}\n\nfunction formatGenericMcpGuidance(servers: string[] | undefined): string {\n\tconst enabledServers = [...new Set(servers ?? [])].sort((left, right) => left.localeCompare(right));\n\tif (enabledServers.length === 0) return \"\";\n\n\treturn [\n\t\t\"# Generic MCP Connections\",\n\t\t\"\",\n\t\t\"Generic MCP connections are accessed through the pre-imported Python `mcp` object in the Python REPL, not as top-level native tool namespaces or installed Python skills.\",\n\t\t`Enabled generic MCP servers: ${enabledServers.map((server) => `\\`${server}\\``).join(\", \")}.`,\n\t\t...enabledServers.map(\n\t\t\t(server) =>\n\t\t\t\t`For \\`${server}\\`, first discover its tools with \\`await mcp.list_tools(\"${server}\")\\`, then call one with \\`await mcp.call_tool(\"${server}\", \"<tool>\", arguments)\\`.`,\n\t\t),\n\t].join(\"\\n\");\n}\n\nfunction formatPromptGuidelines(promptGuidelines: string[] | undefined): string {\n\tconst guidelinesList: string[] = [];\n\tconst guidelinesSet = new Set<string>();\n\n\tfor (const guideline of promptGuidelines ?? []) {\n\t\tconst normalized = guideline.trim();\n\t\tif (normalized.length > 0 && !guidelinesSet.has(normalized)) {\n\t\t\tguidelinesSet.add(normalized);\n\t\t\tguidelinesList.push(normalized);\n\t\t}\n\t}\n\n\treturn guidelinesList.map((guideline) => `- ${guideline}`).join(\"\\n\");\n}\n"]}
@@ -41,7 +41,7 @@ export interface CompiledTaskFrame {
41
41
  /** One source slot per revision; null is the empty literal prefix after the base. */
42
42
  readonly anchors: readonly (TaskFrameAnchor | null)[];
43
43
  }
44
- /** Prepare without changing the previous render cache. Commit only with a successful context build. */
44
+ /** Rebase once when the accumulated render is full; the caller still owns the epoch ACK. */
45
45
  export declare function compileTaskFrame(view: TaskStateView, limits: Readonly<TaskFrameLimits>, previous?: CompiledTaskFrame): CompiledTaskFrame | undefined;
46
46
  export {};
47
47
  //# sourceMappingURL=task-frame.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"task-frame.d.ts","sourceRoot":"","sources":["../../src/core/task-frame.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,eAAO,MAAM,sBAAsB,eAAe,CAAC;AAEnD,MAAM,WAAW,eAAe;IAC/B,+FAA+F;IAC/F,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,aAAa,EAAE,MAAM,CAAC;IACtB,qGAAqG;IACrG,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,eAAe,CAAC,MAAM,GAAE,OAAO,CAAC,eAAe,CAAM,GAAG,QAAQ,CAAC,eAAe,CAAC,CAchG;AAED,UAAU,YAAY;IACrB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAClC,SAAS,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC5C,KAAK,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC7C,SAAS,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;CACzB;AAED,8GAA8G;AAC9G,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,SAAS,YAAY,EAAE,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IAC5C,QAAQ,CAAC,OAAO,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC/C,qFAAqF;IACrF,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,eAAe,GAAG,IAAI,CAAC,EAAE,CAAC;CACtD;AA8ED,uGAAuG;AACvG,wBAAgB,gBAAgB,CAC/B,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,QAAQ,CAAC,eAAe,CAAC,EACjC,QAAQ,CAAC,EAAE,iBAAiB,GAC1B,iBAAiB,GAAG,SAAS,CA+F/B","sourcesContent":["import { stringifyBoundedJson } from \"./bounded-json.js\";\nimport type { CustomMessage } from \"./messages.js\";\nimport type { SourceSnapshotRef } from \"./request-events.js\";\nimport type { TaskStateProjection, TaskStateSourceRef } from \"./task-state.js\";\nimport type { TaskStateView } from \"./task-state-reader.js\";\nimport type { ReducedTaskItem } from \"./task-state-reducer.js\";\n\nexport const TASK_FRAME_CUSTOM_TYPE = \"task_frame\";\n\nexport interface TaskFrameLimits {\n\t/** Aggregate encoded custom-message bytes, including retained sparse revisions. Not tokens. */\n\tmaxBytes: number;\n\t/** Maximum exact source references in the current selective display. */\n\tmaxReferences: number;\n\t/** UTF-8 JSON-string bytes of selected exact clauses; oversized text is referenced, never sliced. */\n\tmaxTextBytes: number;\n}\n\nexport function taskFrameLimits(limits: Partial<TaskFrameLimits> = {}): Readonly<TaskFrameLimits> {\n\tconst captured = Object.freeze({\n\t\tmaxBytes: limits.maxBytes ?? 16_384,\n\t\tmaxReferences: limits.maxReferences ?? 32,\n\t\tmaxTextBytes: limits.maxTextBytes ?? 2_048,\n\t});\n\tif (\n\t\t!Object.values(captured).every(Number.isSafeInteger) ||\n\t\tcaptured.maxBytes <= 0 ||\n\t\tcaptured.maxReferences <= 0 ||\n\t\tcaptured.maxTextBytes < 0\n\t)\n\t\tthrow new Error(\"Invalid task frame limits\");\n\treturn captured;\n}\n\ninterface TaskFrameRow {\n\tsource: TaskStateSourceRef;\n\tkind: TaskStateProjection[\"kind\"];\n\tauthority: TaskStateProjection[\"authority\"];\n\tstate: ReducedTaskItem[\"state\"];\n\titemId?: string;\n\ttaskKey?: string;\n\ttext?: string;\n\ttextOmitted?: true;\n\tresource?: string;\n\tgoalState?: TaskStateProjection[\"goalState\"];\n\trelations: TaskStateProjection[\"relations\"];\n\tchangedBy?: TaskStateSourceRef;\n\tunresolved: boolean;\n}\n\nexport interface TaskFrameAnchor {\n\tentryId: string;\n\tside: \"before\" | \"after\";\n}\n\n/** Bounded internal selected rows and frozen provider text. Reduction is rebuilt from the captured reader. */\nexport interface CompiledTaskFrame {\n\treadonly material: string;\n\treadonly rows: readonly TaskFrameRow[];\n\treadonly messages: readonly CustomMessage[];\n\treadonly origins: readonly SourceSnapshotRef[];\n\t/** One source slot per revision; null is the empty literal prefix after the base. */\n\treadonly anchors: readonly (TaskFrameAnchor | null)[];\n}\n\nfunction key(source: TaskStateSourceRef): string {\n\treturn JSON.stringify([source.sessionId, source.entryId, source.field]);\n}\n\nfunction rank(item: ReducedTaskItem): number | undefined {\n\tif (item.state === \"active\") {\n\t\tif (item.event.authority === \"instruction\") return 0;\n\t\treturn item.event.kind === \"user_goal_revision\" ? 1 : 2;\n\t}\n\tif (item.event.authority === \"unrecorded\" || item.state === \"proposal\") return undefined;\n\tif (item.event.kind === \"open_question\") return 3;\n\tif (item.event.kind === \"observed_fact\" || item.event.kind === \"artifact_state\") return 4;\n\treturn undefined;\n}\n\nfunction row(item: ReducedTaskItem): TaskFrameRow {\n\tconst event = item.event;\n\treturn {\n\t\tsource: event.source,\n\t\tkind: event.kind,\n\t\tauthority: event.authority,\n\t\tstate: item.state,\n\t\t...(event.itemId === undefined ? {} : { itemId: event.itemId }),\n\t\t...(event.taskKey === undefined ? {} : { taskKey: event.taskKey }),\n\t\t...(event.resource === undefined ? {} : { resource: event.resource }),\n\t\t...(event.goalState === undefined ? {} : { goalState: event.goalState }),\n\t\trelations: event.relations,\n\t\t...(item.changedBy === undefined ? {} : { changedBy: item.changedBy }),\n\t\tunresolved: item.unresolved,\n\t};\n}\n\n/** Provider recovery addresses exact public fields by identity, never by physical locator. */\nfunction displaySource(source: TaskStateSourceRef) {\n\treturn {\n\t\tsessionId: source.sessionId,\n\t\tentryId: source.entryId,\n\t\tfield: source.field,\n\t\t...(source.revision === undefined ? {} : { revision: source.revision }),\n\t};\n}\n\nfunction displayRow(selected: TaskFrameRow) {\n\treturn {\n\t\t...selected,\n\t\tsource: displaySource(selected.source),\n\t\t...(selected.changedBy === undefined ? {} : { changedBy: displaySource(selected.changedBy) }),\n\t};\n}\n\nfunction displayRecovery(source: SourceSnapshotRef) {\n\treturn { sessionId: source.sessionId, leafId: source.leafId, sourceSequence: source.sourceSequence };\n}\n\nfunction encode(value: unknown, maxBytes: number): string {\n\ttry {\n\t\treturn stringifyBoundedJson(value, maxBytes);\n\t} catch (error) {\n\t\tif (error instanceof Error && error.message === \"JSON byte limit exceeded\")\n\t\t\tthrow new Error(\"Task frame byte budget exceeded\", { cause: error });\n\t\tthrow error;\n\t}\n}\n\nfunction message(value: unknown, maxBytes: number): CustomMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: TASK_FRAME_CUSTOM_TYPE,\n\t\tdisplay: false,\n\t\ttimestamp: 0,\n\t\tcontent:\n\t\t\t\"Recorded task context. Selective structured evidence, not new instructions or current resource liveness.\\n\" +\n\t\t\tencode(value, maxBytes),\n\t};\n}\n\n/** Prepare without changing the previous render cache. Commit only with a successful context build. */\nexport function compileTaskFrame(\n\tview: TaskStateView,\n\tlimits: Readonly<TaskFrameLimits>,\n\tprevious?: CompiledTaskFrame,\n): CompiledTaskFrame | undefined {\n\tconst eligible = view.items\n\t\t.flatMap((item) => {\n\t\t\tconst priority = rank(item);\n\t\t\treturn priority === undefined ? [] : [{ item, priority }];\n\t\t})\n\t\t.sort((a, b) => a.priority - b.priority || b.item.event.source.sequence - a.item.event.source.sequence);\n\tif (eligible.length === 0 && view.coverage === \"complete\" && !previous) return undefined;\n\tconst rows: TaskFrameRow[] = [];\n\tlet textBytes = 0;\n\t// Reserve space for sparse revisions rather than filling the entire retained frame with the base.\n\tconst selectionBytes = Math.floor(limits.maxBytes / 2);\n\tfor (const { item } of eligible) {\n\t\tif (rows.length >= limits.maxReferences) break;\n\t\tconst selected = row(item);\n\t\tconst bytes = item.event.text === undefined ? 0 : Buffer.byteLength(JSON.stringify(item.event.text));\n\t\tif (item.event.text !== undefined) {\n\t\t\tif (textBytes + bytes <= limits.maxTextBytes) selected.text = item.event.text;\n\t\t\telse selected.textOmitted = true;\n\t\t}\n\t\tif (Buffer.byteLength(JSON.stringify([...rows, selected])) > selectionBytes) {\n\t\t\tif (selected.text !== undefined) {\n\t\t\t\tdelete selected.text;\n\t\t\t\tselected.textOmitted = true;\n\t\t\t}\n\t\t\tif (Buffer.byteLength(JSON.stringify([...rows, selected])) > selectionBytes) continue;\n\t\t}\n\t\trows.push(selected);\n\t\tif (selected.text !== undefined) textBytes += bytes;\n\t}\n\tconst selection = {\n\t\tcoverage: view.coverage,\n\t\tstructuredOnly: true,\n\t\tselective: true,\n\t\teligible: eligible.length,\n\t\tindexed: rows.length,\n\t\ttextOmitted: rows.some((item) => item.textOmitted),\n\t\trows,\n\t};\n\tconst material = encode(selection, limits.maxBytes);\n\tif (previous?.material === material) {\n\t\tencode(previous.messages, limits.maxBytes);\n\t\treturn previous;\n\t}\n\tlet messages: CustomMessage[];\n\tif (!previous) {\n\t\tmessages = [\n\t\t\tmessage(\n\t\t\t\t{ type: \"base\", ...selection, rows: rows.map(displayRow), recovery: displayRecovery(view.source) },\n\t\t\t\tlimits.maxBytes,\n\t\t\t),\n\t\t];\n\t} else {\n\t\tconst old = new Map(previous.rows.map((item) => [key(item.source), JSON.stringify(item)]));\n\t\tconst current = new Set(rows.map((item) => key(item.source)));\n\t\tconst changed = rows.filter((item) => old.get(key(item.source)) !== JSON.stringify(item));\n\t\tconst noLongerSelected = previous.rows\n\t\t\t.filter((item) => !current.has(key(item.source)))\n\t\t\t.map((item) => {\n\t\t\t\tconst actual = view.items.find((candidate) => key(candidate.event.source) === key(item.source));\n\t\t\t\treturn {\n\t\t\t\t\tsource: displaySource(item.source),\n\t\t\t\t\t...(actual\n\t\t\t\t\t\t? { state: actual.state, changedBy: actual.changedBy && displaySource(actual.changedBy) }\n\t\t\t\t\t\t: {}),\n\t\t\t\t\t// Omission from this display is never itself completion, supersession or deletion.\n\t\t\t\t\tselectionOnly: true,\n\t\t\t\t};\n\t\t\t});\n\t\tmessages = [\n\t\t\t...previous.messages,\n\t\t\tmessage(\n\t\t\t\t{\n\t\t\t\t\ttype: \"revision\",\n\t\t\t\t\tcoverage: view.coverage,\n\t\t\t\t\tstructuredOnly: true,\n\t\t\t\t\tselective: true,\n\t\t\t\t\teligible: eligible.length,\n\t\t\t\t\tindexed: rows.length,\n\t\t\t\t\tchanged: changed.map(displayRow),\n\t\t\t\t\tnoLongerSelected,\n\t\t\t\t\trecovery: displayRecovery(view.source),\n\t\t\t\t},\n\t\t\t\tlimits.maxBytes,\n\t\t\t),\n\t\t];\n\t}\n\tencode(messages, limits.maxBytes);\n\treturn {\n\t\tmaterial,\n\t\trows,\n\t\tmessages,\n\t\torigins: [...(previous?.origins ?? []), { ...view.source }],\n\t\tanchors: previous ? [...previous.anchors, null] : [],\n\t};\n}\n"]}
1
+ {"version":3,"file":"task-frame.d.ts","sourceRoot":"","sources":["../../src/core/task-frame.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,eAAO,MAAM,sBAAsB,eAAe,CAAC;AAEnD,MAAM,WAAW,eAAe;IAC/B,+FAA+F;IAC/F,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,aAAa,EAAE,MAAM,CAAC;IACtB,qGAAqG;IACrG,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,eAAe,CAAC,MAAM,GAAE,OAAO,CAAC,eAAe,CAAM,GAAG,QAAQ,CAAC,eAAe,CAAC,CAchG;AAED,UAAU,YAAY;IACrB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAClC,SAAS,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC5C,KAAK,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC7C,SAAS,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;CACzB;AAED,8GAA8G;AAC9G,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,SAAS,YAAY,EAAE,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IAC5C,QAAQ,CAAC,OAAO,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC/C,qFAAqF;IACrF,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,eAAe,GAAG,IAAI,CAAC,EAAE,CAAC;CACtD;AAoLD,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAC/B,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,QAAQ,CAAC,eAAe,CAAC,EACjC,QAAQ,CAAC,EAAE,iBAAiB,GAC1B,iBAAiB,GAAG,SAAS,CAe/B","sourcesContent":["import { stringifyBoundedJson } from \"./bounded-json.js\";\nimport type { CustomMessage } from \"./messages.js\";\nimport type { SourceSnapshotRef } from \"./request-events.js\";\nimport type { TaskStateProjection, TaskStateSourceRef } from \"./task-state.js\";\nimport type { TaskStateView } from \"./task-state-reader.js\";\nimport type { ReducedTaskItem } from \"./task-state-reducer.js\";\n\nexport const TASK_FRAME_CUSTOM_TYPE = \"task_frame\";\n\nexport interface TaskFrameLimits {\n\t/** Aggregate encoded custom-message bytes, including retained sparse revisions. Not tokens. */\n\tmaxBytes: number;\n\t/** Maximum exact source references in the current selective display. */\n\tmaxReferences: number;\n\t/** UTF-8 JSON-string bytes of selected exact clauses; oversized text is referenced, never sliced. */\n\tmaxTextBytes: number;\n}\n\nexport function taskFrameLimits(limits: Partial<TaskFrameLimits> = {}): Readonly<TaskFrameLimits> {\n\tconst captured = Object.freeze({\n\t\tmaxBytes: limits.maxBytes ?? 16_384,\n\t\tmaxReferences: limits.maxReferences ?? 32,\n\t\tmaxTextBytes: limits.maxTextBytes ?? 2_048,\n\t});\n\tif (\n\t\t!Object.values(captured).every(Number.isSafeInteger) ||\n\t\tcaptured.maxBytes <= 0 ||\n\t\tcaptured.maxReferences <= 0 ||\n\t\tcaptured.maxTextBytes < 0\n\t)\n\t\tthrow new Error(\"Invalid task frame limits\");\n\treturn captured;\n}\n\ninterface TaskFrameRow {\n\tsource: TaskStateSourceRef;\n\tkind: TaskStateProjection[\"kind\"];\n\tauthority: TaskStateProjection[\"authority\"];\n\tstate: ReducedTaskItem[\"state\"];\n\titemId?: string;\n\ttaskKey?: string;\n\ttext?: string;\n\ttextOmitted?: true;\n\tresource?: string;\n\tgoalState?: TaskStateProjection[\"goalState\"];\n\trelations: TaskStateProjection[\"relations\"];\n\tchangedBy?: TaskStateSourceRef;\n\tunresolved: boolean;\n}\n\nexport interface TaskFrameAnchor {\n\tentryId: string;\n\tside: \"before\" | \"after\";\n}\n\n/** Bounded internal selected rows and frozen provider text. Reduction is rebuilt from the captured reader. */\nexport interface CompiledTaskFrame {\n\treadonly material: string;\n\treadonly rows: readonly TaskFrameRow[];\n\treadonly messages: readonly CustomMessage[];\n\treadonly origins: readonly SourceSnapshotRef[];\n\t/** One source slot per revision; null is the empty literal prefix after the base. */\n\treadonly anchors: readonly (TaskFrameAnchor | null)[];\n}\n\nfunction key(source: TaskStateSourceRef): string {\n\treturn JSON.stringify([source.sessionId, source.entryId, source.field]);\n}\n\nfunction rank(item: ReducedTaskItem): number | undefined {\n\tif (item.state === \"active\") {\n\t\tif (item.event.authority === \"instruction\") return 0;\n\t\treturn item.event.kind === \"user_goal_revision\" ? 1 : 2;\n\t}\n\tif (item.event.authority === \"unrecorded\" || item.state === \"proposal\") return undefined;\n\tif (item.event.kind === \"open_question\") return 3;\n\tif (item.event.kind === \"observed_fact\" || item.event.kind === \"artifact_state\") return 4;\n\treturn undefined;\n}\n\nfunction row(item: ReducedTaskItem): TaskFrameRow {\n\tconst event = item.event;\n\treturn {\n\t\tsource: event.source,\n\t\tkind: event.kind,\n\t\tauthority: event.authority,\n\t\tstate: item.state,\n\t\t...(event.itemId === undefined ? {} : { itemId: event.itemId }),\n\t\t...(event.taskKey === undefined ? {} : { taskKey: event.taskKey }),\n\t\t...(event.resource === undefined ? {} : { resource: event.resource }),\n\t\t...(event.goalState === undefined ? {} : { goalState: event.goalState }),\n\t\trelations: event.relations,\n\t\t...(item.changedBy === undefined ? {} : { changedBy: item.changedBy }),\n\t\tunresolved: item.unresolved,\n\t};\n}\n\n/** Provider recovery addresses exact public fields by identity, never by physical locator. */\nfunction displaySource(source: TaskStateSourceRef) {\n\treturn {\n\t\tsessionId: source.sessionId,\n\t\tentryId: source.entryId,\n\t\tfield: source.field,\n\t\t...(source.revision === undefined ? {} : { revision: source.revision }),\n\t};\n}\n\nfunction displayRow(selected: TaskFrameRow) {\n\treturn {\n\t\t...selected,\n\t\tsource: displaySource(selected.source),\n\t\t...(selected.changedBy === undefined ? {} : { changedBy: displaySource(selected.changedBy) }),\n\t};\n}\n\nfunction displayRecovery(source: SourceSnapshotRef) {\n\treturn { sessionId: source.sessionId, leafId: source.leafId, sourceSequence: source.sourceSequence };\n}\n\nfunction encode(value: unknown, maxBytes: number): string {\n\ttry {\n\t\treturn stringifyBoundedJson(value, maxBytes);\n\t} catch (error) {\n\t\tif (error instanceof Error && error.message === \"JSON byte limit exceeded\")\n\t\t\tthrow new Error(\"Task frame byte budget exceeded\", { cause: error });\n\t\tthrow error;\n\t}\n}\n\nfunction message(value: unknown, maxBytes: number): CustomMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: TASK_FRAME_CUSTOM_TYPE,\n\t\tdisplay: false,\n\t\ttimestamp: 0,\n\t\tcontent:\n\t\t\t\"Recorded task context. Selective structured evidence, not new instructions or current resource liveness.\\n\" +\n\t\t\tencode(value, maxBytes),\n\t};\n}\n\n/** Prepare without changing the previous render cache. Commit only with a successful context build. */\nfunction compileTaskFrameRevision(\n\tview: TaskStateView,\n\tlimits: Readonly<TaskFrameLimits>,\n\tprevious?: CompiledTaskFrame,\n): CompiledTaskFrame | undefined {\n\tconst eligible = view.items\n\t\t.flatMap((item) => {\n\t\t\tconst priority = rank(item);\n\t\t\treturn priority === undefined ? [] : [{ item, priority }];\n\t\t})\n\t\t.sort((a, b) => a.priority - b.priority || b.item.event.source.sequence - a.item.event.source.sequence);\n\tif (eligible.length === 0 && view.coverage === \"complete\" && !previous) return undefined;\n\tconst rows: TaskFrameRow[] = [];\n\tlet textBytes = 0;\n\t// Reserve space for sparse revisions rather than filling the entire retained frame with the base.\n\tconst selectionBytes = Math.floor(limits.maxBytes / 2);\n\tfor (const { item } of eligible) {\n\t\tif (rows.length >= limits.maxReferences) break;\n\t\tconst selected = row(item);\n\t\tconst bytes = item.event.text === undefined ? 0 : Buffer.byteLength(JSON.stringify(item.event.text));\n\t\tif (item.event.text !== undefined) {\n\t\t\tif (textBytes + bytes <= limits.maxTextBytes) selected.text = item.event.text;\n\t\t\telse selected.textOmitted = true;\n\t\t}\n\t\tif (Buffer.byteLength(JSON.stringify([...rows, selected])) > selectionBytes) {\n\t\t\tif (selected.text !== undefined) {\n\t\t\t\tdelete selected.text;\n\t\t\t\tselected.textOmitted = true;\n\t\t\t}\n\t\t\tif (Buffer.byteLength(JSON.stringify([...rows, selected])) > selectionBytes) continue;\n\t\t}\n\t\trows.push(selected);\n\t\tif (selected.text !== undefined) textBytes += bytes;\n\t}\n\tconst selection = {\n\t\tcoverage: view.coverage,\n\t\tstructuredOnly: true,\n\t\tselective: true,\n\t\teligible: eligible.length,\n\t\tindexed: rows.length,\n\t\ttextOmitted: rows.some((item) => item.textOmitted),\n\t\trows,\n\t};\n\tconst material = encode(selection, limits.maxBytes);\n\tif (previous?.material === material) {\n\t\tencode(previous.messages, limits.maxBytes);\n\t\treturn previous;\n\t}\n\tlet messages: CustomMessage[];\n\tif (!previous) {\n\t\tmessages = [\n\t\t\tmessage(\n\t\t\t\t{ type: \"base\", ...selection, rows: rows.map(displayRow), recovery: displayRecovery(view.source) },\n\t\t\t\tlimits.maxBytes,\n\t\t\t),\n\t\t];\n\t} else {\n\t\tconst old = new Map(previous.rows.map((item) => [key(item.source), JSON.stringify(item)]));\n\t\tconst current = new Set(rows.map((item) => key(item.source)));\n\t\tconst changed = rows.filter((item) => old.get(key(item.source)) !== JSON.stringify(item));\n\t\tconst noLongerSelected = previous.rows\n\t\t\t.filter((item) => !current.has(key(item.source)))\n\t\t\t.map((item) => {\n\t\t\t\tconst actual = view.items.find((candidate) => key(candidate.event.source) === key(item.source));\n\t\t\t\treturn {\n\t\t\t\t\tsource: displaySource(item.source),\n\t\t\t\t\t...(actual\n\t\t\t\t\t\t? { state: actual.state, changedBy: actual.changedBy && displaySource(actual.changedBy) }\n\t\t\t\t\t\t: {}),\n\t\t\t\t\t// Omission from this display is never itself completion, supersession or deletion.\n\t\t\t\t\tselectionOnly: true,\n\t\t\t\t};\n\t\t\t});\n\t\tmessages = [\n\t\t\t...previous.messages,\n\t\t\tmessage(\n\t\t\t\t{\n\t\t\t\t\ttype: \"revision\",\n\t\t\t\t\tcoverage: view.coverage,\n\t\t\t\t\tstructuredOnly: true,\n\t\t\t\t\tselective: true,\n\t\t\t\t\teligible: eligible.length,\n\t\t\t\t\tindexed: rows.length,\n\t\t\t\t\tchanged: changed.map(displayRow),\n\t\t\t\t\tnoLongerSelected,\n\t\t\t\t\trecovery: displayRecovery(view.source),\n\t\t\t\t},\n\t\t\t\tlimits.maxBytes,\n\t\t\t),\n\t\t];\n\t}\n\tencode(messages, limits.maxBytes);\n\treturn {\n\t\tmaterial,\n\t\trows,\n\t\tmessages,\n\t\torigins: [...(previous?.origins ?? []), { ...view.source }],\n\t\tanchors: previous ? [...previous.anchors, null] : [],\n\t};\n}\n\n/** Rebase once when the accumulated render is full; the caller still owns the epoch ACK. */\nexport function compileTaskFrame(\n\tview: TaskStateView,\n\tlimits: Readonly<TaskFrameLimits>,\n\tprevious?: CompiledTaskFrame,\n): CompiledTaskFrame | undefined {\n\ttry {\n\t\treturn compileTaskFrameRevision(view, limits, previous);\n\t} catch (error) {\n\t\tif (!(error instanceof Error) || error.message !== \"Task frame byte budget exceeded\") throw error;\n\t\tif (previous) {\n\t\t\ttry {\n\t\t\t\treturn compileTaskFrameRevision(view, limits);\n\t\t\t} catch (baseError) {\n\t\t\t\tif (!(baseError instanceof Error) || baseError.message !== \"Task frame byte budget exceeded\")\n\t\t\t\t\tthrow baseError;\n\t\t\t}\n\t\t}\n\t\tthrow new Error(\"Task frame byte budget exceeded: current base cannot fit\", { cause: error });\n\t}\n}\n"]}
@@ -86,7 +86,7 @@ function message(value, maxBytes) {
86
86
  };
87
87
  }
88
88
  /** Prepare without changing the previous render cache. Commit only with a successful context build. */
89
- export function compileTaskFrame(view, limits, previous) {
89
+ function compileTaskFrameRevision(view, limits, previous) {
90
90
  const eligible = view.items
91
91
  .flatMap((item) => {
92
92
  const priority = rank(item);
@@ -183,4 +183,24 @@ export function compileTaskFrame(view, limits, previous) {
183
183
  anchors: previous ? [...previous.anchors, null] : [],
184
184
  };
185
185
  }
186
+ /** Rebase once when the accumulated render is full; the caller still owns the epoch ACK. */
187
+ export function compileTaskFrame(view, limits, previous) {
188
+ try {
189
+ return compileTaskFrameRevision(view, limits, previous);
190
+ }
191
+ catch (error) {
192
+ if (!(error instanceof Error) || error.message !== "Task frame byte budget exceeded")
193
+ throw error;
194
+ if (previous) {
195
+ try {
196
+ return compileTaskFrameRevision(view, limits);
197
+ }
198
+ catch (baseError) {
199
+ if (!(baseError instanceof Error) || baseError.message !== "Task frame byte budget exceeded")
200
+ throw baseError;
201
+ }
202
+ }
203
+ throw new Error("Task frame byte budget exceeded: current base cannot fit", { cause: error });
204
+ }
205
+ }
186
206
  //# sourceMappingURL=task-frame.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"task-frame.js","sourceRoot":"","sources":["../../src/core/task-frame.ts"],"names":[],"mappings":"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","sourcesContent":["import { stringifyBoundedJson } from \"./bounded-json.js\";\nimport type { CustomMessage } from \"./messages.js\";\nimport type { SourceSnapshotRef } from \"./request-events.js\";\nimport type { TaskStateProjection, TaskStateSourceRef } from \"./task-state.js\";\nimport type { TaskStateView } from \"./task-state-reader.js\";\nimport type { ReducedTaskItem } from \"./task-state-reducer.js\";\n\nexport const TASK_FRAME_CUSTOM_TYPE = \"task_frame\";\n\nexport interface TaskFrameLimits {\n\t/** Aggregate encoded custom-message bytes, including retained sparse revisions. Not tokens. */\n\tmaxBytes: number;\n\t/** Maximum exact source references in the current selective display. */\n\tmaxReferences: number;\n\t/** UTF-8 JSON-string bytes of selected exact clauses; oversized text is referenced, never sliced. */\n\tmaxTextBytes: number;\n}\n\nexport function taskFrameLimits(limits: Partial<TaskFrameLimits> = {}): Readonly<TaskFrameLimits> {\n\tconst captured = Object.freeze({\n\t\tmaxBytes: limits.maxBytes ?? 16_384,\n\t\tmaxReferences: limits.maxReferences ?? 32,\n\t\tmaxTextBytes: limits.maxTextBytes ?? 2_048,\n\t});\n\tif (\n\t\t!Object.values(captured).every(Number.isSafeInteger) ||\n\t\tcaptured.maxBytes <= 0 ||\n\t\tcaptured.maxReferences <= 0 ||\n\t\tcaptured.maxTextBytes < 0\n\t)\n\t\tthrow new Error(\"Invalid task frame limits\");\n\treturn captured;\n}\n\ninterface TaskFrameRow {\n\tsource: TaskStateSourceRef;\n\tkind: TaskStateProjection[\"kind\"];\n\tauthority: TaskStateProjection[\"authority\"];\n\tstate: ReducedTaskItem[\"state\"];\n\titemId?: string;\n\ttaskKey?: string;\n\ttext?: string;\n\ttextOmitted?: true;\n\tresource?: string;\n\tgoalState?: TaskStateProjection[\"goalState\"];\n\trelations: TaskStateProjection[\"relations\"];\n\tchangedBy?: TaskStateSourceRef;\n\tunresolved: boolean;\n}\n\nexport interface TaskFrameAnchor {\n\tentryId: string;\n\tside: \"before\" | \"after\";\n}\n\n/** Bounded internal selected rows and frozen provider text. Reduction is rebuilt from the captured reader. */\nexport interface CompiledTaskFrame {\n\treadonly material: string;\n\treadonly rows: readonly TaskFrameRow[];\n\treadonly messages: readonly CustomMessage[];\n\treadonly origins: readonly SourceSnapshotRef[];\n\t/** One source slot per revision; null is the empty literal prefix after the base. */\n\treadonly anchors: readonly (TaskFrameAnchor | null)[];\n}\n\nfunction key(source: TaskStateSourceRef): string {\n\treturn JSON.stringify([source.sessionId, source.entryId, source.field]);\n}\n\nfunction rank(item: ReducedTaskItem): number | undefined {\n\tif (item.state === \"active\") {\n\t\tif (item.event.authority === \"instruction\") return 0;\n\t\treturn item.event.kind === \"user_goal_revision\" ? 1 : 2;\n\t}\n\tif (item.event.authority === \"unrecorded\" || item.state === \"proposal\") return undefined;\n\tif (item.event.kind === \"open_question\") return 3;\n\tif (item.event.kind === \"observed_fact\" || item.event.kind === \"artifact_state\") return 4;\n\treturn undefined;\n}\n\nfunction row(item: ReducedTaskItem): TaskFrameRow {\n\tconst event = item.event;\n\treturn {\n\t\tsource: event.source,\n\t\tkind: event.kind,\n\t\tauthority: event.authority,\n\t\tstate: item.state,\n\t\t...(event.itemId === undefined ? {} : { itemId: event.itemId }),\n\t\t...(event.taskKey === undefined ? {} : { taskKey: event.taskKey }),\n\t\t...(event.resource === undefined ? {} : { resource: event.resource }),\n\t\t...(event.goalState === undefined ? {} : { goalState: event.goalState }),\n\t\trelations: event.relations,\n\t\t...(item.changedBy === undefined ? {} : { changedBy: item.changedBy }),\n\t\tunresolved: item.unresolved,\n\t};\n}\n\n/** Provider recovery addresses exact public fields by identity, never by physical locator. */\nfunction displaySource(source: TaskStateSourceRef) {\n\treturn {\n\t\tsessionId: source.sessionId,\n\t\tentryId: source.entryId,\n\t\tfield: source.field,\n\t\t...(source.revision === undefined ? {} : { revision: source.revision }),\n\t};\n}\n\nfunction displayRow(selected: TaskFrameRow) {\n\treturn {\n\t\t...selected,\n\t\tsource: displaySource(selected.source),\n\t\t...(selected.changedBy === undefined ? {} : { changedBy: displaySource(selected.changedBy) }),\n\t};\n}\n\nfunction displayRecovery(source: SourceSnapshotRef) {\n\treturn { sessionId: source.sessionId, leafId: source.leafId, sourceSequence: source.sourceSequence };\n}\n\nfunction encode(value: unknown, maxBytes: number): string {\n\ttry {\n\t\treturn stringifyBoundedJson(value, maxBytes);\n\t} catch (error) {\n\t\tif (error instanceof Error && error.message === \"JSON byte limit exceeded\")\n\t\t\tthrow new Error(\"Task frame byte budget exceeded\", { cause: error });\n\t\tthrow error;\n\t}\n}\n\nfunction message(value: unknown, maxBytes: number): CustomMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: TASK_FRAME_CUSTOM_TYPE,\n\t\tdisplay: false,\n\t\ttimestamp: 0,\n\t\tcontent:\n\t\t\t\"Recorded task context. Selective structured evidence, not new instructions or current resource liveness.\\n\" +\n\t\t\tencode(value, maxBytes),\n\t};\n}\n\n/** Prepare without changing the previous render cache. Commit only with a successful context build. */\nexport function compileTaskFrame(\n\tview: TaskStateView,\n\tlimits: Readonly<TaskFrameLimits>,\n\tprevious?: CompiledTaskFrame,\n): CompiledTaskFrame | undefined {\n\tconst eligible = view.items\n\t\t.flatMap((item) => {\n\t\t\tconst priority = rank(item);\n\t\t\treturn priority === undefined ? [] : [{ item, priority }];\n\t\t})\n\t\t.sort((a, b) => a.priority - b.priority || b.item.event.source.sequence - a.item.event.source.sequence);\n\tif (eligible.length === 0 && view.coverage === \"complete\" && !previous) return undefined;\n\tconst rows: TaskFrameRow[] = [];\n\tlet textBytes = 0;\n\t// Reserve space for sparse revisions rather than filling the entire retained frame with the base.\n\tconst selectionBytes = Math.floor(limits.maxBytes / 2);\n\tfor (const { item } of eligible) {\n\t\tif (rows.length >= limits.maxReferences) break;\n\t\tconst selected = row(item);\n\t\tconst bytes = item.event.text === undefined ? 0 : Buffer.byteLength(JSON.stringify(item.event.text));\n\t\tif (item.event.text !== undefined) {\n\t\t\tif (textBytes + bytes <= limits.maxTextBytes) selected.text = item.event.text;\n\t\t\telse selected.textOmitted = true;\n\t\t}\n\t\tif (Buffer.byteLength(JSON.stringify([...rows, selected])) > selectionBytes) {\n\t\t\tif (selected.text !== undefined) {\n\t\t\t\tdelete selected.text;\n\t\t\t\tselected.textOmitted = true;\n\t\t\t}\n\t\t\tif (Buffer.byteLength(JSON.stringify([...rows, selected])) > selectionBytes) continue;\n\t\t}\n\t\trows.push(selected);\n\t\tif (selected.text !== undefined) textBytes += bytes;\n\t}\n\tconst selection = {\n\t\tcoverage: view.coverage,\n\t\tstructuredOnly: true,\n\t\tselective: true,\n\t\teligible: eligible.length,\n\t\tindexed: rows.length,\n\t\ttextOmitted: rows.some((item) => item.textOmitted),\n\t\trows,\n\t};\n\tconst material = encode(selection, limits.maxBytes);\n\tif (previous?.material === material) {\n\t\tencode(previous.messages, limits.maxBytes);\n\t\treturn previous;\n\t}\n\tlet messages: CustomMessage[];\n\tif (!previous) {\n\t\tmessages = [\n\t\t\tmessage(\n\t\t\t\t{ type: \"base\", ...selection, rows: rows.map(displayRow), recovery: displayRecovery(view.source) },\n\t\t\t\tlimits.maxBytes,\n\t\t\t),\n\t\t];\n\t} else {\n\t\tconst old = new Map(previous.rows.map((item) => [key(item.source), JSON.stringify(item)]));\n\t\tconst current = new Set(rows.map((item) => key(item.source)));\n\t\tconst changed = rows.filter((item) => old.get(key(item.source)) !== JSON.stringify(item));\n\t\tconst noLongerSelected = previous.rows\n\t\t\t.filter((item) => !current.has(key(item.source)))\n\t\t\t.map((item) => {\n\t\t\t\tconst actual = view.items.find((candidate) => key(candidate.event.source) === key(item.source));\n\t\t\t\treturn {\n\t\t\t\t\tsource: displaySource(item.source),\n\t\t\t\t\t...(actual\n\t\t\t\t\t\t? { state: actual.state, changedBy: actual.changedBy && displaySource(actual.changedBy) }\n\t\t\t\t\t\t: {}),\n\t\t\t\t\t// Omission from this display is never itself completion, supersession or deletion.\n\t\t\t\t\tselectionOnly: true,\n\t\t\t\t};\n\t\t\t});\n\t\tmessages = [\n\t\t\t...previous.messages,\n\t\t\tmessage(\n\t\t\t\t{\n\t\t\t\t\ttype: \"revision\",\n\t\t\t\t\tcoverage: view.coverage,\n\t\t\t\t\tstructuredOnly: true,\n\t\t\t\t\tselective: true,\n\t\t\t\t\teligible: eligible.length,\n\t\t\t\t\tindexed: rows.length,\n\t\t\t\t\tchanged: changed.map(displayRow),\n\t\t\t\t\tnoLongerSelected,\n\t\t\t\t\trecovery: displayRecovery(view.source),\n\t\t\t\t},\n\t\t\t\tlimits.maxBytes,\n\t\t\t),\n\t\t];\n\t}\n\tencode(messages, limits.maxBytes);\n\treturn {\n\t\tmaterial,\n\t\trows,\n\t\tmessages,\n\t\torigins: [...(previous?.origins ?? []), { ...view.source }],\n\t\tanchors: previous ? [...previous.anchors, null] : [],\n\t};\n}\n"]}
1
+ {"version":3,"file":"task-frame.js","sourceRoot":"","sources":["../../src/core/task-frame.ts"],"names":[],"mappings":"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","sourcesContent":["import { stringifyBoundedJson } from \"./bounded-json.js\";\nimport type { CustomMessage } from \"./messages.js\";\nimport type { SourceSnapshotRef } from \"./request-events.js\";\nimport type { TaskStateProjection, TaskStateSourceRef } from \"./task-state.js\";\nimport type { TaskStateView } from \"./task-state-reader.js\";\nimport type { ReducedTaskItem } from \"./task-state-reducer.js\";\n\nexport const TASK_FRAME_CUSTOM_TYPE = \"task_frame\";\n\nexport interface TaskFrameLimits {\n\t/** Aggregate encoded custom-message bytes, including retained sparse revisions. Not tokens. */\n\tmaxBytes: number;\n\t/** Maximum exact source references in the current selective display. */\n\tmaxReferences: number;\n\t/** UTF-8 JSON-string bytes of selected exact clauses; oversized text is referenced, never sliced. */\n\tmaxTextBytes: number;\n}\n\nexport function taskFrameLimits(limits: Partial<TaskFrameLimits> = {}): Readonly<TaskFrameLimits> {\n\tconst captured = Object.freeze({\n\t\tmaxBytes: limits.maxBytes ?? 16_384,\n\t\tmaxReferences: limits.maxReferences ?? 32,\n\t\tmaxTextBytes: limits.maxTextBytes ?? 2_048,\n\t});\n\tif (\n\t\t!Object.values(captured).every(Number.isSafeInteger) ||\n\t\tcaptured.maxBytes <= 0 ||\n\t\tcaptured.maxReferences <= 0 ||\n\t\tcaptured.maxTextBytes < 0\n\t)\n\t\tthrow new Error(\"Invalid task frame limits\");\n\treturn captured;\n}\n\ninterface TaskFrameRow {\n\tsource: TaskStateSourceRef;\n\tkind: TaskStateProjection[\"kind\"];\n\tauthority: TaskStateProjection[\"authority\"];\n\tstate: ReducedTaskItem[\"state\"];\n\titemId?: string;\n\ttaskKey?: string;\n\ttext?: string;\n\ttextOmitted?: true;\n\tresource?: string;\n\tgoalState?: TaskStateProjection[\"goalState\"];\n\trelations: TaskStateProjection[\"relations\"];\n\tchangedBy?: TaskStateSourceRef;\n\tunresolved: boolean;\n}\n\nexport interface TaskFrameAnchor {\n\tentryId: string;\n\tside: \"before\" | \"after\";\n}\n\n/** Bounded internal selected rows and frozen provider text. Reduction is rebuilt from the captured reader. */\nexport interface CompiledTaskFrame {\n\treadonly material: string;\n\treadonly rows: readonly TaskFrameRow[];\n\treadonly messages: readonly CustomMessage[];\n\treadonly origins: readonly SourceSnapshotRef[];\n\t/** One source slot per revision; null is the empty literal prefix after the base. */\n\treadonly anchors: readonly (TaskFrameAnchor | null)[];\n}\n\nfunction key(source: TaskStateSourceRef): string {\n\treturn JSON.stringify([source.sessionId, source.entryId, source.field]);\n}\n\nfunction rank(item: ReducedTaskItem): number | undefined {\n\tif (item.state === \"active\") {\n\t\tif (item.event.authority === \"instruction\") return 0;\n\t\treturn item.event.kind === \"user_goal_revision\" ? 1 : 2;\n\t}\n\tif (item.event.authority === \"unrecorded\" || item.state === \"proposal\") return undefined;\n\tif (item.event.kind === \"open_question\") return 3;\n\tif (item.event.kind === \"observed_fact\" || item.event.kind === \"artifact_state\") return 4;\n\treturn undefined;\n}\n\nfunction row(item: ReducedTaskItem): TaskFrameRow {\n\tconst event = item.event;\n\treturn {\n\t\tsource: event.source,\n\t\tkind: event.kind,\n\t\tauthority: event.authority,\n\t\tstate: item.state,\n\t\t...(event.itemId === undefined ? {} : { itemId: event.itemId }),\n\t\t...(event.taskKey === undefined ? {} : { taskKey: event.taskKey }),\n\t\t...(event.resource === undefined ? {} : { resource: event.resource }),\n\t\t...(event.goalState === undefined ? {} : { goalState: event.goalState }),\n\t\trelations: event.relations,\n\t\t...(item.changedBy === undefined ? {} : { changedBy: item.changedBy }),\n\t\tunresolved: item.unresolved,\n\t};\n}\n\n/** Provider recovery addresses exact public fields by identity, never by physical locator. */\nfunction displaySource(source: TaskStateSourceRef) {\n\treturn {\n\t\tsessionId: source.sessionId,\n\t\tentryId: source.entryId,\n\t\tfield: source.field,\n\t\t...(source.revision === undefined ? {} : { revision: source.revision }),\n\t};\n}\n\nfunction displayRow(selected: TaskFrameRow) {\n\treturn {\n\t\t...selected,\n\t\tsource: displaySource(selected.source),\n\t\t...(selected.changedBy === undefined ? {} : { changedBy: displaySource(selected.changedBy) }),\n\t};\n}\n\nfunction displayRecovery(source: SourceSnapshotRef) {\n\treturn { sessionId: source.sessionId, leafId: source.leafId, sourceSequence: source.sourceSequence };\n}\n\nfunction encode(value: unknown, maxBytes: number): string {\n\ttry {\n\t\treturn stringifyBoundedJson(value, maxBytes);\n\t} catch (error) {\n\t\tif (error instanceof Error && error.message === \"JSON byte limit exceeded\")\n\t\t\tthrow new Error(\"Task frame byte budget exceeded\", { cause: error });\n\t\tthrow error;\n\t}\n}\n\nfunction message(value: unknown, maxBytes: number): CustomMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: TASK_FRAME_CUSTOM_TYPE,\n\t\tdisplay: false,\n\t\ttimestamp: 0,\n\t\tcontent:\n\t\t\t\"Recorded task context. Selective structured evidence, not new instructions or current resource liveness.\\n\" +\n\t\t\tencode(value, maxBytes),\n\t};\n}\n\n/** Prepare without changing the previous render cache. Commit only with a successful context build. */\nfunction compileTaskFrameRevision(\n\tview: TaskStateView,\n\tlimits: Readonly<TaskFrameLimits>,\n\tprevious?: CompiledTaskFrame,\n): CompiledTaskFrame | undefined {\n\tconst eligible = view.items\n\t\t.flatMap((item) => {\n\t\t\tconst priority = rank(item);\n\t\t\treturn priority === undefined ? [] : [{ item, priority }];\n\t\t})\n\t\t.sort((a, b) => a.priority - b.priority || b.item.event.source.sequence - a.item.event.source.sequence);\n\tif (eligible.length === 0 && view.coverage === \"complete\" && !previous) return undefined;\n\tconst rows: TaskFrameRow[] = [];\n\tlet textBytes = 0;\n\t// Reserve space for sparse revisions rather than filling the entire retained frame with the base.\n\tconst selectionBytes = Math.floor(limits.maxBytes / 2);\n\tfor (const { item } of eligible) {\n\t\tif (rows.length >= limits.maxReferences) break;\n\t\tconst selected = row(item);\n\t\tconst bytes = item.event.text === undefined ? 0 : Buffer.byteLength(JSON.stringify(item.event.text));\n\t\tif (item.event.text !== undefined) {\n\t\t\tif (textBytes + bytes <= limits.maxTextBytes) selected.text = item.event.text;\n\t\t\telse selected.textOmitted = true;\n\t\t}\n\t\tif (Buffer.byteLength(JSON.stringify([...rows, selected])) > selectionBytes) {\n\t\t\tif (selected.text !== undefined) {\n\t\t\t\tdelete selected.text;\n\t\t\t\tselected.textOmitted = true;\n\t\t\t}\n\t\t\tif (Buffer.byteLength(JSON.stringify([...rows, selected])) > selectionBytes) continue;\n\t\t}\n\t\trows.push(selected);\n\t\tif (selected.text !== undefined) textBytes += bytes;\n\t}\n\tconst selection = {\n\t\tcoverage: view.coverage,\n\t\tstructuredOnly: true,\n\t\tselective: true,\n\t\teligible: eligible.length,\n\t\tindexed: rows.length,\n\t\ttextOmitted: rows.some((item) => item.textOmitted),\n\t\trows,\n\t};\n\tconst material = encode(selection, limits.maxBytes);\n\tif (previous?.material === material) {\n\t\tencode(previous.messages, limits.maxBytes);\n\t\treturn previous;\n\t}\n\tlet messages: CustomMessage[];\n\tif (!previous) {\n\t\tmessages = [\n\t\t\tmessage(\n\t\t\t\t{ type: \"base\", ...selection, rows: rows.map(displayRow), recovery: displayRecovery(view.source) },\n\t\t\t\tlimits.maxBytes,\n\t\t\t),\n\t\t];\n\t} else {\n\t\tconst old = new Map(previous.rows.map((item) => [key(item.source), JSON.stringify(item)]));\n\t\tconst current = new Set(rows.map((item) => key(item.source)));\n\t\tconst changed = rows.filter((item) => old.get(key(item.source)) !== JSON.stringify(item));\n\t\tconst noLongerSelected = previous.rows\n\t\t\t.filter((item) => !current.has(key(item.source)))\n\t\t\t.map((item) => {\n\t\t\t\tconst actual = view.items.find((candidate) => key(candidate.event.source) === key(item.source));\n\t\t\t\treturn {\n\t\t\t\t\tsource: displaySource(item.source),\n\t\t\t\t\t...(actual\n\t\t\t\t\t\t? { state: actual.state, changedBy: actual.changedBy && displaySource(actual.changedBy) }\n\t\t\t\t\t\t: {}),\n\t\t\t\t\t// Omission from this display is never itself completion, supersession or deletion.\n\t\t\t\t\tselectionOnly: true,\n\t\t\t\t};\n\t\t\t});\n\t\tmessages = [\n\t\t\t...previous.messages,\n\t\t\tmessage(\n\t\t\t\t{\n\t\t\t\t\ttype: \"revision\",\n\t\t\t\t\tcoverage: view.coverage,\n\t\t\t\t\tstructuredOnly: true,\n\t\t\t\t\tselective: true,\n\t\t\t\t\teligible: eligible.length,\n\t\t\t\t\tindexed: rows.length,\n\t\t\t\t\tchanged: changed.map(displayRow),\n\t\t\t\t\tnoLongerSelected,\n\t\t\t\t\trecovery: displayRecovery(view.source),\n\t\t\t\t},\n\t\t\t\tlimits.maxBytes,\n\t\t\t),\n\t\t];\n\t}\n\tencode(messages, limits.maxBytes);\n\treturn {\n\t\tmaterial,\n\t\trows,\n\t\tmessages,\n\t\torigins: [...(previous?.origins ?? []), { ...view.source }],\n\t\tanchors: previous ? [...previous.anchors, null] : [],\n\t};\n}\n\n/** Rebase once when the accumulated render is full; the caller still owns the epoch ACK. */\nexport function compileTaskFrame(\n\tview: TaskStateView,\n\tlimits: Readonly<TaskFrameLimits>,\n\tprevious?: CompiledTaskFrame,\n): CompiledTaskFrame | undefined {\n\ttry {\n\t\treturn compileTaskFrameRevision(view, limits, previous);\n\t} catch (error) {\n\t\tif (!(error instanceof Error) || error.message !== \"Task frame byte budget exceeded\") throw error;\n\t\tif (previous) {\n\t\t\ttry {\n\t\t\t\treturn compileTaskFrameRevision(view, limits);\n\t\t\t} catch (baseError) {\n\t\t\t\tif (!(baseError instanceof Error) || baseError.message !== \"Task frame byte budget exceeded\")\n\t\t\t\t\tthrow baseError;\n\t\t\t}\n\t\t}\n\t\tthrow new Error(\"Task frame byte budget exceeded: current base cannot fit\", { cause: error });\n\t}\n}\n"]}
@@ -9,8 +9,16 @@ export interface TaskStateView {
9
9
  selective: true;
10
10
  items: ReducedTaskItem[];
11
11
  }
12
+ type TaskHistory = Pick<SessionHistoryReadScope, "source" | "branchContext" | "hydrateEntry">;
12
13
  /** Consume this complete-or-refuse view inside its existing captured-history callback. */
13
- export declare function readTaskStateFromHistory(history: Pick<SessionHistoryReadScope, "source" | "branchContext" | "hydrateEntry">, limits?: Partial<TaskStateReadLimits>): Promise<TaskStateView>;
14
- /** Adapt the existing branch-only inference view; never recapture through its Manager. */
14
+ export declare function readTaskStateFromHistory(history: TaskHistory, limits?: Partial<TaskStateReadLimits>): Promise<TaskStateView>;
15
15
  export declare function readTaskStateFromView(view: SessionHistoryReadView, limits?: Partial<TaskStateReadLimits>): Promise<TaskStateView>;
16
+ /** Compiler-owned derived state only. Returned views are internal and must not be mutated. */
17
+ export declare class TaskStateReadCache {
18
+ private state?;
19
+ private generation;
20
+ clear(): void;
21
+ read(view: SessionHistoryReadView, supplied?: Partial<TaskStateReadLimits>): Promise<TaskStateView>;
22
+ }
23
+ export {};
16
24
  //# sourceMappingURL=task-state-reader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"task-state-reader.d.ts","sourceRoot":"","sources":["../../src/core/task-state-reader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAEN,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,mBAAmB,EAAoB,MAAM,yBAAyB,CAAC;AAE3G,MAAM,WAAW,aAAa;IAC7B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,EAAE,UAAU,GAAG,SAAS,CAAC;IACjC,4FAA4F;IAC5F,cAAc,EAAE,IAAI,CAAC;IACrB,SAAS,EAAE,IAAI,CAAC;IAChB,KAAK,EAAE,eAAe,EAAE,CAAC;CACzB;AAED,0FAA0F;AAC1F,wBAAsB,wBAAwB,CAC7C,OAAO,EAAE,IAAI,CAAC,uBAAuB,EAAE,QAAQ,GAAG,eAAe,GAAG,cAAc,CAAC,EACnF,MAAM,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACvC,OAAO,CAAC,aAAa,CAAC,CAwDxB;AAED,0FAA0F;AAC1F,wBAAgB,qBAAqB,CACpC,IAAI,EAAE,sBAAsB,EAC5B,MAAM,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACvC,OAAO,CAAC,aAAa,CAAC,CAgBxB","sourcesContent":["import type { TaskEvidenceCursor } from \"./history-index.js\";\nimport type { SourceSnapshotRef } from \"./request-events.js\";\nimport {\n\thydrateCapturedHistoryEntry,\n\ttype SessionHistoryReadScope,\n\ttype SessionHistoryReadView,\n} from \"./session-history-index.js\";\nimport { projectTaskStateSource, type TaskStateProjection } from \"./task-state.js\";\nimport { type ReducedTaskItem, type TaskStateReadLimits, TaskStateReducer } from \"./task-state-reducer.js\";\n\nexport interface TaskStateView {\n\tsource: SourceSnapshotRef;\n\tcoverage: \"complete\" | \"partial\";\n\t/** Complete structured branch reduction, not exhaustive semantic requirement extraction. */\n\tstructuredOnly: true;\n\tselective: true;\n\titems: ReducedTaskItem[];\n}\n\n/** Consume this complete-or-refuse view inside its existing captured-history callback. */\nexport async function readTaskStateFromHistory(\n\thistory: Pick<SessionHistoryReadScope, \"source\" | \"branchContext\" | \"hydrateEntry\">,\n\tlimits: Partial<TaskStateReadLimits> = {},\n): Promise<TaskStateView> {\n\tconst reducer = new TaskStateReducer(limits);\n\tlet after: TaskEvidenceCursor | null = null;\n\tlet coverage: TaskStateView[\"coverage\"] = \"complete\";\n\tlet sourceBytes = 0;\n\tlet sourceSequence = -1;\n\tlet projected: Generator<TaskStateProjection> | undefined;\n\tlet projectedOrdinal = -1;\n\tfor (;;) {\n\t\tconst page = await history.branchContext.taskEvidence({ after, limit: 64 });\n\t\tif (page.indexedThrough < history.source.sourceSequence)\n\t\t\tthrow new Error(\"Task-state source index coverage is incomplete\");\n\t\tif (page.coverage === \"partial\") coverage = \"partial\";\n\t\tfor (const row of page.entries) {\n\t\t\tconst source = row.truncated ? row.source : row.projection.source;\n\t\t\tif (row.sequence !== sourceSequence) {\n\t\t\t\tprojected = undefined;\n\t\t\t\tprojectedOrdinal = -1;\n\t\t\t\tif (!source.locator) throw new Error(\"Task-state source locator is unavailable\");\n\t\t\t\tsourceBytes += source.locator.length;\n\t\t\t\tif (sourceBytes > reducer.limits.maxSourceBytes) throw new Error(\"Task-state source byte budget exceeded\");\n\t\t\t\tsourceSequence = row.sequence;\n\t\t\t}\n\t\t\tif (!row.truncated) {\n\t\t\t\treducer.add(row.projection);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!projected) {\n\t\t\t\tconst hydrated = await history.hydrateEntry(source.entryId, source.locator!.length);\n\t\t\t\tif (!hydrated) throw new Error(\"Task-state source is unavailable\");\n\t\t\t\tprojected = projectTaskStateSource({\n\t\t\t\t\t...hydrated.source,\n\t\t\t\t\tsessionId: history.source.sessionId,\n\t\t\t\t\tentry: hydrated.entry,\n\t\t\t\t});\n\t\t\t}\n\t\t\tlet projection: TaskStateProjection | undefined;\n\t\t\twhile (projectedOrdinal < row.ordinal) {\n\t\t\t\tif (++projectedOrdinal >= reducer.limits.maxItems) throw new Error(\"Task-state item budget exceeded\");\n\t\t\t\tconst next = projected.next();\n\t\t\t\tif (next.done) throw new Error(\"Task-state projection source is unavailable\");\n\t\t\t\tprojection = next.value;\n\t\t\t}\n\t\t\tif (!projection || projection.source.field !== source.field)\n\t\t\t\tthrow new Error(\"Task-state projection source does not match its indexed reference\");\n\t\t\treducer.add(projection);\n\t\t}\n\t\tif (!page.nextAfter) break;\n\t\tafter = page.nextAfter;\n\t}\n\treturn reducer.finish({\n\t\tsource: { ...history.source },\n\t\tcoverage,\n\t\tstructuredOnly: true as const,\n\t\tselective: true as const,\n\t});\n}\n\n/** Adapt the existing branch-only inference view; never recapture through its Manager. */\nexport function readTaskStateFromView(\n\tview: SessionHistoryReadView,\n\tlimits: Partial<TaskStateReadLimits> = {},\n): Promise<TaskStateView> {\n\treturn readTaskStateFromHistory(\n\t\t{\n\t\t\tsource: view.source,\n\t\t\tbranchContext: view,\n\t\t\thydrateEntry: async (id, maxSourceBytes) => {\n\t\t\t\tconst source = await view.get(id);\n\t\t\t\treturn source\n\t\t\t\t\t? hydrateCapturedHistoryEntry(source, maxSourceBytes, (entryId, options) =>\n\t\t\t\t\t\t\tview.readPayload(entryId, options),\n\t\t\t\t\t\t)\n\t\t\t\t\t: undefined;\n\t\t\t},\n\t\t},\n\t\tlimits,\n\t);\n}\n"]}
1
+ {"version":3,"file":"task-state-reader.d.ts","sourceRoot":"","sources":["../../src/core/task-state-reader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAEN,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACN,KAAK,eAAe,EACpB,KAAK,mBAAmB,EAGxB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,aAAa;IAC7B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,EAAE,UAAU,GAAG,SAAS,CAAC;IACjC,4FAA4F;IAC5F,cAAc,EAAE,IAAI,CAAC;IACrB,SAAS,EAAE,IAAI,CAAC;IAChB,KAAK,EAAE,eAAe,EAAE,CAAC;CACzB;AAED,KAAK,WAAW,GAAG,IAAI,CAAC,uBAAuB,EAAE,QAAQ,GAAG,eAAe,GAAG,cAAc,CAAC,CAAC;AAQ9F,0FAA0F;AAC1F,wBAAgB,wBAAwB,CACvC,OAAO,EAAE,WAAW,EACpB,MAAM,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACvC,OAAO,CAAC,aAAa,CAAC,CAExB;AAoFD,wBAAgB,qBAAqB,CACpC,IAAI,EAAE,sBAAsB,EAC5B,MAAM,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACvC,OAAO,CAAC,aAAa,CAAC,CAExB;AAED,8FAA8F;AAC9F,qBAAa,kBAAkB;IAC9B,OAAO,CAAC,KAAK,CAAC,CAAY;IAC1B,OAAO,CAAC,UAAU,CAAK;IAEvB,KAAK,IAAI,IAAI,CAGZ;IAEK,IAAI,CAAC,IAAI,EAAE,sBAAsB,EAAE,QAAQ,GAAE,OAAO,CAAC,mBAAmB,CAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAoD5G;CACD","sourcesContent":["import type { TaskEvidenceCursor, TaskEvidencePage } from \"./history-index.js\";\nimport type { SourceSnapshotRef } from \"./request-events.js\";\nimport {\n\thydrateCapturedHistoryEntry,\n\ttype SessionHistoryReadScope,\n\ttype SessionHistoryReadView,\n} from \"./session-history-index.js\";\nimport { projectTaskStateSource, type TaskStateProjection } from \"./task-state.js\";\nimport {\n\ttype ReducedTaskItem,\n\ttype TaskStateReadLimits,\n\tTaskStateReducer,\n\ttaskStateReadLimits,\n} from \"./task-state-reducer.js\";\n\nexport interface TaskStateView {\n\tsource: SourceSnapshotRef;\n\tcoverage: \"complete\" | \"partial\";\n\t/** Complete structured branch reduction, not exhaustive semantic requirement extraction. */\n\tstructuredOnly: true;\n\tselective: true;\n\titems: ReducedTaskItem[];\n}\n\ntype TaskHistory = Pick<SessionHistoryReadScope, \"source\" | \"branchContext\" | \"hydrateEntry\">;\ninterface Reduction {\n\treducer: TaskStateReducer;\n\tsourceBytes: number;\n\tidentity?: TaskEvidencePage[\"sourceIdentity\"];\n\tview?: TaskStateView;\n}\n\n/** Consume this complete-or-refuse view inside its existing captured-history callback. */\nexport function readTaskStateFromHistory(\n\thistory: TaskHistory,\n\tlimits: Partial<TaskStateReadLimits> = {},\n): Promise<TaskStateView> {\n\treturn reduceHistory(history, { reducer: new TaskStateReducer(limits), sourceBytes: 0 });\n}\n\nasync function reduceHistory(\n\thistory: TaskHistory,\n\tstate: Reduction,\n\tfirstPage?: TaskEvidencePage,\n): Promise<TaskStateView> {\n\tconst { reducer } = state;\n\tlet after: TaskEvidenceCursor | null = null;\n\tlet coverage: TaskStateView[\"coverage\"] = \"complete\";\n\tlet sourceBytes = state.sourceBytes;\n\tlet sourceSequence = -1;\n\tlet projected: Generator<TaskStateProjection> | undefined;\n\tlet projectedOrdinal = -1;\n\tfor (;;) {\n\t\tconst page: TaskEvidencePage = firstPage ?? (await history.branchContext.taskEvidence({ after, limit: 64 }));\n\t\tfirstPage = undefined;\n\t\tstate.identity = page.sourceIdentity;\n\t\tif (page.indexedThrough < history.source.sourceSequence)\n\t\t\tthrow new Error(\"Task-state source index coverage is incomplete\");\n\t\tif (page.coverage === \"partial\") coverage = \"partial\";\n\t\tfor (const row of page.entries) {\n\t\t\tconst source = row.truncated ? row.source : row.projection.source;\n\t\t\tif (row.sequence !== sourceSequence) {\n\t\t\t\tprojected = undefined;\n\t\t\t\tprojectedOrdinal = -1;\n\t\t\t\tif (!source.locator) throw new Error(\"Task-state source locator is unavailable\");\n\t\t\t\tsourceBytes += source.locator.length;\n\t\t\t\tif (sourceBytes > reducer.limits.maxSourceBytes) throw new Error(\"Task-state source byte budget exceeded\");\n\t\t\t\tsourceSequence = row.sequence;\n\t\t\t}\n\t\t\tif (!row.truncated) {\n\t\t\t\treducer.add(row.projection);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!projected) {\n\t\t\t\tconst hydrated = await history.hydrateEntry(source.entryId, source.locator!.length);\n\t\t\t\tif (!hydrated) throw new Error(\"Task-state source is unavailable\");\n\t\t\t\tprojected = projectTaskStateSource({\n\t\t\t\t\t...hydrated.source,\n\t\t\t\t\tsessionId: history.source.sessionId,\n\t\t\t\t\tentry: hydrated.entry,\n\t\t\t\t});\n\t\t\t}\n\t\t\tlet projection: TaskStateProjection | undefined;\n\t\t\twhile (projectedOrdinal < row.ordinal) {\n\t\t\t\tif (++projectedOrdinal >= reducer.limits.maxItems) throw new Error(\"Task-state item budget exceeded\");\n\t\t\t\tconst next = projected.next();\n\t\t\t\tif (next.done) throw new Error(\"Task-state projection source is unavailable\");\n\t\t\t\tprojection = next.value;\n\t\t\t}\n\t\t\tif (!projection || projection.source.field !== source.field)\n\t\t\t\tthrow new Error(\"Task-state projection source does not match its indexed reference\");\n\t\t\treducer.add(projection);\n\t\t}\n\t\tif (!page.nextAfter) break;\n\t\tafter = page.nextAfter;\n\t}\n\tstate.sourceBytes = sourceBytes;\n\tstate.view = reducer.finish({\n\t\tsource: { ...history.source },\n\t\tcoverage,\n\t\tstructuredOnly: true as const,\n\t\tselective: true as const,\n\t});\n\treturn state.view;\n}\n\n/** Adapt the existing branch-only inference view; never recapture through its Manager. */\nfunction taskHistory(view: SessionHistoryReadView): TaskHistory {\n\treturn {\n\t\tsource: view.source,\n\t\tbranchContext: view,\n\t\thydrateEntry: async (id, maxSourceBytes) => {\n\t\t\tconst source = await view.get(id);\n\t\t\treturn source\n\t\t\t\t? hydrateCapturedHistoryEntry(source, maxSourceBytes, (entryId, options) =>\n\t\t\t\t\t\tview.readPayload(entryId, options),\n\t\t\t\t\t)\n\t\t\t\t: undefined;\n\t\t},\n\t};\n}\n\nexport function readTaskStateFromView(\n\tview: SessionHistoryReadView,\n\tlimits: Partial<TaskStateReadLimits> = {},\n): Promise<TaskStateView> {\n\treturn readTaskStateFromHistory(taskHistory(view), limits);\n}\n\n/** Compiler-owned derived state only. Returned views are internal and must not be mutated. */\nexport class TaskStateReadCache {\n\tprivate state?: Reduction;\n\tprivate generation = 0;\n\n\tclear(): void {\n\t\tthis.generation++;\n\t\tthis.state = undefined;\n\t}\n\n\tasync read(view: SessionHistoryReadView, supplied: Partial<TaskStateReadLimits> = {}): Promise<TaskStateView> {\n\t\tconst limits = taskStateReadLimits(supplied);\n\t\tconst cached = this.state;\n\t\tconst generation = ++this.generation;\n\t\t// A failed or overlapping read cannot publish a partially mutated reducer.\n\t\tthis.state = undefined;\n\t\tconst previous = cached?.view?.source;\n\t\tlet compatible = Boolean(\n\t\t\tcached?.identity &&\n\t\t\t\tprevious &&\n\t\t\t\tprevious.sessionId === view.source.sessionId &&\n\t\t\t\tprevious.sessionFile === view.source.sessionFile &&\n\t\t\t\tprevious.persistent === view.source.persistent &&\n\t\t\t\tprevious.sourceSequence <= view.source.sourceSequence &&\n\t\t\t\tObject.entries(limits).every(\n\t\t\t\t\t([key, value]) => cached!.reducer.limits[key as keyof TaskStateReadLimits] === value,\n\t\t\t\t),\n\t\t);\n\t\tif (compatible && previous!.leafId !== view.source.leafId) {\n\t\t\tconst oldLeaf = previous!.leafId === null ? undefined : await view.get(previous!.leafId);\n\t\t\tconst newLeaf = view.source.leafId === null ? undefined : await view.get(view.source.leafId);\n\t\t\t// Moving to a pre-existing descendant is branch navigation, not an append.\n\t\t\tcompatible = Boolean(oldLeaf && newLeaf && newLeaf.sequence > previous!.sourceSequence);\n\t\t}\n\t\tlet state: Reduction = compatible ? cached! : { reducer: new TaskStateReducer(limits), sourceBytes: 0 };\n\t\tlet page = await view.taskEvidence({\n\t\t\tafter: compatible ? { sequence: previous!.sourceSequence, ordinal: Number.MAX_SAFE_INTEGER } : null,\n\t\t\tlimit: 64,\n\t\t});\n\t\tif (\n\t\t\tcompatible &&\n\t\t\t(!page.sourceIdentity ||\n\t\t\t\tpage.sourceIdentity.journalPath !== cached!.identity!.journalPath ||\n\t\t\t\tpage.sourceIdentity.dev !== cached!.identity!.dev ||\n\t\t\t\tpage.sourceIdentity.ino !== cached!.identity!.ino)\n\t\t) {\n\t\t\tstate = { reducer: new TaskStateReducer(limits), sourceBytes: 0 };\n\t\t\tcompatible = false;\n\t\t\tpage = await view.taskEvidence({ after: null, limit: 64 });\n\t\t}\n\t\tif (page.indexedThrough < view.source.sourceSequence)\n\t\t\tthrow new Error(\"Task-state source index coverage is incomplete\");\n\t\tconst unchanged =\n\t\t\tcompatible &&\n\t\t\tprevious!.sourceSequence === view.source.sourceSequence &&\n\t\t\tprevious!.leafId === view.source.leafId &&\n\t\t\tpage.entries.length === 0 &&\n\t\t\t!page.nextAfter &&\n\t\t\tpage.coverage === state.view!.coverage;\n\t\tconst result = unchanged ? state.view! : await reduceHistory(taskHistory(view), state, page);\n\t\tif (generation === this.generation) this.state = state;\n\t\treturn result;\n\t}\n}\n"]}
@@ -1,17 +1,22 @@
1
1
  import { hydrateCapturedHistoryEntry, } from "./session-history-index.js";
2
2
  import { projectTaskStateSource } from "./task-state.js";
3
- import { TaskStateReducer } from "./task-state-reducer.js";
3
+ import { TaskStateReducer, taskStateReadLimits, } from "./task-state-reducer.js";
4
4
  /** Consume this complete-or-refuse view inside its existing captured-history callback. */
5
- export async function readTaskStateFromHistory(history, limits = {}) {
6
- const reducer = new TaskStateReducer(limits);
5
+ export function readTaskStateFromHistory(history, limits = {}) {
6
+ return reduceHistory(history, { reducer: new TaskStateReducer(limits), sourceBytes: 0 });
7
+ }
8
+ async function reduceHistory(history, state, firstPage) {
9
+ const { reducer } = state;
7
10
  let after = null;
8
11
  let coverage = "complete";
9
- let sourceBytes = 0;
12
+ let sourceBytes = state.sourceBytes;
10
13
  let sourceSequence = -1;
11
14
  let projected;
12
15
  let projectedOrdinal = -1;
13
16
  for (;;) {
14
- const page = await history.branchContext.taskEvidence({ after, limit: 64 });
17
+ const page = firstPage ?? (await history.branchContext.taskEvidence({ after, limit: 64 }));
18
+ firstPage = undefined;
19
+ state.identity = page.sourceIdentity;
15
20
  if (page.indexedThrough < history.source.sourceSequence)
16
21
  throw new Error("Task-state source index coverage is incomplete");
17
22
  if (page.coverage === "partial")
@@ -59,16 +64,18 @@ export async function readTaskStateFromHistory(history, limits = {}) {
59
64
  break;
60
65
  after = page.nextAfter;
61
66
  }
62
- return reducer.finish({
67
+ state.sourceBytes = sourceBytes;
68
+ state.view = reducer.finish({
63
69
  source: { ...history.source },
64
70
  coverage,
65
71
  structuredOnly: true,
66
72
  selective: true,
67
73
  });
74
+ return state.view;
68
75
  }
69
76
  /** Adapt the existing branch-only inference view; never recapture through its Manager. */
70
- export function readTaskStateFromView(view, limits = {}) {
71
- return readTaskStateFromHistory({
77
+ function taskHistory(view) {
78
+ return {
72
79
  source: view.source,
73
80
  branchContext: view,
74
81
  hydrateEntry: async (id, maxSourceBytes) => {
@@ -77,6 +84,65 @@ export function readTaskStateFromView(view, limits = {}) {
77
84
  ? hydrateCapturedHistoryEntry(source, maxSourceBytes, (entryId, options) => view.readPayload(entryId, options))
78
85
  : undefined;
79
86
  },
80
- }, limits);
87
+ };
88
+ }
89
+ export function readTaskStateFromView(view, limits = {}) {
90
+ return readTaskStateFromHistory(taskHistory(view), limits);
91
+ }
92
+ /** Compiler-owned derived state only. Returned views are internal and must not be mutated. */
93
+ export class TaskStateReadCache {
94
+ state;
95
+ generation = 0;
96
+ clear() {
97
+ this.generation++;
98
+ this.state = undefined;
99
+ }
100
+ async read(view, supplied = {}) {
101
+ const limits = taskStateReadLimits(supplied);
102
+ const cached = this.state;
103
+ const generation = ++this.generation;
104
+ // A failed or overlapping read cannot publish a partially mutated reducer.
105
+ this.state = undefined;
106
+ const previous = cached?.view?.source;
107
+ let compatible = Boolean(cached?.identity &&
108
+ previous &&
109
+ previous.sessionId === view.source.sessionId &&
110
+ previous.sessionFile === view.source.sessionFile &&
111
+ previous.persistent === view.source.persistent &&
112
+ previous.sourceSequence <= view.source.sourceSequence &&
113
+ Object.entries(limits).every(([key, value]) => cached.reducer.limits[key] === value));
114
+ if (compatible && previous.leafId !== view.source.leafId) {
115
+ const oldLeaf = previous.leafId === null ? undefined : await view.get(previous.leafId);
116
+ const newLeaf = view.source.leafId === null ? undefined : await view.get(view.source.leafId);
117
+ // Moving to a pre-existing descendant is branch navigation, not an append.
118
+ compatible = Boolean(oldLeaf && newLeaf && newLeaf.sequence > previous.sourceSequence);
119
+ }
120
+ let state = compatible ? cached : { reducer: new TaskStateReducer(limits), sourceBytes: 0 };
121
+ let page = await view.taskEvidence({
122
+ after: compatible ? { sequence: previous.sourceSequence, ordinal: Number.MAX_SAFE_INTEGER } : null,
123
+ limit: 64,
124
+ });
125
+ if (compatible &&
126
+ (!page.sourceIdentity ||
127
+ page.sourceIdentity.journalPath !== cached.identity.journalPath ||
128
+ page.sourceIdentity.dev !== cached.identity.dev ||
129
+ page.sourceIdentity.ino !== cached.identity.ino)) {
130
+ state = { reducer: new TaskStateReducer(limits), sourceBytes: 0 };
131
+ compatible = false;
132
+ page = await view.taskEvidence({ after: null, limit: 64 });
133
+ }
134
+ if (page.indexedThrough < view.source.sourceSequence)
135
+ throw new Error("Task-state source index coverage is incomplete");
136
+ const unchanged = compatible &&
137
+ previous.sourceSequence === view.source.sourceSequence &&
138
+ previous.leafId === view.source.leafId &&
139
+ page.entries.length === 0 &&
140
+ !page.nextAfter &&
141
+ page.coverage === state.view.coverage;
142
+ const result = unchanged ? state.view : await reduceHistory(taskHistory(view), state, page);
143
+ if (generation === this.generation)
144
+ this.state = state;
145
+ return result;
146
+ }
81
147
  }
82
148
  //# sourceMappingURL=task-state-reader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"task-state-reader.js","sourceRoot":"","sources":["../../src/core/task-state-reader.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TaskEvidenceCursor } from \"./history-index.js\";\nimport type { SourceSnapshotRef } from \"./request-events.js\";\nimport {\n\thydrateCapturedHistoryEntry,\n\ttype SessionHistoryReadScope,\n\ttype SessionHistoryReadView,\n} from \"./session-history-index.js\";\nimport { projectTaskStateSource, type TaskStateProjection } from \"./task-state.js\";\nimport { type ReducedTaskItem, type TaskStateReadLimits, TaskStateReducer } from \"./task-state-reducer.js\";\n\nexport interface TaskStateView {\n\tsource: SourceSnapshotRef;\n\tcoverage: \"complete\" | \"partial\";\n\t/** Complete structured branch reduction, not exhaustive semantic requirement extraction. */\n\tstructuredOnly: true;\n\tselective: true;\n\titems: ReducedTaskItem[];\n}\n\n/** Consume this complete-or-refuse view inside its existing captured-history callback. */\nexport async function readTaskStateFromHistory(\n\thistory: Pick<SessionHistoryReadScope, \"source\" | \"branchContext\" | \"hydrateEntry\">,\n\tlimits: Partial<TaskStateReadLimits> = {},\n): Promise<TaskStateView> {\n\tconst reducer = new TaskStateReducer(limits);\n\tlet after: TaskEvidenceCursor | null = null;\n\tlet coverage: TaskStateView[\"coverage\"] = \"complete\";\n\tlet sourceBytes = 0;\n\tlet sourceSequence = -1;\n\tlet projected: Generator<TaskStateProjection> | undefined;\n\tlet projectedOrdinal = -1;\n\tfor (;;) {\n\t\tconst page = await history.branchContext.taskEvidence({ after, limit: 64 });\n\t\tif (page.indexedThrough < history.source.sourceSequence)\n\t\t\tthrow new Error(\"Task-state source index coverage is incomplete\");\n\t\tif (page.coverage === \"partial\") coverage = \"partial\";\n\t\tfor (const row of page.entries) {\n\t\t\tconst source = row.truncated ? row.source : row.projection.source;\n\t\t\tif (row.sequence !== sourceSequence) {\n\t\t\t\tprojected = undefined;\n\t\t\t\tprojectedOrdinal = -1;\n\t\t\t\tif (!source.locator) throw new Error(\"Task-state source locator is unavailable\");\n\t\t\t\tsourceBytes += source.locator.length;\n\t\t\t\tif (sourceBytes > reducer.limits.maxSourceBytes) throw new Error(\"Task-state source byte budget exceeded\");\n\t\t\t\tsourceSequence = row.sequence;\n\t\t\t}\n\t\t\tif (!row.truncated) {\n\t\t\t\treducer.add(row.projection);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!projected) {\n\t\t\t\tconst hydrated = await history.hydrateEntry(source.entryId, source.locator!.length);\n\t\t\t\tif (!hydrated) throw new Error(\"Task-state source is unavailable\");\n\t\t\t\tprojected = projectTaskStateSource({\n\t\t\t\t\t...hydrated.source,\n\t\t\t\t\tsessionId: history.source.sessionId,\n\t\t\t\t\tentry: hydrated.entry,\n\t\t\t\t});\n\t\t\t}\n\t\t\tlet projection: TaskStateProjection | undefined;\n\t\t\twhile (projectedOrdinal < row.ordinal) {\n\t\t\t\tif (++projectedOrdinal >= reducer.limits.maxItems) throw new Error(\"Task-state item budget exceeded\");\n\t\t\t\tconst next = projected.next();\n\t\t\t\tif (next.done) throw new Error(\"Task-state projection source is unavailable\");\n\t\t\t\tprojection = next.value;\n\t\t\t}\n\t\t\tif (!projection || projection.source.field !== source.field)\n\t\t\t\tthrow new Error(\"Task-state projection source does not match its indexed reference\");\n\t\t\treducer.add(projection);\n\t\t}\n\t\tif (!page.nextAfter) break;\n\t\tafter = page.nextAfter;\n\t}\n\treturn reducer.finish({\n\t\tsource: { ...history.source },\n\t\tcoverage,\n\t\tstructuredOnly: true as const,\n\t\tselective: true as const,\n\t});\n}\n\n/** Adapt the existing branch-only inference view; never recapture through its Manager. */\nexport function readTaskStateFromView(\n\tview: SessionHistoryReadView,\n\tlimits: Partial<TaskStateReadLimits> = {},\n): Promise<TaskStateView> {\n\treturn readTaskStateFromHistory(\n\t\t{\n\t\t\tsource: view.source,\n\t\t\tbranchContext: view,\n\t\t\thydrateEntry: async (id, maxSourceBytes) => {\n\t\t\t\tconst source = await view.get(id);\n\t\t\t\treturn source\n\t\t\t\t\t? hydrateCapturedHistoryEntry(source, maxSourceBytes, (entryId, options) =>\n\t\t\t\t\t\t\tview.readPayload(entryId, options),\n\t\t\t\t\t\t)\n\t\t\t\t\t: undefined;\n\t\t\t},\n\t\t},\n\t\tlimits,\n\t);\n}\n"]}
1
+ {"version":3,"file":"task-state-reader.js","sourceRoot":"","sources":["../../src/core/task-state-reader.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TaskEvidenceCursor, TaskEvidencePage } from \"./history-index.js\";\nimport type { SourceSnapshotRef } from \"./request-events.js\";\nimport {\n\thydrateCapturedHistoryEntry,\n\ttype SessionHistoryReadScope,\n\ttype SessionHistoryReadView,\n} from \"./session-history-index.js\";\nimport { projectTaskStateSource, type TaskStateProjection } from \"./task-state.js\";\nimport {\n\ttype ReducedTaskItem,\n\ttype TaskStateReadLimits,\n\tTaskStateReducer,\n\ttaskStateReadLimits,\n} from \"./task-state-reducer.js\";\n\nexport interface TaskStateView {\n\tsource: SourceSnapshotRef;\n\tcoverage: \"complete\" | \"partial\";\n\t/** Complete structured branch reduction, not exhaustive semantic requirement extraction. */\n\tstructuredOnly: true;\n\tselective: true;\n\titems: ReducedTaskItem[];\n}\n\ntype TaskHistory = Pick<SessionHistoryReadScope, \"source\" | \"branchContext\" | \"hydrateEntry\">;\ninterface Reduction {\n\treducer: TaskStateReducer;\n\tsourceBytes: number;\n\tidentity?: TaskEvidencePage[\"sourceIdentity\"];\n\tview?: TaskStateView;\n}\n\n/** Consume this complete-or-refuse view inside its existing captured-history callback. */\nexport function readTaskStateFromHistory(\n\thistory: TaskHistory,\n\tlimits: Partial<TaskStateReadLimits> = {},\n): Promise<TaskStateView> {\n\treturn reduceHistory(history, { reducer: new TaskStateReducer(limits), sourceBytes: 0 });\n}\n\nasync function reduceHistory(\n\thistory: TaskHistory,\n\tstate: Reduction,\n\tfirstPage?: TaskEvidencePage,\n): Promise<TaskStateView> {\n\tconst { reducer } = state;\n\tlet after: TaskEvidenceCursor | null = null;\n\tlet coverage: TaskStateView[\"coverage\"] = \"complete\";\n\tlet sourceBytes = state.sourceBytes;\n\tlet sourceSequence = -1;\n\tlet projected: Generator<TaskStateProjection> | undefined;\n\tlet projectedOrdinal = -1;\n\tfor (;;) {\n\t\tconst page: TaskEvidencePage = firstPage ?? (await history.branchContext.taskEvidence({ after, limit: 64 }));\n\t\tfirstPage = undefined;\n\t\tstate.identity = page.sourceIdentity;\n\t\tif (page.indexedThrough < history.source.sourceSequence)\n\t\t\tthrow new Error(\"Task-state source index coverage is incomplete\");\n\t\tif (page.coverage === \"partial\") coverage = \"partial\";\n\t\tfor (const row of page.entries) {\n\t\t\tconst source = row.truncated ? row.source : row.projection.source;\n\t\t\tif (row.sequence !== sourceSequence) {\n\t\t\t\tprojected = undefined;\n\t\t\t\tprojectedOrdinal = -1;\n\t\t\t\tif (!source.locator) throw new Error(\"Task-state source locator is unavailable\");\n\t\t\t\tsourceBytes += source.locator.length;\n\t\t\t\tif (sourceBytes > reducer.limits.maxSourceBytes) throw new Error(\"Task-state source byte budget exceeded\");\n\t\t\t\tsourceSequence = row.sequence;\n\t\t\t}\n\t\t\tif (!row.truncated) {\n\t\t\t\treducer.add(row.projection);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!projected) {\n\t\t\t\tconst hydrated = await history.hydrateEntry(source.entryId, source.locator!.length);\n\t\t\t\tif (!hydrated) throw new Error(\"Task-state source is unavailable\");\n\t\t\t\tprojected = projectTaskStateSource({\n\t\t\t\t\t...hydrated.source,\n\t\t\t\t\tsessionId: history.source.sessionId,\n\t\t\t\t\tentry: hydrated.entry,\n\t\t\t\t});\n\t\t\t}\n\t\t\tlet projection: TaskStateProjection | undefined;\n\t\t\twhile (projectedOrdinal < row.ordinal) {\n\t\t\t\tif (++projectedOrdinal >= reducer.limits.maxItems) throw new Error(\"Task-state item budget exceeded\");\n\t\t\t\tconst next = projected.next();\n\t\t\t\tif (next.done) throw new Error(\"Task-state projection source is unavailable\");\n\t\t\t\tprojection = next.value;\n\t\t\t}\n\t\t\tif (!projection || projection.source.field !== source.field)\n\t\t\t\tthrow new Error(\"Task-state projection source does not match its indexed reference\");\n\t\t\treducer.add(projection);\n\t\t}\n\t\tif (!page.nextAfter) break;\n\t\tafter = page.nextAfter;\n\t}\n\tstate.sourceBytes = sourceBytes;\n\tstate.view = reducer.finish({\n\t\tsource: { ...history.source },\n\t\tcoverage,\n\t\tstructuredOnly: true as const,\n\t\tselective: true as const,\n\t});\n\treturn state.view;\n}\n\n/** Adapt the existing branch-only inference view; never recapture through its Manager. */\nfunction taskHistory(view: SessionHistoryReadView): TaskHistory {\n\treturn {\n\t\tsource: view.source,\n\t\tbranchContext: view,\n\t\thydrateEntry: async (id, maxSourceBytes) => {\n\t\t\tconst source = await view.get(id);\n\t\t\treturn source\n\t\t\t\t? hydrateCapturedHistoryEntry(source, maxSourceBytes, (entryId, options) =>\n\t\t\t\t\t\tview.readPayload(entryId, options),\n\t\t\t\t\t)\n\t\t\t\t: undefined;\n\t\t},\n\t};\n}\n\nexport function readTaskStateFromView(\n\tview: SessionHistoryReadView,\n\tlimits: Partial<TaskStateReadLimits> = {},\n): Promise<TaskStateView> {\n\treturn readTaskStateFromHistory(taskHistory(view), limits);\n}\n\n/** Compiler-owned derived state only. Returned views are internal and must not be mutated. */\nexport class TaskStateReadCache {\n\tprivate state?: Reduction;\n\tprivate generation = 0;\n\n\tclear(): void {\n\t\tthis.generation++;\n\t\tthis.state = undefined;\n\t}\n\n\tasync read(view: SessionHistoryReadView, supplied: Partial<TaskStateReadLimits> = {}): Promise<TaskStateView> {\n\t\tconst limits = taskStateReadLimits(supplied);\n\t\tconst cached = this.state;\n\t\tconst generation = ++this.generation;\n\t\t// A failed or overlapping read cannot publish a partially mutated reducer.\n\t\tthis.state = undefined;\n\t\tconst previous = cached?.view?.source;\n\t\tlet compatible = Boolean(\n\t\t\tcached?.identity &&\n\t\t\t\tprevious &&\n\t\t\t\tprevious.sessionId === view.source.sessionId &&\n\t\t\t\tprevious.sessionFile === view.source.sessionFile &&\n\t\t\t\tprevious.persistent === view.source.persistent &&\n\t\t\t\tprevious.sourceSequence <= view.source.sourceSequence &&\n\t\t\t\tObject.entries(limits).every(\n\t\t\t\t\t([key, value]) => cached!.reducer.limits[key as keyof TaskStateReadLimits] === value,\n\t\t\t\t),\n\t\t);\n\t\tif (compatible && previous!.leafId !== view.source.leafId) {\n\t\t\tconst oldLeaf = previous!.leafId === null ? undefined : await view.get(previous!.leafId);\n\t\t\tconst newLeaf = view.source.leafId === null ? undefined : await view.get(view.source.leafId);\n\t\t\t// Moving to a pre-existing descendant is branch navigation, not an append.\n\t\t\tcompatible = Boolean(oldLeaf && newLeaf && newLeaf.sequence > previous!.sourceSequence);\n\t\t}\n\t\tlet state: Reduction = compatible ? cached! : { reducer: new TaskStateReducer(limits), sourceBytes: 0 };\n\t\tlet page = await view.taskEvidence({\n\t\t\tafter: compatible ? { sequence: previous!.sourceSequence, ordinal: Number.MAX_SAFE_INTEGER } : null,\n\t\t\tlimit: 64,\n\t\t});\n\t\tif (\n\t\t\tcompatible &&\n\t\t\t(!page.sourceIdentity ||\n\t\t\t\tpage.sourceIdentity.journalPath !== cached!.identity!.journalPath ||\n\t\t\t\tpage.sourceIdentity.dev !== cached!.identity!.dev ||\n\t\t\t\tpage.sourceIdentity.ino !== cached!.identity!.ino)\n\t\t) {\n\t\t\tstate = { reducer: new TaskStateReducer(limits), sourceBytes: 0 };\n\t\t\tcompatible = false;\n\t\t\tpage = await view.taskEvidence({ after: null, limit: 64 });\n\t\t}\n\t\tif (page.indexedThrough < view.source.sourceSequence)\n\t\t\tthrow new Error(\"Task-state source index coverage is incomplete\");\n\t\tconst unchanged =\n\t\t\tcompatible &&\n\t\t\tprevious!.sourceSequence === view.source.sourceSequence &&\n\t\t\tprevious!.leafId === view.source.leafId &&\n\t\t\tpage.entries.length === 0 &&\n\t\t\t!page.nextAfter &&\n\t\t\tpage.coverage === state.view!.coverage;\n\t\tconst result = unchanged ? state.view! : await reduceHistory(taskHistory(view), state, page);\n\t\tif (generation === this.generation) this.state = state;\n\t\treturn result;\n\t}\n}\n"]}
@@ -5,6 +5,7 @@ import type { ToolDefinition } from "../extensions/types.js";
5
5
  import type { KernelBootstrapProgressHandler } from "../kernel/bootstrap.js";
6
6
  import { type CapturedKernelLifecycle, type ExecuteOptions, type HostRequestHandlers, type KernelAttachment, type KernelClient, type KernelDiffDisplay, type KernelSentAgentMessage } from "../kernel/index.js";
7
7
  import { type RestoreResult } from "../kernel/state-snapshot.js";
8
+ import { type RetainedToolOutput } from "../retained-tool-output.js";
8
9
  import { nativeRecoveryMetadata } from "../selective-recovery.js";
9
10
  import type { PythonSkillRuntimeInfo } from "../skills.js";
10
11
  export declare function buildRlmBootstrapCode(pythonSkills?: readonly PythonSkillRuntimeInfo[]): string;
@@ -13,6 +14,8 @@ declare const ipythonSchema: Type.TObject<{
13
14
  }>;
14
15
  export type IpythonToolInput = Static<typeof ipythonSchema>;
15
16
  export interface IpythonToolDetails {
17
+ /** Large finalized channels are excerpts; this descriptor identifies the full captured public text. */
18
+ retainedOutput?: RetainedToolOutput;
16
19
  /** Descriptive selectors only; the exact selected body is in this tool result's content. */
17
20
  nativeRecoveries?: ReturnType<typeof nativeRecoveryMetadata>[];
18
21
  durationMs?: number;
@@ -85,6 +88,8 @@ export declare class IpythonKernelProvisioner {
85
88
  /** Snapshot policy of the dispose that aborted a startup, honored by startKernel's failure teardown. */
86
89
  private disposeSnapshot;
87
90
  constructor(cwd: string, options?: Omit<IpythonToolOptions, "provisioner"> | undefined);
91
+ /** The same persistent owner directory used on cold resume; absent for in-memory sessions. */
92
+ get artifactDir(): string | undefined;
88
93
  /** The kernel manager, once a startup has completed successfully. */
89
94
  get manager(): KernelClient | undefined;
90
95
  captureKernelState(): CapturedKernelLifecycle;