@oyasmi/pipiclaw 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -5
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +156 -57
- package/dist/agent.js.map +1 -1
- package/dist/context.d.ts +18 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +26 -0
- package/dist/context.js.map +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/llm-json.d.ts +7 -0
- package/dist/llm-json.d.ts.map +1 -0
- package/dist/llm-json.js +77 -0
- package/dist/llm-json.js.map +1 -0
- package/dist/markdown-sections.d.ts +6 -0
- package/dist/markdown-sections.d.ts.map +1 -0
- package/dist/markdown-sections.js +34 -0
- package/dist/markdown-sections.js.map +1 -0
- package/dist/memory-candidates.d.ts +21 -0
- package/dist/memory-candidates.d.ts.map +1 -0
- package/dist/memory-candidates.js +126 -0
- package/dist/memory-candidates.js.map +1 -0
- package/dist/memory-consolidation.d.ts.map +1 -1
- package/dist/memory-consolidation.js +28 -49
- package/dist/memory-consolidation.js.map +1 -1
- package/dist/memory-files.d.ts +3 -0
- package/dist/memory-files.d.ts.map +1 -1
- package/dist/memory-files.js +51 -0
- package/dist/memory-files.js.map +1 -1
- package/dist/memory-lifecycle.d.ts +9 -0
- package/dist/memory-lifecycle.d.ts.map +1 -1
- package/dist/memory-lifecycle.js +66 -0
- package/dist/memory-lifecycle.js.map +1 -1
- package/dist/memory-recall.d.ts +29 -0
- package/dist/memory-recall.d.ts.map +1 -0
- package/dist/memory-recall.js +218 -0
- package/dist/memory-recall.js.map +1 -0
- package/dist/prompt-builder.d.ts.map +1 -1
- package/dist/prompt-builder.js +7 -2
- package/dist/prompt-builder.js.map +1 -1
- package/dist/session-memory-files.d.ts +2 -0
- package/dist/session-memory-files.d.ts.map +1 -0
- package/dist/session-memory-files.js +2 -0
- package/dist/session-memory-files.js.map +1 -0
- package/dist/session-memory.d.ts +22 -0
- package/dist/session-memory.d.ts.map +1 -0
- package/dist/session-memory.js +274 -0
- package/dist/session-memory.js.map +1 -0
- package/dist/sidecar-worker.d.ts +27 -0
- package/dist/sidecar-worker.d.ts.map +1 -0
- package/dist/sidecar-worker.js +105 -0
- package/dist/sidecar-worker.js.map +1 -0
- package/dist/sub-agents.d.ts +10 -0
- package/dist/sub-agents.d.ts.map +1 -1
- package/dist/sub-agents.js +90 -0
- package/dist/sub-agents.js.map +1 -1
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/subagent.d.ts +6 -0
- package/dist/tools/subagent.d.ts.map +1 -1
- package/dist/tools/subagent.js +127 -12
- package/dist/tools/subagent.js.map +1 -1
- package/docs/improve-memory/design.md +537 -0
- package/docs/improve-memory/interfaces-and-tests.md +473 -0
- package/docs/improve-memory/spec.md +357 -0
- package/docs/memory-rfc.md +7 -1
- package/docs/proj-review.md +188 -0
- package/docs/test-supplementation-plan.md +553 -0
- package/package.json +3 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subagent.js","sourceRoot":"","sources":["../../src/tools/subagent.ts"],"names":[],"mappings":"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","sourcesContent":["import { Agent, type AgentEvent, type AgentMessage, type AgentTool } from \"@mariozechner/pi-agent-core\";\nimport type { Api, AssistantMessage, Model, TextContent } from \"@mariozechner/pi-ai\";\nimport { convertToLlm } from \"@mariozechner/pi-coding-agent\";\nimport { Type } from \"@sinclair/typebox\";\nimport { formatModelReference } from \"../model-utils.js\";\nimport type { Executor } from \"../sandbox.js\";\nimport {\n\tformatSubAgentList,\n\ttype ResolvedSubAgentConfig,\n\tresolveSubAgentConfig,\n\ttype SubAgentConfig,\n\ttype SubAgentDiscoveryResult,\n\tvalidateSubAgentTask,\n} from \"../sub-agents.js\";\nimport { createBashTool } from \"./bash.js\";\nimport { createEditTool } from \"./edit.js\";\nimport { createReadTool } from \"./read.js\";\nimport { createWriteTool } from \"./write.js\";\n\nconst subagentSchema = Type.Object({\n\tlabel: Type.String({ description: \"Brief description of what this sub-agent task does (shown to user)\" }),\n\tagent: Type.Optional(Type.String({ description: \"Name of a predefined sub-agent from workspaceDir/sub-agents/\" })),\n\tname: Type.Optional(Type.String({ description: \"Optional display name for an inline sub-agent\" })),\n\ttask: Type.String({ description: \"Complete task description for the sub-agent\" }),\n\tsystemPrompt: Type.Optional(\n\t\tType.String({\n\t\t\tdescription: \"Optional inline system prompt for a temporary sub-agent. Use when no predefined agent fits.\",\n\t\t}),\n\t),\n\ttools: Type.Optional(Type.Array(Type.String(), { description: \"Optional tool whitelist for the sub-agent\" })),\n\tmodel: Type.Optional(\n\t\tType.String({ description: \"Optional exact model reference. Defaults to the parent's current model.\" }),\n\t),\n\tmaxTurns: Type.Optional(Type.Number({ description: \"Optional maximum assistant turns for this sub-agent\" })),\n\tmaxToolCalls: Type.Optional(Type.Number({ description: \"Optional maximum tool calls for this sub-agent\" })),\n\tmaxWallTimeSec: Type.Optional(\n\t\tType.Number({ description: \"Optional wall time budget in seconds for this sub-agent\" }),\n\t),\n\tbashTimeoutSec: Type.Optional(\n\t\tType.Number({ description: \"Optional default timeout in seconds for bash commands inside this sub-agent\" }),\n\t),\n});\n\ninterface UsageTotals {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\ttotal: number;\n\tcost: {\n\t\tinput: number;\n\t\toutput: number;\n\t\tcacheRead: number;\n\t\tcacheWrite: number;\n\t\ttotal: number;\n\t};\n}\n\nexport interface SubAgentToolDetails {\n\tkind: \"subagent\";\n\tagent: string;\n\tsource: \"predefined\" | \"inline\";\n\tmodel: string;\n\ttools: string[];\n\tturns: number;\n\ttoolCalls: number;\n\tdurationMs: number;\n\tfailed: boolean;\n\tfailureReason?: string;\n\tusage: UsageTotals;\n}\n\nexport interface SubAgentToolOptions {\n\texecutor: Executor;\n\tgetCurrentModel: () => Model<Api>;\n\tgetAvailableModels: () => Model<Api>[];\n\tresolveApiKey: (model: Model<Api>) => Promise<string>;\n\tworkspaceDir: string;\n\tgetSubAgentDiscovery?: () => SubAgentDiscoveryResult;\n\truntimeContext: {\n\t\tworkspacePath: string;\n\t\tchannelId: string;\n\t\tsandbox: string;\n\t};\n\tcreateWorker?: (config: {\n\t\tsubAgent: ResolvedSubAgentConfig;\n\t\tapiKey: string;\n\t\ttools: AgentTool<any>[];\n\t}) => SubAgentWorker;\n}\n\ninterface SubAgentWorker {\n\tstate: { messages: AgentMessage[] };\n\tsubscribe(listener: (event: AgentEvent) => void): () => void;\n\tabort(): void;\n\tprompt(input: string): Promise<void>;\n\twaitForIdle(): Promise<void>;\n}\n\nfunction createEmptyUsageTotals(): UsageTotals {\n\treturn {\n\t\tinput: 0,\n\t\toutput: 0,\n\t\tcacheRead: 0,\n\t\tcacheWrite: 0,\n\t\ttotal: 0,\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t};\n}\n\nfunction isAssistantMessage(message: AgentMessage): message is AssistantMessage {\n\treturn typeof message === \"object\" && message !== null && \"role\" in message && message.role === \"assistant\";\n}\n\nfunction extractAssistantText(message: AssistantMessage): string {\n\treturn message.content\n\t\t.filter((part): part is Extract<AssistantMessage[\"content\"][number], TextContent> => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\")\n\t\t.trim();\n}\n\nfunction getLastAssistantMessage(messages: AgentMessage[]): AssistantMessage | null {\n\tfor (let i = messages.length - 1; i >= 0; i--) {\n\t\tconst message = messages[i];\n\t\tif (isAssistantMessage(message)) {\n\t\t\treturn message;\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction extractLabelFromArgs(args: unknown): string | null {\n\tif (!args || typeof args !== \"object\" || !(\"label\" in args)) {\n\t\treturn null;\n\t}\n\tconst label = (args as { label?: unknown }).label;\n\treturn typeof label === \"string\" && label.trim() ? label.trim() : null;\n}\n\nfunction formatStatus(agentName: string, text: string): string {\n\treturn `Subagent ${agentName}: ${text}`;\n}\n\nfunction buildFailureText(config: SubAgentConfig, reason: string, lastAssistantText: string): string {\n\tconst trimmedLastText = lastAssistantText.trim();\n\tif (!trimmedLastText) {\n\t\treturn `Sub-agent ${config.name} failed: ${reason}`;\n\t}\n\treturn `Sub-agent ${config.name} failed: ${reason}\\n\\nLast output:\\n${trimmedLastText}`;\n}\n\nfunction buildStoppedText(config: SubAgentConfig, reason: string, finalText: string): string {\n\tconst trimmedFinalText = finalText.trim();\n\tif (!trimmedFinalText) {\n\t\treturn `Sub-agent ${config.name} stopped: ${reason}`;\n\t}\n\treturn `[Sub-agent ${config.name} stopped: ${reason}]\\n\\n${trimmedFinalText}`;\n}\n\nfunction createToolSet(executor: Executor, bashTimeoutSec: number): AgentTool<any>[] {\n\treturn [\n\t\tcreateReadTool(executor),\n\t\tcreateBashTool(executor, { defaultTimeoutSeconds: bashTimeoutSec }),\n\t\tcreateEditTool(executor),\n\t\tcreateWriteTool(executor),\n\t];\n}\n\nfunction buildSubAgentTask(\n\ttask: string,\n\tconfig: ResolvedSubAgentConfig,\n\truntimeContext: SubAgentToolOptions[\"runtimeContext\"],\n): string {\n\tconst taskText = task.trim();\n\treturn `Runtime context:\n- Workspace root: ${runtimeContext.workspacePath}\n- Channel id: ${runtimeContext.channelId}\n- Channel directory: ${runtimeContext.workspacePath}/${runtimeContext.channelId}\n- Sandbox: ${runtimeContext.sandbox}\n- Filesystem isolation: none (files written here are visible to the parent agent)\n- Your configured role: ${config.name}\n\nTask:\n${taskText}`;\n}\n\nfunction filterToolsByName(allTools: AgentTool<any>[], names: string[]): AgentTool<any>[] {\n\tconst allowed = new Set(names);\n\treturn allTools.filter((tool) => allowed.has(tool.name));\n}\n\nfunction createDetails(\n\tconfig: ResolvedSubAgentConfig,\n\tusage: UsageTotals,\n\tturns: number,\n\ttoolCalls: number,\n\tdurationMs: number,\n\tfailed: boolean,\n\tfailureReason?: string,\n): SubAgentToolDetails {\n\treturn {\n\t\tkind: \"subagent\",\n\t\tagent: config.name,\n\t\tsource: config.source,\n\t\tmodel: formatModelReference(config.model),\n\t\ttools: [...config.tools],\n\t\tturns,\n\t\ttoolCalls,\n\t\tdurationMs,\n\t\tfailed,\n\t\tfailureReason,\n\t\tusage: {\n\t\t\t...usage,\n\t\t\tcost: { ...usage.cost },\n\t\t},\n\t};\n}\n\nfunction linkAbortSignals(parentSignal: AbortSignal | undefined, childController: AbortController): () => void {\n\tif (!parentSignal) {\n\t\treturn () => {};\n\t}\n\n\tconst abortChild = () => childController.abort(parentSignal.reason);\n\tif (parentSignal.aborted) {\n\t\tabortChild();\n\t\treturn () => {};\n\t}\n\n\tparentSignal.addEventListener(\"abort\", abortChild, { once: true });\n\treturn () => parentSignal.removeEventListener(\"abort\", abortChild);\n}\n\nexport function createSubAgentTool(\n\toptions: SubAgentToolOptions,\n): AgentTool<typeof subagentSchema, SubAgentToolDetails> {\n\treturn {\n\t\tname: \"subagent\",\n\t\tlabel: \"subagent\",\n\t\tdescription:\n\t\t\t\"Delegate a task to a sub-agent with an isolated context. You may use a predefined sub-agent from workspaceDir/sub-agents/ or define a temporary inline sub-agent by providing systemPrompt/tools/model parameters. Sub-agents never receive the subagent tool, so they cannot create nested agents.\",\n\t\tparameters: subagentSchema,\n\t\texecute: async (_toolCallId, params, signal, onUpdate) => {\n\t\t\tconst availableModels = options.getAvailableModels();\n\t\t\tconst discovery = options.getSubAgentDiscovery?.() ?? {\n\t\t\t\tdirectory: `${options.workspaceDir}/sub-agents`,\n\t\t\t\tagents: [],\n\t\t\t\twarnings: [],\n\t\t\t};\n\t\t\tconst currentModel = options.getCurrentModel();\n\t\t\tconst taskLengthError = validateSubAgentTask(params.task);\n\t\t\tif (taskLengthError) {\n\t\t\t\tthrow new Error(taskLengthError);\n\t\t\t}\n\t\t\tconst invocation = resolveSubAgentConfig(availableModels, currentModel, discovery.agents, params);\n\t\t\tif (!invocation.config) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`${invocation.error}\\n\\nAvailable predefined sub-agents:\\n${formatSubAgentList(discovery.agents)}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst config = invocation.config;\n\t\t\tconst apiKey = await options.resolveApiKey(config.model);\n\t\t\tconst startedAt = Date.now();\n\t\t\tconst usage = createEmptyUsageTotals();\n\t\t\tlet assistantTurns = 0;\n\t\t\tlet toolCalls = 0;\n\t\t\tlet failureReason: string | undefined;\n\t\t\tlet lastUpdateText = \"\";\n\n\t\t\tconst emitUpdate = (text: string) => {\n\t\t\t\tconst nextText = text.trim();\n\t\t\t\tif (!nextText || nextText === lastUpdateText) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlastUpdateText = nextText;\n\t\t\t\tonUpdate?.({\n\t\t\t\t\tcontent: [{ type: \"text\", text: nextText }],\n\t\t\t\t\tdetails: createDetails(\n\t\t\t\t\t\tconfig,\n\t\t\t\t\t\tusage,\n\t\t\t\t\t\tassistantTurns,\n\t\t\t\t\t\ttoolCalls,\n\t\t\t\t\t\tDate.now() - startedAt,\n\t\t\t\t\t\tBoolean(failureReason),\n\t\t\t\t\t\tfailureReason,\n\t\t\t\t\t),\n\t\t\t\t});\n\t\t\t};\n\n\t\t\tconst worker =\n\t\t\t\toptions.createWorker?.({\n\t\t\t\t\tsubAgent: config,\n\t\t\t\t\tapiKey,\n\t\t\t\t\ttools: filterToolsByName(createToolSet(options.executor, config.bashTimeoutSec), config.tools),\n\t\t\t\t}) ??\n\t\t\t\tnew Agent({\n\t\t\t\t\tinitialState: {\n\t\t\t\t\t\tsystemPrompt: config.systemPrompt,\n\t\t\t\t\t\tmodel: config.model,\n\t\t\t\t\t\tthinkingLevel: \"off\",\n\t\t\t\t\t\ttools: filterToolsByName(createToolSet(options.executor, config.bashTimeoutSec), config.tools),\n\t\t\t\t\t},\n\t\t\t\t\tconvertToLlm,\n\t\t\t\t\tgetApiKey: async () => apiKey,\n\t\t\t\t});\n\n\t\t\tconst childController = new AbortController();\n\t\t\tconst unlinkAbortSignals = linkAbortSignals(signal, childController);\n\t\t\tconst wallClockTimer = setTimeout(() => {\n\t\t\t\tfailureReason = `Wall time budget exceeded (${config.maxWallTimeSec}s)`;\n\t\t\t\tworker.abort();\n\t\t\t}, config.maxWallTimeSec * 1000);\n\n\t\t\tconst unsubscribe = worker.subscribe((event: AgentEvent) => {\n\t\t\t\tif (event.type === \"message_end\" && isAssistantMessage(event.message)) {\n\t\t\t\t\tassistantTurns++;\n\t\t\t\t\tconst messageUsage = event.message.usage;\n\t\t\t\t\tusage.input += messageUsage.input;\n\t\t\t\t\tusage.output += messageUsage.output;\n\t\t\t\t\tusage.cacheRead += messageUsage.cacheRead;\n\t\t\t\t\tusage.cacheWrite += messageUsage.cacheWrite;\n\t\t\t\t\tusage.total += messageUsage.totalTokens;\n\t\t\t\t\tusage.cost.input += messageUsage.cost.input;\n\t\t\t\t\tusage.cost.output += messageUsage.cost.output;\n\t\t\t\t\tusage.cost.cacheRead += messageUsage.cost.cacheRead;\n\t\t\t\t\tusage.cost.cacheWrite += messageUsage.cost.cacheWrite;\n\t\t\t\t\tusage.cost.total += messageUsage.cost.total;\n\t\t\t\t}\n\n\t\t\t\tif (event.type === \"tool_execution_start\") {\n\t\t\t\t\ttoolCalls++;\n\t\t\t\t\tconst label = extractLabelFromArgs(event.args) || event.toolName;\n\t\t\t\t\temitUpdate(formatStatus(config.name, label));\n\t\t\t\t\tif (toolCalls > config.maxToolCalls) {\n\t\t\t\t\t\tfailureReason = `Tool call budget exceeded (${config.maxToolCalls})`;\n\t\t\t\t\t\temitUpdate(formatStatus(config.name, \"tool budget reached\"));\n\t\t\t\t\t\tworker.abort();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tevent.type === \"turn_end\" &&\n\t\t\t\t\tisAssistantMessage(event.message) &&\n\t\t\t\t\tevent.toolResults.length > 0 &&\n\t\t\t\t\tassistantTurns >= config.maxTurns\n\t\t\t\t) {\n\t\t\t\t\tfailureReason = `Turn budget exceeded (${config.maxTurns})`;\n\t\t\t\t\temitUpdate(formatStatus(config.name, \"turn budget reached\"));\n\t\t\t\t\tworker.abort();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\temitUpdate(formatStatus(config.name, \"started\"));\n\n\t\t\ttry {\n\t\t\t\tif (childController.signal.aborted) {\n\t\t\t\t\tthrow new Error(\"Sub-agent aborted\");\n\t\t\t\t}\n\n\t\t\t\tconst abortWorker = () => worker.abort();\n\t\t\t\tchildController.signal.addEventListener(\"abort\", abortWorker, { once: true });\n\t\t\t\ttry {\n\t\t\t\t\tawait worker.prompt(buildSubAgentTask(params.task, config, options.runtimeContext));\n\t\t\t\t\tawait worker.waitForIdle();\n\t\t\t\t} finally {\n\t\t\t\t\tchildController.signal.removeEventListener(\"abort\", abortWorker);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tunsubscribe();\n\t\t\t\tunlinkAbortSignals();\n\t\t\t\tclearTimeout(wallClockTimer);\n\t\t\t}\n\n\t\t\tif (signal?.aborted) {\n\t\t\t\tthrow new Error(\"Sub-agent aborted\");\n\t\t\t}\n\n\t\t\tconst lastAssistantMessage = getLastAssistantMessage(worker.state.messages);\n\t\t\tconst durationMs = Date.now() - startedAt;\n\t\t\tif (!lastAssistantMessage) {\n\t\t\t\tfailureReason = failureReason || \"Sub-agent returned no assistant message\";\n\t\t\t\temitUpdate(formatStatus(config.name, \"failed\"));\n\t\t\t\tthrow new Error(`Sub-agent ${config.name} failed: ${failureReason}`);\n\t\t\t}\n\n\t\t\tconst finalText = extractAssistantText(lastAssistantMessage);\n\t\t\tconst effectiveFailureReason =\n\t\t\t\tfailureReason ||\n\t\t\t\t(lastAssistantMessage.stopReason === \"error\" || lastAssistantMessage.stopReason === \"aborted\"\n\t\t\t\t\t? lastAssistantMessage.errorMessage || `Sub-agent stopped with ${lastAssistantMessage.stopReason}`\n\t\t\t\t\t: undefined);\n\n\t\t\tif (effectiveFailureReason) {\n\t\t\t\tif (!finalText.trim()) {\n\t\t\t\t\temitUpdate(formatStatus(config.name, \"failed\"));\n\t\t\t\t\tthrow new Error(buildFailureText(config, effectiveFailureReason, finalText));\n\t\t\t\t}\n\t\t\t\temitUpdate(formatStatus(config.name, \"stopped\"));\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: buildStoppedText(config, effectiveFailureReason, finalText) }],\n\t\t\t\t\tdetails: createDetails(\n\t\t\t\t\t\tconfig,\n\t\t\t\t\t\tusage,\n\t\t\t\t\t\tassistantTurns,\n\t\t\t\t\t\ttoolCalls,\n\t\t\t\t\t\tdurationMs,\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t\teffectiveFailureReason,\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: finalText || `(Sub-agent ${config.name} completed with no text output)` }],\n\t\t\t\tdetails: createDetails(config, usage, assistantTurns, toolCalls, durationMs, false),\n\t\t\t};\n\t\t},\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"subagent.js","sourceRoot":"","sources":["../../src/tools/subagent.ts"],"names":[],"mappings":"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","sourcesContent":["import { Agent, type AgentEvent, type AgentMessage, type AgentTool } from \"@mariozechner/pi-agent-core\";\nimport type { Api, AssistantMessage, Model, TextContent } from \"@mariozechner/pi-ai\";\nimport { convertToLlm } from \"@mariozechner/pi-coding-agent\";\nimport { Type } from \"@sinclair/typebox\";\nimport type { PipiclawMemoryRecallSettings } from \"../context.js\";\nimport { splitLevelOneSections } from \"../markdown-sections.js\";\nimport { createMemoryCandidateCache } from \"../memory-candidates.js\";\nimport { readChannelSession } from \"../memory-files.js\";\nimport { recallRelevantMemory } from \"../memory-recall.js\";\nimport { formatModelReference } from \"../model-utils.js\";\nimport type { Executor } from \"../sandbox.js\";\nimport {\n\tformatSubAgentList,\n\ttype ResolvedSubAgentConfig,\n\tresolveSubAgentConfig,\n\ttype SubAgentConfig,\n\ttype SubAgentDiscoveryResult,\n\tvalidateSubAgentTask,\n} from \"../sub-agents.js\";\nimport { createBashTool } from \"./bash.js\";\nimport { createEditTool } from \"./edit.js\";\nimport { createReadTool } from \"./read.js\";\nimport { createWriteTool } from \"./write.js\";\n\nconst subagentSchema = Type.Object({\n\tlabel: Type.String({ description: \"Brief description of what this sub-agent task does (shown to user)\" }),\n\tagent: Type.Optional(Type.String({ description: \"Name of a predefined sub-agent from workspaceDir/sub-agents/\" })),\n\tname: Type.Optional(Type.String({ description: \"Optional display name for an inline sub-agent\" })),\n\ttask: Type.String({ description: \"Complete task description for the sub-agent\" }),\n\tsystemPrompt: Type.Optional(\n\t\tType.String({\n\t\t\tdescription: \"Optional inline system prompt for a temporary sub-agent. Use when no predefined agent fits.\",\n\t\t}),\n\t),\n\ttools: Type.Optional(Type.Array(Type.String(), { description: \"Optional tool whitelist for the sub-agent\" })),\n\tmodel: Type.Optional(\n\t\tType.String({ description: \"Optional exact model reference. Defaults to the parent's current model.\" }),\n\t),\n\tmaxTurns: Type.Optional(Type.Number({ description: \"Optional maximum assistant turns for this sub-agent\" })),\n\tmaxToolCalls: Type.Optional(Type.Number({ description: \"Optional maximum tool calls for this sub-agent\" })),\n\tmaxWallTimeSec: Type.Optional(\n\t\tType.Number({ description: \"Optional wall time budget in seconds for this sub-agent\" }),\n\t),\n\tbashTimeoutSec: Type.Optional(\n\t\tType.Number({ description: \"Optional default timeout in seconds for bash commands inside this sub-agent\" }),\n\t),\n\tcontextMode: Type.Optional(\n\t\tType.String({\n\t\t\tdescription: 'Optional context mode. Use \"contextual\" to inject selected session and memory context.',\n\t\t}),\n\t),\n\tmemory: Type.Optional(\n\t\tType.String({\n\t\t\tdescription: 'Optional memory mode for contextual sub-agents: \"none\", \"session\", or \"relevant\".',\n\t\t}),\n\t),\n\tpaths: Type.Optional(\n\t\tType.Array(Type.String(), {\n\t\t\tdescription: \"Optional preferred file or directory paths for the sub-agent to focus on.\",\n\t\t}),\n\t),\n});\n\ninterface UsageTotals {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\ttotal: number;\n\tcost: {\n\t\tinput: number;\n\t\toutput: number;\n\t\tcacheRead: number;\n\t\tcacheWrite: number;\n\t\ttotal: number;\n\t};\n}\n\nexport interface SubAgentToolDetails {\n\tkind: \"subagent\";\n\tagent: string;\n\tsource: \"predefined\" | \"inline\";\n\tmodel: string;\n\ttools: string[];\n\tturns: number;\n\ttoolCalls: number;\n\tdurationMs: number;\n\tfailed: boolean;\n\tfailureReason?: string;\n\tusage: UsageTotals;\n}\n\nexport interface SubAgentToolOptions {\n\texecutor: Executor;\n\tgetCurrentModel: () => Model<Api>;\n\tgetAvailableModels: () => Model<Api>[];\n\tresolveApiKey: (model: Model<Api>) => Promise<string>;\n\tworkspaceDir: string;\n\tchannelDir: string;\n\tgetSubAgentDiscovery?: () => SubAgentDiscoveryResult;\n\tgetMemoryRecallSettings?: () => PipiclawMemoryRecallSettings;\n\truntimeContext: {\n\t\tworkspacePath: string;\n\t\tchannelId: string;\n\t\tsandbox: string;\n\t};\n\tcreateWorker?: (config: {\n\t\tsubAgent: ResolvedSubAgentConfig;\n\t\tapiKey: string;\n\t\ttools: AgentTool<any>[];\n\t}) => SubAgentWorker;\n}\n\ninterface SubAgentWorker {\n\tstate: { messages: AgentMessage[] };\n\tsubscribe(listener: (event: AgentEvent) => void): () => void;\n\tabort(): void;\n\tprompt(input: string): Promise<void>;\n\twaitForIdle(): Promise<void>;\n}\n\nconst DEFAULT_SUBAGENT_MEMORY_RECALL_SETTINGS: PipiclawMemoryRecallSettings = {\n\tenabled: true,\n\tmaxCandidates: 8,\n\tmaxInjected: 3,\n\tmaxChars: 3500,\n\trerankWithModel: false,\n};\nconst SESSION_SECTION_ORDER = [\"Current State\", \"User Intent\", \"Active Files\", \"Errors & Corrections\", \"Next Steps\"];\nconst MAX_SESSION_SECTION_CHARS = 280;\nconst MAX_SESSION_CONTEXT_CHARS = 1800;\nconst MAX_RECALL_CONTEXT_CHARS = 2200;\nconst HAN_REGEX = /\\p{Script=Han}/u;\n\nfunction createEmptyUsageTotals(): UsageTotals {\n\treturn {\n\t\tinput: 0,\n\t\toutput: 0,\n\t\tcacheRead: 0,\n\t\tcacheWrite: 0,\n\t\ttotal: 0,\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t};\n}\n\nfunction isAssistantMessage(message: AgentMessage): message is AssistantMessage {\n\treturn typeof message === \"object\" && message !== null && \"role\" in message && message.role === \"assistant\";\n}\n\nfunction extractAssistantText(message: AssistantMessage): string {\n\treturn message.content\n\t\t.filter((part): part is Extract<AssistantMessage[\"content\"][number], TextContent> => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\")\n\t\t.trim();\n}\n\nfunction getLastAssistantMessage(messages: AgentMessage[]): AssistantMessage | null {\n\tfor (let i = messages.length - 1; i >= 0; i--) {\n\t\tconst message = messages[i];\n\t\tif (isAssistantMessage(message)) {\n\t\t\treturn message;\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction extractLabelFromArgs(args: unknown): string | null {\n\tif (!args || typeof args !== \"object\" || !(\"label\" in args)) {\n\t\treturn null;\n\t}\n\tconst label = (args as { label?: unknown }).label;\n\treturn typeof label === \"string\" && label.trim() ? label.trim() : null;\n}\n\nfunction formatStatus(agentName: string, text: string): string {\n\treturn `Subagent ${agentName}: ${text}`;\n}\n\nfunction buildFailureText(config: SubAgentConfig, reason: string, lastAssistantText: string): string {\n\tconst trimmedLastText = lastAssistantText.trim();\n\tif (!trimmedLastText) {\n\t\treturn `Sub-agent ${config.name} failed: ${reason}`;\n\t}\n\treturn `Sub-agent ${config.name} failed: ${reason}\\n\\nLast output:\\n${trimmedLastText}`;\n}\n\nfunction buildStoppedText(config: SubAgentConfig, reason: string, finalText: string): string {\n\tconst trimmedFinalText = finalText.trim();\n\tif (!trimmedFinalText) {\n\t\treturn `Sub-agent ${config.name} stopped: ${reason}`;\n\t}\n\treturn `[Sub-agent ${config.name} stopped: ${reason}]\\n\\n${trimmedFinalText}`;\n}\n\nfunction createToolSet(executor: Executor, bashTimeoutSec: number): AgentTool<any>[] {\n\treturn [\n\t\tcreateReadTool(executor),\n\t\tcreateBashTool(executor, { defaultTimeoutSeconds: bashTimeoutSec }),\n\t\tcreateEditTool(executor),\n\t\tcreateWriteTool(executor),\n\t];\n}\n\nfunction buildSubAgentTask(\n\ttask: string,\n\tconfig: ResolvedSubAgentConfig,\n\truntimeContext: SubAgentToolOptions[\"runtimeContext\"],\n\tcontextBlocks: string[],\n): string {\n\tconst taskText = task.trim();\n\tconst lines = [\n\t\t`Runtime context:`,\n\t\t`- Workspace root: ${runtimeContext.workspacePath}`,\n\t\t`- Channel id: ${runtimeContext.channelId}`,\n\t\t`- Channel directory: ${runtimeContext.workspacePath}/${runtimeContext.channelId}`,\n\t\t`- Sandbox: ${runtimeContext.sandbox}`,\n\t\t`- Filesystem isolation: none (files written here are visible to the parent agent)`,\n\t\t`- Your configured role: ${config.name}`,\n\t];\n\n\tfor (const block of contextBlocks) {\n\t\tif (!block.trim()) {\n\t\t\tcontinue;\n\t\t}\n\t\tlines.push(\"\", block.trim());\n\t}\n\n\tlines.push(\"\", `Task:`, taskText);\n\treturn lines.join(\"\\n\");\n}\n\nfunction clipText(text: string, maxChars: number): string {\n\tconst normalized = text.replace(/\\s+\\n/g, \"\\n\").trim();\n\tif (normalized.length <= maxChars) {\n\t\treturn normalized;\n\t}\n\treturn `${normalized.slice(0, Math.max(0, maxChars - 3)).trimEnd()}...`;\n}\n\nfunction buildSessionContextBlock(sessionMarkdown: string): string {\n\tconst sections = splitLevelOneSections(sessionMarkdown);\n\tif (sections.length === 0) {\n\t\treturn \"\";\n\t}\n\n\tconst selectedSections = SESSION_SECTION_ORDER.flatMap((heading) =>\n\t\tsections.filter((section) => section.heading.toLowerCase() === heading.toLowerCase()),\n\t);\n\n\tif (selectedSections.length === 0) {\n\t\treturn \"\";\n\t}\n\n\tconst lines = [\"Relevant session state:\"];\n\tlet usedChars = lines[0].length;\n\tfor (const section of selectedSections) {\n\t\tconst clipped = clipText(section.content, MAX_SESSION_SECTION_CHARS);\n\t\tconst block = `- ${section.heading}: ${clipped}`;\n\t\tif (usedChars + block.length > MAX_SESSION_CONTEXT_CHARS) {\n\t\t\tbreak;\n\t\t}\n\t\tlines.push(block);\n\t\tusedChars += block.length + 1;\n\t}\n\treturn lines.length > 1 ? lines.join(\"\\n\") : \"\";\n}\n\nfunction stripRuntimeContextWrapper(renderedText: string): string {\n\treturn renderedText\n\t\t.replace(/^<runtime_context>\\s*/i, \"\")\n\t\t.replace(/\\s*<\\/runtime_context>$/i, \"\")\n\t\t.trim();\n}\n\nasync function buildContextualBlocks(\n\ttask: string,\n\tconfig: ResolvedSubAgentConfig,\n\toptions: SubAgentToolOptions,\n\tcurrentModel: Model<Api>,\n\tcandidateCache = createMemoryCandidateCache(),\n): Promise<string[]> {\n\tif (config.contextMode !== \"contextual\") {\n\t\treturn [];\n\t}\n\n\tconst blocks: string[] = [];\n\tif (config.paths.length > 0) {\n\t\tblocks.push(`Preferred focus paths:\\n${config.paths.map((path) => `- ${path}`).join(\"\\n\")}`);\n\t}\n\n\tif (config.memory === \"none\") {\n\t\treturn blocks;\n\t}\n\n\tconst sessionMarkdown = await readChannelSession(options.channelDir);\n\tconst sessionBlock = buildSessionContextBlock(sessionMarkdown);\n\tif (sessionBlock) {\n\t\tblocks.push(sessionBlock);\n\t}\n\n\tif (config.memory !== \"relevant\") {\n\t\treturn blocks;\n\t}\n\n\tconst recallSettings = {\n\t\t...DEFAULT_SUBAGENT_MEMORY_RECALL_SETTINGS,\n\t\t...options.getMemoryRecallSettings?.(),\n\t};\n\tif (!recallSettings.enabled) {\n\t\treturn blocks;\n\t}\n\n\tconst recallQuery = [task.trim(), config.description.trim(), ...config.paths].filter(Boolean).join(\"\\n\");\n\tconst recalled = await recallRelevantMemory({\n\t\tquery: recallQuery,\n\t\tworkspaceDir: options.workspaceDir,\n\t\tchannelDir: options.channelDir,\n\t\tmaxCandidates: recallSettings.maxCandidates,\n\t\tmaxInjected: recallSettings.maxInjected,\n\t\tmaxChars: Math.min(recallSettings.maxChars, MAX_RECALL_CONTEXT_CHARS),\n\t\trerankWithModel: recallSettings.rerankWithModel,\n\t\tautoRerank: HAN_REGEX.test(recallQuery),\n\t\tmodel: currentModel,\n\t\tresolveApiKey: options.resolveApiKey,\n\t\tallowedSources: [\"workspace-memory\", \"channel-memory\", \"channel-history\"],\n\t\tcandidateCache,\n\t});\n\tconst recalledText = stripRuntimeContextWrapper(recalled.renderedText);\n\tif (recalledText) {\n\t\tblocks.push(recalledText);\n\t}\n\n\treturn blocks;\n}\n\nfunction filterToolsByName(allTools: AgentTool<any>[], names: string[]): AgentTool<any>[] {\n\tconst allowed = new Set(names);\n\treturn allTools.filter((tool) => allowed.has(tool.name));\n}\n\nfunction createDetails(\n\tconfig: ResolvedSubAgentConfig,\n\tusage: UsageTotals,\n\tturns: number,\n\ttoolCalls: number,\n\tdurationMs: number,\n\tfailed: boolean,\n\tfailureReason?: string,\n): SubAgentToolDetails {\n\treturn {\n\t\tkind: \"subagent\",\n\t\tagent: config.name,\n\t\tsource: config.source,\n\t\tmodel: formatModelReference(config.model),\n\t\ttools: [...config.tools],\n\t\tturns,\n\t\ttoolCalls,\n\t\tdurationMs,\n\t\tfailed,\n\t\tfailureReason,\n\t\tusage: {\n\t\t\t...usage,\n\t\t\tcost: { ...usage.cost },\n\t\t},\n\t};\n}\n\nfunction linkAbortSignals(parentSignal: AbortSignal | undefined, childController: AbortController): () => void {\n\tif (!parentSignal) {\n\t\treturn () => {};\n\t}\n\n\tconst abortChild = () => childController.abort(parentSignal.reason);\n\tif (parentSignal.aborted) {\n\t\tabortChild();\n\t\treturn () => {};\n\t}\n\n\tparentSignal.addEventListener(\"abort\", abortChild, { once: true });\n\treturn () => parentSignal.removeEventListener(\"abort\", abortChild);\n}\n\nexport function createSubAgentTool(\n\toptions: SubAgentToolOptions,\n): AgentTool<typeof subagentSchema, SubAgentToolDetails> {\n\treturn {\n\t\tname: \"subagent\",\n\t\tlabel: \"subagent\",\n\t\tdescription:\n\t\t\t\"Delegate a task to a sub-agent with an isolated context. You may use a predefined sub-agent from workspaceDir/sub-agents/ or define a temporary inline sub-agent by providing systemPrompt/tools/model parameters. Sub-agents never receive the subagent tool, so they cannot create nested agents.\",\n\t\tparameters: subagentSchema,\n\t\texecute: async (_toolCallId, params, signal, onUpdate) => {\n\t\t\tconst availableModels = options.getAvailableModels();\n\t\t\tconst discovery = options.getSubAgentDiscovery?.() ?? {\n\t\t\t\tdirectory: `${options.workspaceDir}/sub-agents`,\n\t\t\t\tagents: [],\n\t\t\t\twarnings: [],\n\t\t\t};\n\t\t\tconst currentModel = options.getCurrentModel();\n\t\t\tconst taskLengthError = validateSubAgentTask(params.task);\n\t\t\tif (taskLengthError) {\n\t\t\t\tthrow new Error(taskLengthError);\n\t\t\t}\n\t\t\tconst invocation = resolveSubAgentConfig(availableModels, currentModel, discovery.agents, params);\n\t\t\tif (!invocation.config) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`${invocation.error}\\n\\nAvailable predefined sub-agents:\\n${formatSubAgentList(discovery.agents)}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst config = invocation.config;\n\t\t\tconst apiKey = await options.resolveApiKey(config.model);\n\t\t\tconst startedAt = Date.now();\n\t\t\tconst usage = createEmptyUsageTotals();\n\t\t\tlet assistantTurns = 0;\n\t\t\tlet toolCalls = 0;\n\t\t\tlet failureReason: string | undefined;\n\t\t\tlet lastUpdateText = \"\";\n\n\t\t\tconst emitUpdate = (text: string) => {\n\t\t\t\tconst nextText = text.trim();\n\t\t\t\tif (!nextText || nextText === lastUpdateText) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlastUpdateText = nextText;\n\t\t\t\tonUpdate?.({\n\t\t\t\t\tcontent: [{ type: \"text\", text: nextText }],\n\t\t\t\t\tdetails: createDetails(\n\t\t\t\t\t\tconfig,\n\t\t\t\t\t\tusage,\n\t\t\t\t\t\tassistantTurns,\n\t\t\t\t\t\ttoolCalls,\n\t\t\t\t\t\tDate.now() - startedAt,\n\t\t\t\t\t\tBoolean(failureReason),\n\t\t\t\t\t\tfailureReason,\n\t\t\t\t\t),\n\t\t\t\t});\n\t\t\t};\n\n\t\t\tconst worker =\n\t\t\t\toptions.createWorker?.({\n\t\t\t\t\tsubAgent: config,\n\t\t\t\t\tapiKey,\n\t\t\t\t\ttools: filterToolsByName(createToolSet(options.executor, config.bashTimeoutSec), config.tools),\n\t\t\t\t}) ??\n\t\t\t\tnew Agent({\n\t\t\t\t\tinitialState: {\n\t\t\t\t\t\tsystemPrompt: config.systemPrompt,\n\t\t\t\t\t\tmodel: config.model,\n\t\t\t\t\t\tthinkingLevel: \"off\",\n\t\t\t\t\t\ttools: filterToolsByName(createToolSet(options.executor, config.bashTimeoutSec), config.tools),\n\t\t\t\t\t},\n\t\t\t\t\tconvertToLlm,\n\t\t\t\t\tgetApiKey: async () => apiKey,\n\t\t\t\t});\n\n\t\t\tconst childController = new AbortController();\n\t\t\tconst unlinkAbortSignals = linkAbortSignals(signal, childController);\n\t\t\tconst wallClockTimer = setTimeout(() => {\n\t\t\t\tfailureReason = `Wall time budget exceeded (${config.maxWallTimeSec}s)`;\n\t\t\t\tworker.abort();\n\t\t\t}, config.maxWallTimeSec * 1000);\n\n\t\t\tconst unsubscribe = worker.subscribe((event: AgentEvent) => {\n\t\t\t\tif (event.type === \"message_end\" && isAssistantMessage(event.message)) {\n\t\t\t\t\tassistantTurns++;\n\t\t\t\t\tconst messageUsage = event.message.usage;\n\t\t\t\t\tusage.input += messageUsage.input;\n\t\t\t\t\tusage.output += messageUsage.output;\n\t\t\t\t\tusage.cacheRead += messageUsage.cacheRead;\n\t\t\t\t\tusage.cacheWrite += messageUsage.cacheWrite;\n\t\t\t\t\tusage.total += messageUsage.totalTokens;\n\t\t\t\t\tusage.cost.input += messageUsage.cost.input;\n\t\t\t\t\tusage.cost.output += messageUsage.cost.output;\n\t\t\t\t\tusage.cost.cacheRead += messageUsage.cost.cacheRead;\n\t\t\t\t\tusage.cost.cacheWrite += messageUsage.cost.cacheWrite;\n\t\t\t\t\tusage.cost.total += messageUsage.cost.total;\n\t\t\t\t}\n\n\t\t\t\tif (event.type === \"tool_execution_start\") {\n\t\t\t\t\ttoolCalls++;\n\t\t\t\t\tconst label = extractLabelFromArgs(event.args) || event.toolName;\n\t\t\t\t\temitUpdate(formatStatus(config.name, label));\n\t\t\t\t\tif (toolCalls > config.maxToolCalls) {\n\t\t\t\t\t\tfailureReason = `Tool call budget exceeded (${config.maxToolCalls})`;\n\t\t\t\t\t\temitUpdate(formatStatus(config.name, \"tool budget reached\"));\n\t\t\t\t\t\tworker.abort();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tevent.type === \"turn_end\" &&\n\t\t\t\t\tisAssistantMessage(event.message) &&\n\t\t\t\t\tevent.toolResults.length > 0 &&\n\t\t\t\t\tassistantTurns >= config.maxTurns\n\t\t\t\t) {\n\t\t\t\t\tfailureReason = `Turn budget exceeded (${config.maxTurns})`;\n\t\t\t\t\temitUpdate(formatStatus(config.name, \"turn budget reached\"));\n\t\t\t\t\tworker.abort();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\temitUpdate(formatStatus(config.name, \"started\"));\n\n\t\t\ttry {\n\t\t\t\tif (childController.signal.aborted) {\n\t\t\t\t\tthrow new Error(\"Sub-agent aborted\");\n\t\t\t\t}\n\n\t\t\t\tconst abortWorker = () => worker.abort();\n\t\t\t\tchildController.signal.addEventListener(\"abort\", abortWorker, { once: true });\n\t\t\t\ttry {\n\t\t\t\t\tconst contextualBlocks = await buildContextualBlocks(params.task, config, options, currentModel);\n\t\t\t\t\tawait worker.prompt(buildSubAgentTask(params.task, config, options.runtimeContext, contextualBlocks));\n\t\t\t\t\tawait worker.waitForIdle();\n\t\t\t\t} finally {\n\t\t\t\t\tchildController.signal.removeEventListener(\"abort\", abortWorker);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tunsubscribe();\n\t\t\t\tunlinkAbortSignals();\n\t\t\t\tclearTimeout(wallClockTimer);\n\t\t\t}\n\n\t\t\tif (signal?.aborted) {\n\t\t\t\tthrow new Error(\"Sub-agent aborted\");\n\t\t\t}\n\n\t\t\tconst lastAssistantMessage = getLastAssistantMessage(worker.state.messages);\n\t\t\tconst durationMs = Date.now() - startedAt;\n\t\t\tif (!lastAssistantMessage) {\n\t\t\t\tfailureReason = failureReason || \"Sub-agent returned no assistant message\";\n\t\t\t\temitUpdate(formatStatus(config.name, \"failed\"));\n\t\t\t\tthrow new Error(`Sub-agent ${config.name} failed: ${failureReason}`);\n\t\t\t}\n\n\t\t\tconst finalText = extractAssistantText(lastAssistantMessage);\n\t\t\tconst effectiveFailureReason =\n\t\t\t\tfailureReason ||\n\t\t\t\t(lastAssistantMessage.stopReason === \"error\" || lastAssistantMessage.stopReason === \"aborted\"\n\t\t\t\t\t? lastAssistantMessage.errorMessage || `Sub-agent stopped with ${lastAssistantMessage.stopReason}`\n\t\t\t\t\t: undefined);\n\n\t\t\tif (effectiveFailureReason) {\n\t\t\t\tif (!finalText.trim()) {\n\t\t\t\t\temitUpdate(formatStatus(config.name, \"failed\"));\n\t\t\t\t\tthrow new Error(buildFailureText(config, effectiveFailureReason, finalText));\n\t\t\t\t}\n\t\t\t\temitUpdate(formatStatus(config.name, \"stopped\"));\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: buildStoppedText(config, effectiveFailureReason, finalText) }],\n\t\t\t\t\tdetails: createDetails(\n\t\t\t\t\t\tconfig,\n\t\t\t\t\t\tusage,\n\t\t\t\t\t\tassistantTurns,\n\t\t\t\t\t\ttoolCalls,\n\t\t\t\t\t\tdurationMs,\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t\teffectiveFailureReason,\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: finalText || `(Sub-agent ${config.name} completed with no text output)` }],\n\t\t\t\tdetails: createDetails(config, usage, assistantTurns, toolCalls, durationMs, false),\n\t\t\t};\n\t\t},\n\t};\n}\n"]}
|
|
@@ -0,0 +1,537 @@
|
|
|
1
|
+
# Pipiclaw Context Upgrade Design
|
|
2
|
+
|
|
3
|
+
## Scope
|
|
4
|
+
|
|
5
|
+
This document translates the context-upgrade spec into runtime behavior for `pipiclaw`.
|
|
6
|
+
|
|
7
|
+
It covers:
|
|
8
|
+
|
|
9
|
+
1. relevant memory injection
|
|
10
|
+
2. `SESSION.md`
|
|
11
|
+
3. changed `MEMORY.md` / `HISTORY.md` flow
|
|
12
|
+
4. compaction integration
|
|
13
|
+
5. contextual sub-agents
|
|
14
|
+
6. skill metadata and lightweight hooks
|
|
15
|
+
|
|
16
|
+
## Current Baseline
|
|
17
|
+
|
|
18
|
+
Today the main integration points are:
|
|
19
|
+
|
|
20
|
+
1. [ChannelRunner](/Users/oyasmi/projects/pipiclaw/src/agent.ts#L260)
|
|
21
|
+
2. [buildAppendSystemPrompt](/Users/oyasmi/projects/pipiclaw/src/prompt-builder.ts#L7)
|
|
22
|
+
3. [MemoryLifecycle](/Users/oyasmi/projects/pipiclaw/src/memory-lifecycle.ts#L20)
|
|
23
|
+
4. [memory consolidation](/Users/oyasmi/projects/pipiclaw/src/memory-consolidation.ts#L271)
|
|
24
|
+
5. [sub-agent discovery and execution](/Users/oyasmi/projects/pipiclaw/src/sub-agents.ts#L189) [subagent tool](/Users/oyasmi/projects/pipiclaw/src/tools/subagent.ts#L235)
|
|
25
|
+
6. [channel memory file bootstrap](/Users/oyasmi/projects/pipiclaw/src/memory-files.ts#L60)
|
|
26
|
+
|
|
27
|
+
The design below intentionally reuses these hooks rather than introducing a second runtime.
|
|
28
|
+
|
|
29
|
+
## Design Overview
|
|
30
|
+
|
|
31
|
+
### Main Idea
|
|
32
|
+
|
|
33
|
+
Introduce a new working-state artifact, `SESSION.md`, and a recall pipeline that proactively surfaces only the memory slices most likely to matter on the current turn.
|
|
34
|
+
|
|
35
|
+
The runtime then uses three complementary maintenance loops:
|
|
36
|
+
|
|
37
|
+
1. turn-time recall loop
|
|
38
|
+
2. session-state update loop
|
|
39
|
+
3. durable consolidation loop
|
|
40
|
+
|
|
41
|
+
### Why This Works
|
|
42
|
+
|
|
43
|
+
This design borrows the highest-value ideas from `claude-code` without importing its heaviest machinery:
|
|
44
|
+
|
|
45
|
+
1. proactive relevant-memory surfacing
|
|
46
|
+
2. explicit session notes
|
|
47
|
+
3. sidecar worker pattern for background extraction
|
|
48
|
+
4. compaction informed by working-state artifacts
|
|
49
|
+
|
|
50
|
+
It does not attempt to reproduce:
|
|
51
|
+
|
|
52
|
+
1. full prompt-cache-safe fork infrastructure
|
|
53
|
+
2. multi-backend swarm orchestration
|
|
54
|
+
3. complex task OS abstractions
|
|
55
|
+
|
|
56
|
+
## Runtime Components
|
|
57
|
+
|
|
58
|
+
### A. Relevant Memory Recall
|
|
59
|
+
|
|
60
|
+
Purpose:
|
|
61
|
+
|
|
62
|
+
- improve precision of context use without making every turn read full memory files
|
|
63
|
+
|
|
64
|
+
Inputs:
|
|
65
|
+
|
|
66
|
+
1. user message
|
|
67
|
+
2. current session model
|
|
68
|
+
3. `SESSION.md`
|
|
69
|
+
4. channel `MEMORY.md`
|
|
70
|
+
5. workspace `MEMORY.md`
|
|
71
|
+
6. channel `HISTORY.md`
|
|
72
|
+
|
|
73
|
+
Outputs:
|
|
74
|
+
|
|
75
|
+
1. a small injected memory block prepended to the user prompt
|
|
76
|
+
|
|
77
|
+
Selection pipeline:
|
|
78
|
+
|
|
79
|
+
1. parse each file into sections/blocks
|
|
80
|
+
2. score locally with lexical and structural heuristics
|
|
81
|
+
3. if candidate set is large, optionally rerank with a small model call
|
|
82
|
+
4. truncate to injection budget
|
|
83
|
+
|
|
84
|
+
Priority order:
|
|
85
|
+
|
|
86
|
+
1. `SESSION.md`
|
|
87
|
+
2. channel `MEMORY.md`
|
|
88
|
+
3. workspace `MEMORY.md`
|
|
89
|
+
4. `HISTORY.md`
|
|
90
|
+
|
|
91
|
+
Reasons:
|
|
92
|
+
|
|
93
|
+
1. current state usually matters more than old history
|
|
94
|
+
2. channel-local state usually matters more than workspace-shared background
|
|
95
|
+
3. history should help recovery, not dominate normal turns
|
|
96
|
+
|
|
97
|
+
### B. SESSION.md Updater
|
|
98
|
+
|
|
99
|
+
Purpose:
|
|
100
|
+
|
|
101
|
+
- maintain a compact, structured representation of the current working state
|
|
102
|
+
|
|
103
|
+
Shape:
|
|
104
|
+
|
|
105
|
+
Recommended stable sections:
|
|
106
|
+
|
|
107
|
+
1. `# Session Title`
|
|
108
|
+
2. `# Current State`
|
|
109
|
+
3. `# User Intent`
|
|
110
|
+
4. `# Active Files`
|
|
111
|
+
5. `# Decisions`
|
|
112
|
+
6. `# Constraints`
|
|
113
|
+
7. `# Errors & Corrections`
|
|
114
|
+
8. `# Next Steps`
|
|
115
|
+
9. `# Worklog`
|
|
116
|
+
|
|
117
|
+
Update model:
|
|
118
|
+
|
|
119
|
+
1. background updates after meaningful work
|
|
120
|
+
2. forced refresh before compaction
|
|
121
|
+
3. forced refresh before `/new` session switch
|
|
122
|
+
|
|
123
|
+
Important choice:
|
|
124
|
+
|
|
125
|
+
The updater should return structured JSON, and the runtime should render Markdown.
|
|
126
|
+
|
|
127
|
+
Reason:
|
|
128
|
+
|
|
129
|
+
1. less fragile than asking the worker to surgically edit Markdown
|
|
130
|
+
2. easier to test
|
|
131
|
+
3. easier to enforce section boundaries
|
|
132
|
+
4. easier to migrate format later
|
|
133
|
+
|
|
134
|
+
### C. Durable Consolidation
|
|
135
|
+
|
|
136
|
+
Purpose:
|
|
137
|
+
|
|
138
|
+
- promote long-lived facts to `MEMORY.md`
|
|
139
|
+
- push older narrative to `HISTORY.md`
|
|
140
|
+
|
|
141
|
+
This extends the existing system rather than replacing it.
|
|
142
|
+
|
|
143
|
+
Behavioral change:
|
|
144
|
+
|
|
145
|
+
The consolidation worker should treat `SESSION.md` as an input artifact when deciding:
|
|
146
|
+
|
|
147
|
+
1. what belongs in durable memory
|
|
148
|
+
2. what is still merely active work state
|
|
149
|
+
3. what should move to history
|
|
150
|
+
|
|
151
|
+
That change closes the loop:
|
|
152
|
+
|
|
153
|
+
recent transcript -> `SESSION.md` -> durable promotion -> future recall
|
|
154
|
+
|
|
155
|
+
### D. Sidecar Worker Abstraction
|
|
156
|
+
|
|
157
|
+
Purpose:
|
|
158
|
+
|
|
159
|
+
- unify small internal worker tasks under one runtime helper
|
|
160
|
+
|
|
161
|
+
Candidate tasks:
|
|
162
|
+
|
|
163
|
+
1. relevant-memory reranking
|
|
164
|
+
2. `SESSION.md` update generation
|
|
165
|
+
3. durable consolidation cleanup
|
|
166
|
+
4. history folding
|
|
167
|
+
|
|
168
|
+
This does not need prompt-cache-safe inheritance in the first iteration.
|
|
169
|
+
|
|
170
|
+
The first version should optimize for:
|
|
171
|
+
|
|
172
|
+
1. correctness
|
|
173
|
+
2. isolation
|
|
174
|
+
3. observability
|
|
175
|
+
4. shared error handling
|
|
176
|
+
|
|
177
|
+
## Source Of Truth Rules
|
|
178
|
+
|
|
179
|
+
The runtime should make conflicts boring and deterministic.
|
|
180
|
+
|
|
181
|
+
### Current Work State
|
|
182
|
+
|
|
183
|
+
For current active work state, trust:
|
|
184
|
+
|
|
185
|
+
1. live in-memory session messages first
|
|
186
|
+
2. then `SESSION.md`
|
|
187
|
+
3. then `MEMORY.md`
|
|
188
|
+
4. then `HISTORY.md`
|
|
189
|
+
|
|
190
|
+
### Durable Constraints And Decisions
|
|
191
|
+
|
|
192
|
+
For durable constraints and decisions, trust:
|
|
193
|
+
|
|
194
|
+
1. explicit human-managed workspace files first
|
|
195
|
+
2. then channel `MEMORY.md`
|
|
196
|
+
3. then `SESSION.md`
|
|
197
|
+
4. then `HISTORY.md`
|
|
198
|
+
|
|
199
|
+
This prevents the new hot-memory layer from accidentally becoming the durable truth for everything.
|
|
200
|
+
|
|
201
|
+
## Detailed Lifecycle
|
|
202
|
+
|
|
203
|
+
### 1. Channel Bootstrap
|
|
204
|
+
|
|
205
|
+
When a channel directory is created or touched for the first time:
|
|
206
|
+
|
|
207
|
+
1. ensure `MEMORY.md`
|
|
208
|
+
2. ensure `HISTORY.md`
|
|
209
|
+
3. ensure `SESSION.md`
|
|
210
|
+
|
|
211
|
+
This should extend the existing [ensureChannelMemoryFilesSync](/Users/oyasmi/projects/pipiclaw/src/memory-files.ts#L60) behavior.
|
|
212
|
+
|
|
213
|
+
### 2. Session Start
|
|
214
|
+
|
|
215
|
+
At session start:
|
|
216
|
+
|
|
217
|
+
1. load `SOUL.md`
|
|
218
|
+
2. load `AGENTS.md`
|
|
219
|
+
3. load skills metadata
|
|
220
|
+
4. do not preload `MEMORY.md`, `HISTORY.md`, or `SESSION.md`
|
|
221
|
+
|
|
222
|
+
Rationale:
|
|
223
|
+
|
|
224
|
+
1. keep base prompt lean
|
|
225
|
+
2. let recall injection decide what to surface
|
|
226
|
+
|
|
227
|
+
### 3. Normal User Turn
|
|
228
|
+
|
|
229
|
+
Before `session.prompt()`:
|
|
230
|
+
|
|
231
|
+
1. build the formatted user message as today
|
|
232
|
+
2. run relevant-memory recall
|
|
233
|
+
3. prepend a runtime context block if recall produced useful results
|
|
234
|
+
|
|
235
|
+
After the turn finishes successfully:
|
|
236
|
+
|
|
237
|
+
1. evaluate whether the turn dirtied working state enough to refresh `SESSION.md`
|
|
238
|
+
2. if yes, queue the background updater
|
|
239
|
+
|
|
240
|
+
Dirty signals include:
|
|
241
|
+
|
|
242
|
+
1. at least one assistant final response
|
|
243
|
+
2. tool activity
|
|
244
|
+
3. file-writing activity
|
|
245
|
+
4. large token delta
|
|
246
|
+
5. explicit user steering that changes task direction
|
|
247
|
+
|
|
248
|
+
### 4. Busy Steering / Follow-Up
|
|
249
|
+
|
|
250
|
+
Steer and follow-up messages remain normal runtime messages, but they should also count as `SESSION.md`-dirty signals.
|
|
251
|
+
|
|
252
|
+
Reason:
|
|
253
|
+
|
|
254
|
+
These are precisely the moments when "current state" tends to change.
|
|
255
|
+
|
|
256
|
+
### 5. Before Compaction
|
|
257
|
+
|
|
258
|
+
When `session_before_compact` fires:
|
|
259
|
+
|
|
260
|
+
1. synchronously refresh `SESSION.md` using the current session messages
|
|
261
|
+
2. run inline durable consolidation
|
|
262
|
+
3. proceed to compaction
|
|
263
|
+
|
|
264
|
+
Fallback:
|
|
265
|
+
|
|
266
|
+
1. if refresh fails, keep the last persisted `SESSION.md`
|
|
267
|
+
2. if durable consolidation fails, compaction still proceeds with the last good durable files
|
|
268
|
+
|
|
269
|
+
### 6. After Compaction
|
|
270
|
+
|
|
271
|
+
After compaction:
|
|
272
|
+
|
|
273
|
+
1. queue background cleanup for `MEMORY.md`
|
|
274
|
+
2. queue background folding for `HISTORY.md`
|
|
275
|
+
3. do not immediately rewrite `SESSION.md` again unless compaction changed work state interpretation
|
|
276
|
+
|
|
277
|
+
### 7. Before New Session
|
|
278
|
+
|
|
279
|
+
When `session_before_switch(reason=new)` fires:
|
|
280
|
+
|
|
281
|
+
1. synchronously refresh `SESSION.md`
|
|
282
|
+
2. run inline durable consolidation
|
|
283
|
+
3. allow session switch
|
|
284
|
+
|
|
285
|
+
After switch:
|
|
286
|
+
|
|
287
|
+
1. background cleanup may run
|
|
288
|
+
2. `SESSION.md` remains available to the next session
|
|
289
|
+
|
|
290
|
+
### 8. Process Restart
|
|
291
|
+
|
|
292
|
+
After restart:
|
|
293
|
+
|
|
294
|
+
1. the runner should reconstruct state from files
|
|
295
|
+
2. `SESSION.md` serves as the persisted hot handoff
|
|
296
|
+
3. no extra persisted metadata is required in the first iteration
|
|
297
|
+
|
|
298
|
+
Design choice:
|
|
299
|
+
|
|
300
|
+
Do not add a `memory-state.json` file yet.
|
|
301
|
+
|
|
302
|
+
Reason:
|
|
303
|
+
|
|
304
|
+
1. first iteration can remain simple
|
|
305
|
+
2. `SESSION.md` is already the persisted hot state
|
|
306
|
+
3. current session messages plus file timestamps are sufficient for an initial robust version
|
|
307
|
+
|
|
308
|
+
If later needed, a metadata file can be added as a follow-up optimization rather than a baseline dependency.
|
|
309
|
+
|
|
310
|
+
### 9. Old Channel Migration
|
|
311
|
+
|
|
312
|
+
For existing channels that predate this design:
|
|
313
|
+
|
|
314
|
+
1. create `SESSION.md` lazily when the channel is next touched
|
|
315
|
+
2. do not perform a one-shot rewrite of `MEMORY.md`
|
|
316
|
+
3. let background cleanup gradually strip transient working-state details from `MEMORY.md`
|
|
317
|
+
|
|
318
|
+
This avoids rollout-time churn on live channels.
|
|
319
|
+
|
|
320
|
+
## Memory Ownership Rules
|
|
321
|
+
|
|
322
|
+
### SESSION.md Owns
|
|
323
|
+
|
|
324
|
+
1. precise active task state
|
|
325
|
+
2. active files and commands
|
|
326
|
+
3. immediate next steps
|
|
327
|
+
4. recent significant errors
|
|
328
|
+
5. temporary but important work hypotheses
|
|
329
|
+
|
|
330
|
+
### MEMORY.md Owns
|
|
331
|
+
|
|
332
|
+
1. durable facts
|
|
333
|
+
2. durable preferences
|
|
334
|
+
3. stable constraints
|
|
335
|
+
4. decisions that should survive beyond current execution
|
|
336
|
+
5. medium-horizon open loops
|
|
337
|
+
|
|
338
|
+
### HISTORY.md Owns
|
|
339
|
+
|
|
340
|
+
1. chronological work periods
|
|
341
|
+
2. milestones
|
|
342
|
+
3. older summarized context
|
|
343
|
+
|
|
344
|
+
### Cleanup Implication
|
|
345
|
+
|
|
346
|
+
Background cleanup should now be allowed to remove from `MEMORY.md` content that is clearly transient working state and belongs in `SESSION.md`.
|
|
347
|
+
|
|
348
|
+
This is an intentional semantic shift from the current append-first-only behavior.
|
|
349
|
+
|
|
350
|
+
## End-To-End Flow
|
|
351
|
+
|
|
352
|
+
The intended steady-state loop is:
|
|
353
|
+
|
|
354
|
+
1. user sends a message
|
|
355
|
+
2. runtime recalls relevant context from `SESSION.md`, `MEMORY.md`, and `HISTORY.md`
|
|
356
|
+
3. main agent runs with a small injected memory block
|
|
357
|
+
4. turn completes
|
|
358
|
+
5. runtime updates `SESSION.md` if work state changed enough
|
|
359
|
+
6. before compaction or new session, runtime forces a fresh `SESSION.md` flush
|
|
360
|
+
7. runtime promotes durable facts to `MEMORY.md` and older narrative to `HISTORY.md`
|
|
361
|
+
8. next turn benefits from the updated files
|
|
362
|
+
|
|
363
|
+
This is the operational closure that the current design lacks.
|
|
364
|
+
|
|
365
|
+
## Recall Injection Format
|
|
366
|
+
|
|
367
|
+
Use an explicit runtime wrapper rather than pretending the memory snippets are part of the user text.
|
|
368
|
+
|
|
369
|
+
Recommended shape:
|
|
370
|
+
|
|
371
|
+
```text
|
|
372
|
+
<runtime_context>
|
|
373
|
+
Relevant context for this turn:
|
|
374
|
+
|
|
375
|
+
[session/current-state]
|
|
376
|
+
...
|
|
377
|
+
|
|
378
|
+
[channel-memory/constraints]
|
|
379
|
+
...
|
|
380
|
+
</runtime_context>
|
|
381
|
+
|
|
382
|
+
<user_message>
|
|
383
|
+
...
|
|
384
|
+
</user_message>
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
Rationale:
|
|
388
|
+
|
|
389
|
+
1. separates runtime-provided context from user intent
|
|
390
|
+
2. keeps prompts inspectable in debug mode
|
|
391
|
+
3. makes future migration to attachment-style rendering easier
|
|
392
|
+
|
|
393
|
+
## SESSION.md Rendering
|
|
394
|
+
|
|
395
|
+
The runtime should render `SESSION.md` deterministically from structured update data.
|
|
396
|
+
|
|
397
|
+
Properties:
|
|
398
|
+
|
|
399
|
+
1. stable section order
|
|
400
|
+
2. empty sections omitted or left blank according to template choice
|
|
401
|
+
3. explicit truncation for very large sections
|
|
402
|
+
4. deterministic formatting for testing
|
|
403
|
+
|
|
404
|
+
Recommended rule:
|
|
405
|
+
|
|
406
|
+
- keep a stable template
|
|
407
|
+
- render empty sections as present but blank only if needed for readability
|
|
408
|
+
- otherwise omit clearly empty tail sections to keep file lean
|
|
409
|
+
|
|
410
|
+
Recommended practical default:
|
|
411
|
+
|
|
412
|
+
1. keep top sections stable
|
|
413
|
+
2. omit empty low-value tail sections such as `Worklog` when fully empty
|
|
414
|
+
3. cap `Worklog` aggressively so it never becomes a second `HISTORY.md`
|
|
415
|
+
|
|
416
|
+
## Update Trigger Strategy
|
|
417
|
+
|
|
418
|
+
The updater should not run on every turn.
|
|
419
|
+
|
|
420
|
+
Suggested thresholds:
|
|
421
|
+
|
|
422
|
+
1. at least 2 meaningful user/assistant exchanges since last update
|
|
423
|
+
2. or at least 4 tool calls since last update
|
|
424
|
+
3. or at least one file mutation plus a final assistant reply
|
|
425
|
+
4. or an impending compaction / new-session switch
|
|
426
|
+
|
|
427
|
+
This keeps cost bounded while still refreshing the working state at natural boundaries.
|
|
428
|
+
|
|
429
|
+
## Failure Handling
|
|
430
|
+
|
|
431
|
+
### Relevant Recall Failure
|
|
432
|
+
|
|
433
|
+
If recall fails:
|
|
434
|
+
|
|
435
|
+
1. continue the turn without injected memory
|
|
436
|
+
2. log warning
|
|
437
|
+
3. do not block the agent
|
|
438
|
+
|
|
439
|
+
### SESSION.md Update Failure
|
|
440
|
+
|
|
441
|
+
If the background update fails:
|
|
442
|
+
|
|
443
|
+
1. keep the last persisted file
|
|
444
|
+
2. mark no special error to user
|
|
445
|
+
3. retry next time thresholds are met
|
|
446
|
+
|
|
447
|
+
If the synchronous pre-compaction refresh fails:
|
|
448
|
+
|
|
449
|
+
1. keep the last persisted file
|
|
450
|
+
2. log warning
|
|
451
|
+
3. continue to compaction
|
|
452
|
+
|
|
453
|
+
If no persisted `SESSION.md` exists yet:
|
|
454
|
+
|
|
455
|
+
1. fall back to an empty template
|
|
456
|
+
2. continue without blocking the user
|
|
457
|
+
|
|
458
|
+
### Durable Consolidation Failure
|
|
459
|
+
|
|
460
|
+
If inline durable consolidation fails:
|
|
461
|
+
|
|
462
|
+
1. keep existing `MEMORY.md` and `HISTORY.md`
|
|
463
|
+
2. continue to compaction if `SESSION.md` is available
|
|
464
|
+
3. queue background retry later
|
|
465
|
+
|
|
466
|
+
### Corruption Policy
|
|
467
|
+
|
|
468
|
+
All writes to `SESSION.md`, `MEMORY.md`, and `HISTORY.md` should be atomic.
|
|
469
|
+
|
|
470
|
+
That matches the direction already used in [memory-files.ts](/Users/oyasmi/projects/pipiclaw/src/memory-files.ts#L38).
|
|
471
|
+
|
|
472
|
+
## Sub-Agent Design Integration
|
|
473
|
+
|
|
474
|
+
Current sub-agents are explicitly isolated and only receive a generated runtime preamble plus the supplied task, [subagent.ts](/Users/oyasmi/projects/pipiclaw/src/tools/subagent.ts#L170).
|
|
475
|
+
|
|
476
|
+
The upgraded design adds:
|
|
477
|
+
|
|
478
|
+
1. `contextMode: isolated | contextual`
|
|
479
|
+
2. `memory: none | relevant | session | channel`
|
|
480
|
+
|
|
481
|
+
Semantics:
|
|
482
|
+
|
|
483
|
+
1. `isolated`
|
|
484
|
+
- current behavior
|
|
485
|
+
2. `contextual + relevant`
|
|
486
|
+
- prepend relevant recall slices for the subtask
|
|
487
|
+
3. `contextual + session`
|
|
488
|
+
- prepend condensed `SESSION.md`
|
|
489
|
+
4. `contextual + channel`
|
|
490
|
+
- prepend relevant `SESSION.md` plus durable memory summary
|
|
491
|
+
|
|
492
|
+
This avoids forcing the parent agent to manually hand-write all background context into `task`.
|
|
493
|
+
|
|
494
|
+
## Skill Design Integration
|
|
495
|
+
|
|
496
|
+
Current skill loading is metadata-light and passive, [agent.ts](/Users/oyasmi/projects/pipiclaw/src/agent.ts#L362).
|
|
497
|
+
|
|
498
|
+
The upgraded design adds light frontmatter semantics:
|
|
499
|
+
|
|
500
|
+
1. `when_to_use`
|
|
501
|
+
2. `allowed_tools`
|
|
502
|
+
3. `paths`
|
|
503
|
+
4. `hooks`
|
|
504
|
+
5. optional `memory_scope`
|
|
505
|
+
|
|
506
|
+
Supported hook points in first iteration:
|
|
507
|
+
|
|
508
|
+
1. `before_prompt`
|
|
509
|
+
2. `after_response`
|
|
510
|
+
3. `before_compact`
|
|
511
|
+
4. `after_subagent`
|
|
512
|
+
|
|
513
|
+
These hooks should remain session-scoped and lightweight. They exist to shape runtime context, not to build a separate automation engine.
|
|
514
|
+
|
|
515
|
+
## Explicitly Deferred Decisions
|
|
516
|
+
|
|
517
|
+
These are intentionally deferred so they do not block the first strong implementation:
|
|
518
|
+
|
|
519
|
+
1. persisted dirty-cursor metadata
|
|
520
|
+
2. prompt-cache-safe fork inheritance
|
|
521
|
+
3. richer background scheduling policy
|
|
522
|
+
4. automatic promotion heuristics based on file edit detection alone
|
|
523
|
+
|
|
524
|
+
If the first rollout proves stable, these can be revisited from real usage data rather than guessed up front.
|
|
525
|
+
|
|
526
|
+
## What We Intentionally Do Not Adopt Yet
|
|
527
|
+
|
|
528
|
+
We do not adopt these `claude-code` patterns in the first implementation:
|
|
529
|
+
|
|
530
|
+
1. full cache-safe fork inheritance
|
|
531
|
+
2. streaming concurrent tool executor
|
|
532
|
+
3. tmux/swarm task backends
|
|
533
|
+
4. full task OS abstractions
|
|
534
|
+
|
|
535
|
+
Reason:
|
|
536
|
+
|
|
537
|
+
The biggest near-term performance gain for `pipiclaw` comes from context quality, not orchestration maximalism.
|