@oyasmi/pipiclaw 0.3.5 → 0.5.0
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/CHANGELOG.md +3 -0
- package/LICENSE +184 -0
- package/README.md +267 -230
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +158 -76
- package/dist/agent.js.map +1 -1
- package/dist/command-extension.d.ts.map +1 -1
- package/dist/command-extension.js.map +1 -1
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js.map +1 -1
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/config-loader.js.map +1 -1
- package/dist/context.d.ts +18 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +26 -2
- package/dist/context.js.map +1 -1
- package/dist/delivery.d.ts.map +1 -1
- package/dist/delivery.js +11 -14
- package/dist/delivery.js.map +1 -1
- package/dist/dingtalk.d.ts.map +1 -1
- package/dist/dingtalk.js +26 -26
- package/dist/dingtalk.js.map +1 -1
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +5 -8
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- 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/log.d.ts.map +1 -1
- package/dist/log.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js.map +1 -1
- 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 +67 -2
- 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/model-utils.d.ts.map +1 -1
- package/dist/model-utils.js.map +1 -1
- package/dist/paths.d.ts.map +1 -1
- 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/sandbox.d.ts.map +1 -1
- package/dist/sandbox.js +0 -1
- package/dist/sandbox.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/shell-escape.d.ts.map +1 -1
- package/dist/shell-escape.js.map +1 -1
- 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/store.d.ts.map +1 -1
- package/dist/store.js +2 -3
- package/dist/store.js.map +1 -1
- package/dist/sub-agents.d.ts +10 -0
- package/dist/sub-agents.d.ts.map +1 -1
- package/dist/sub-agents.js +132 -10
- package/dist/sub-agents.js.map +1 -1
- package/dist/tools/attach.d.ts.map +1 -1
- package/dist/tools/attach.js.map +1 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.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/read.d.ts.map +1 -1
- package/dist/tools/read.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/dist/tools/truncate.d.ts.map +1 -1
- package/dist/tools/truncate.js.map +1 -1
- package/dist/tools/write-content.d.ts.map +1 -1
- package/dist/tools/write-content.js.map +1 -1
- package/dist/tools/write.d.ts.map +1 -1
- package/dist/tools/write.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 +297 -0
- package/docs/proj-review.md +188 -0
- package/docs/subagent/pi-subagent-analyse.txt +190 -0
- package/docs/subagent/pi-subagent-design.txt +266 -0
- package/docs/subagent/pi-subagent-phase1-plan.txt +529 -0
- package/docs/test-supplementation-plan.md +553 -0
- package/package.json +71 -53
package/dist/sub-agents.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sub-agents.d.ts","sourceRoot":"","sources":["../src/sub-agents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAQtD,QAAA,MAAM,uBAAuB,4CAA6C,CAAC;AAS3E,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,YAAY,GAAG,QAAQ,CAAC;CAChC;AAED,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAAC,cAAc,EAAE,OAAO,GAAG,UAAU,CAAC;IACzF,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,2BAA2B;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AASD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAErE;AAMD,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAE5D;AAeD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,GAAG;IAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAuB7G;AAoCD,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,uBAAuB,CAyG9G;AAED,wBAAgB,qBAAqB,CACpC,eAAe,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,EAC7B,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,EACxB,gBAAgB,EAAE,cAAc,EAAE,EAClC,SAAS,EAAE,2BAA2B,GACpC;IAAE,MAAM,CAAC,EAAE,sBAAsB,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAyErD;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,QAAQ,GAAE,MAAW,GAAG,MAAM,CAW1F","sourcesContent":["import type { Api, Model } from \"@mariozechner/pi-ai\";\nimport { parseFrontmatter } from \"@mariozechner/pi-coding-agent\";\nimport type { Dirent } from \"fs\";\nimport { existsSync, readdirSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { findExactModelReferenceMatch, formatModelReference } from \"./model-utils.js\";\nimport { SUB_AGENTS_DIR_NAME } from \"./paths.js\";\n\nconst ALLOWED_SUB_AGENT_TOOLS = [\"read\", \"bash\", \"edit\", \"write\"] as const;\nconst DEFAULT_SUB_AGENT_TOOLS = [\"read\", \"bash\"] as const;\nconst DEFAULT_MAX_TURNS = 24;\nconst DEFAULT_MAX_TOOL_CALLS = 48;\nconst DEFAULT_MAX_WALL_TIME_SEC = 300;\nconst DEFAULT_BASH_TIMEOUT_SEC = 120;\nconst MAX_SUB_AGENT_TASK_CHARS = 12000;\nconst MAX_SUB_AGENT_SYSTEM_PROMPT_CHARS = 16000;\n\nexport type SubAgentToolName = (typeof ALLOWED_SUB_AGENT_TOOLS)[number];\n\nexport interface SubAgentConfig {\n\tname: string;\n\tdescription: string;\n\tsystemPrompt: string;\n\ttools: SubAgentToolName[];\n\tmodel?: Model<Api>;\n\tmodelRef?: string;\n\tmaxTurns: number;\n\tmaxToolCalls: number;\n\tmaxWallTimeSec: number;\n\tbashTimeoutSec: number;\n\tfilePath?: string;\n\tsource: \"predefined\" | \"inline\";\n}\n\nexport interface ResolvedSubAgentConfig extends Omit<SubAgentConfig, \"model\" | \"modelRef\"> {\n\tmodel: Model<Api>;\n\tmodelRef: string;\n}\n\nexport interface SubAgentDiscoveryResult {\n\tdirectory: string;\n\tagents: SubAgentConfig[];\n\twarnings: string[];\n}\n\nexport interface SubAgentInvocationOverrides {\n\tagent?: string;\n\tname?: string;\n\tsystemPrompt?: string;\n\ttools?: string[];\n\tmodel?: string;\n\tmaxTurns?: number;\n\tmaxToolCalls?: number;\n\tmaxWallTimeSec?: number;\n\tbashTimeoutSec?: number;\n}\n\nfunction validateTextLength(value: string, maxChars: number, label: string): string | undefined {\n\tif (value.length <= maxChars) {\n\t\treturn undefined;\n\t}\n\treturn `${label} exceeds ${maxChars} characters (got ${value.length}).`;\n}\n\nexport function validateSubAgentTask(task: string): string | undefined {\n\treturn validateTextLength(task, MAX_SUB_AGENT_TASK_CHARS, \"Sub-agent task\");\n}\n\nfunction validateSubAgentSystemPrompt(systemPrompt: string, label: string): string | undefined {\n\treturn validateTextLength(systemPrompt, MAX_SUB_AGENT_SYSTEM_PROMPT_CHARS, label);\n}\n\nexport function getSubAgentsDir(workspaceDir: string): string {\n\treturn join(workspaceDir, SUB_AGENTS_DIR_NAME);\n}\n\nfunction parseToolNames(raw: string | undefined): { tools: SubAgentToolName[]; error?: string } {\n\tif (!raw || !raw.trim()) {\n\t\treturn { tools: [...DEFAULT_SUB_AGENT_TOOLS] };\n\t}\n\n\tconst values = raw\n\t\t.split(\",\")\n\t\t.map((value) => value.trim())\n\t\t.filter((value) => value.length > 0);\n\n\treturn validateToolNames(values);\n}\n\nexport function validateToolNames(values: string[] | undefined): { tools: SubAgentToolName[]; error?: string } {\n\tif (!values || values.length === 0) {\n\t\treturn { tools: [...DEFAULT_SUB_AGENT_TOOLS] };\n\t}\n\n\tconst tools: SubAgentToolName[] = [];\n\tconst seen = new Set<string>();\n\tfor (const value of values) {\n\t\tconst normalized = value.trim();\n\t\tif (!normalized || seen.has(normalized)) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (!ALLOWED_SUB_AGENT_TOOLS.includes(normalized as SubAgentToolName)) {\n\t\t\treturn {\n\t\t\t\ttools: [],\n\t\t\t\terror: `Unknown tool \"${normalized}\". Allowed tools: ${ALLOWED_SUB_AGENT_TOOLS.join(\", \")}`,\n\t\t\t};\n\t\t}\n\t\tseen.add(normalized);\n\t\ttools.push(normalized as SubAgentToolName);\n\t}\n\n\treturn { tools: tools.length > 0 ? tools : [...DEFAULT_SUB_AGENT_TOOLS] };\n}\n\nfunction parsePositiveInteger(raw: string | undefined, fallback: number): { value: number; warning?: string } {\n\tif (!raw || !raw.trim()) {\n\t\treturn { value: fallback };\n\t}\n\n\tconst parsed = Number.parseInt(raw.trim(), 10);\n\tif (!Number.isFinite(parsed) || parsed <= 0) {\n\t\treturn { value: fallback, warning: `Invalid numeric value \"${raw}\", using default ${fallback}` };\n\t}\n\n\treturn { value: parsed };\n}\n\nfunction resolvePositiveOverride(value: number | undefined, fallback: number): number {\n\tif (!Number.isFinite(value) || value === undefined || value <= 0) {\n\t\treturn fallback;\n\t}\n\treturn Math.floor(value);\n}\n\nfunction resolveModelReference(\n\tmodelRef: string,\n\tavailableModels: Model<Api>[],\n): { model?: Model<Api>; error?: string } {\n\tconst { match, ambiguous } = findExactModelReferenceMatch(modelRef, availableModels);\n\tif (match) {\n\t\treturn { model: match };\n\t}\n\tif (ambiguous) {\n\t\treturn { error: `Model reference \"${modelRef}\" is ambiguous. Use provider/modelId.` };\n\t}\n\treturn { error: `Model reference \"${modelRef}\" was not found among available models.` };\n}\n\nexport function discoverSubAgents(workspaceDir: string, availableModels: Model<Api>[]): SubAgentDiscoveryResult {\n\tconst directory = getSubAgentsDir(workspaceDir);\n\tif (!existsSync(directory)) {\n\t\treturn { directory, agents: [], warnings: [] };\n\t}\n\n\tconst warnings: string[] = [];\n\tconst agents: SubAgentConfig[] = [];\n\tconst seenNames = new Set<string>();\n\tlet entries: Dirent<string>[];\n\ttry {\n\t\tentries = readdirSync(directory, { withFileTypes: true })\n\t\t\t.filter((entry) => entry.name.endsWith(\".md\") && (entry.isFile() || entry.isSymbolicLink()))\n\t\t\t.sort((a, b) => a.name.localeCompare(b.name));\n\t} catch (error) {\n\t\treturn {\n\t\t\tdirectory,\n\t\t\tagents: [],\n\t\t\twarnings: [`Failed to read sub-agents directory (${error instanceof Error ? error.message : String(error)})`],\n\t\t};\n\t}\n\n\tfor (const entry of entries) {\n\t\tconst filePath = join(directory, entry.name);\n\t\tlet content = \"\";\n\t\ttry {\n\t\t\tcontent = readFileSync(filePath, \"utf-8\");\n\t\t} catch (error) {\n\t\t\twarnings.push(\n\t\t\t\t`${entry.name}: failed to read file (${error instanceof Error ? error.message : String(error)})`,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst { frontmatter, body } = parseFrontmatter<Record<string, string>>(content);\n\t\tconst name = frontmatter.name?.trim();\n\t\tconst description = frontmatter.description?.trim();\n\n\t\tif (!name || !description) {\n\t\t\twarnings.push(`${entry.name}: missing required frontmatter fields \"name\" or \"description\"`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (seenNames.has(name)) {\n\t\t\twarnings.push(`${entry.name}: duplicate sub-agent name \"${name}\" ignored`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst toolParse = parseToolNames(frontmatter.tools);\n\t\tif (toolParse.error) {\n\t\t\twarnings.push(`${entry.name}: ${toolParse.error}`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst maxTurns = parsePositiveInteger(frontmatter.maxTurns, DEFAULT_MAX_TURNS);\n\t\tconst maxToolCalls = parsePositiveInteger(frontmatter.maxToolCalls, DEFAULT_MAX_TOOL_CALLS);\n\t\tconst maxWallTimeSec = parsePositiveInteger(frontmatter.maxWallTimeSec, DEFAULT_MAX_WALL_TIME_SEC);\n\t\tconst bashTimeoutSec = parsePositiveInteger(frontmatter.bashTimeoutSec, DEFAULT_BASH_TIMEOUT_SEC);\n\n\t\tfor (const warning of [maxTurns.warning, maxToolCalls.warning, maxWallTimeSec.warning, bashTimeoutSec.warning]) {\n\t\t\tif (warning) {\n\t\t\t\twarnings.push(`${entry.name}: ${warning}`);\n\t\t\t}\n\t\t}\n\n\t\tconst modelRef = frontmatter.model?.trim();\n\t\tlet model: Model<Api> | undefined;\n\t\tif (modelRef) {\n\t\t\tconst resolved = resolveModelReference(modelRef, availableModels);\n\t\t\tif (!resolved.model) {\n\t\t\t\twarnings.push(`${entry.name}: ${resolved.error}`);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tmodel = resolved.model;\n\t\t}\n\n\t\tconst trimmedBody = body.trim();\n\t\tif (!trimmedBody) {\n\t\t\twarnings.push(`${entry.name}: empty system prompt body`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst promptLengthError = validateSubAgentSystemPrompt(trimmedBody, \"Sub-agent system prompt\");\n\t\tif (promptLengthError) {\n\t\t\twarnings.push(`${entry.name}: ${promptLengthError}`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tseenNames.add(name);\n\t\tagents.push({\n\t\t\tname,\n\t\t\tdescription,\n\t\t\tsystemPrompt: trimmedBody,\n\t\t\ttools: toolParse.tools,\n\t\t\tmodel,\n\t\t\tmodelRef: modelRef || (model ? formatModelReference(model) : undefined),\n\t\t\tmaxTurns: maxTurns.value,\n\t\t\tmaxToolCalls: maxToolCalls.value,\n\t\t\tmaxWallTimeSec: maxWallTimeSec.value,\n\t\t\tbashTimeoutSec: bashTimeoutSec.value,\n\t\t\tfilePath,\n\t\t\tsource: \"predefined\",\n\t\t});\n\t}\n\n\treturn { directory, agents, warnings };\n}\n\nexport function resolveSubAgentConfig(\n\tavailableModels: Model<Api>[],\n\tcurrentModel: Model<Api>,\n\tpredefinedAgents: SubAgentConfig[],\n\toverrides: SubAgentInvocationOverrides,\n): { config?: ResolvedSubAgentConfig; error?: string } {\n\tconst baseConfig = overrides.agent ? predefinedAgents.find((agent) => agent.name === overrides.agent) : undefined;\n\tif (overrides.agent && !baseConfig) {\n\t\tconst available = predefinedAgents.length > 0 ? predefinedAgents.map((agent) => agent.name).join(\", \") : \"none\";\n\t\treturn { error: `Unknown sub-agent \"${overrides.agent}\". Available sub-agents: ${available}.` };\n\t}\n\n\tif (!baseConfig && (!overrides.systemPrompt || !overrides.systemPrompt.trim())) {\n\t\treturn { error: 'Provide either \"agent\" or \"systemPrompt\" to define the sub-agent.' };\n\t}\n\n\tconst tools = overrides.tools\n\t\t? validateToolNames(overrides.tools)\n\t\t: { tools: baseConfig?.tools ?? [...DEFAULT_SUB_AGENT_TOOLS] };\n\tif (tools.error) {\n\t\treturn { error: tools.error };\n\t}\n\n\tlet model = baseConfig?.model;\n\tlet modelRef = baseConfig?.modelRef;\n\tif (overrides.model?.trim()) {\n\t\tconst resolved = resolveModelReference(overrides.model.trim(), availableModels);\n\t\tif (!resolved.model) {\n\t\t\treturn { error: resolved.error };\n\t\t}\n\t\tmodel = resolved.model;\n\t\tmodelRef = formatModelReference(resolved.model);\n\t}\n\n\tconst maxTurns = resolvePositiveOverride(overrides.maxTurns, baseConfig?.maxTurns ?? DEFAULT_MAX_TURNS);\n\tconst maxToolCalls = resolvePositiveOverride(\n\t\toverrides.maxToolCalls,\n\t\tbaseConfig?.maxToolCalls ?? DEFAULT_MAX_TOOL_CALLS,\n\t);\n\tconst maxWallTimeSec = resolvePositiveOverride(\n\t\toverrides.maxWallTimeSec,\n\t\tbaseConfig?.maxWallTimeSec ?? DEFAULT_MAX_WALL_TIME_SEC,\n\t);\n\tconst bashTimeoutSec = resolvePositiveOverride(\n\t\toverrides.bashTimeoutSec,\n\t\tbaseConfig?.bashTimeoutSec ?? DEFAULT_BASH_TIMEOUT_SEC,\n\t);\n\n\tconst systemPrompt = overrides.systemPrompt?.trim() || baseConfig?.systemPrompt || \"\";\n\tif (!systemPrompt) {\n\t\treturn { error: \"Sub-agent system prompt cannot be empty.\" };\n\t}\n\tif (overrides.systemPrompt?.trim()) {\n\t\tconst promptLengthError = validateSubAgentSystemPrompt(\n\t\t\toverrides.systemPrompt.trim(),\n\t\t\t\"Inline sub-agent systemPrompt\",\n\t\t);\n\t\tif (promptLengthError) {\n\t\t\treturn { error: promptLengthError };\n\t\t}\n\t}\n\n\treturn {\n\t\tconfig: {\n\t\t\tname: overrides.name?.trim() || baseConfig?.name || \"dynamic-subagent\",\n\t\t\tdescription: baseConfig?.description || \"Inline sub-agent\",\n\t\t\tsystemPrompt,\n\t\t\ttools: tools.tools,\n\t\t\tmodel: model ?? currentModel,\n\t\t\tmodelRef: modelRef ?? formatModelReference(model ?? currentModel),\n\t\t\tmaxTurns,\n\t\t\tmaxToolCalls,\n\t\t\tmaxWallTimeSec,\n\t\t\tbashTimeoutSec,\n\t\t\tfilePath: baseConfig?.filePath,\n\t\t\tsource: baseConfig ? \"predefined\" : \"inline\",\n\t\t},\n\t};\n}\n\nexport function formatSubAgentList(agents: SubAgentConfig[], maxItems: number = 12): string {\n\tif (agents.length === 0) {\n\t\treturn \"none\";\n\t}\n\n\tconst listed = agents.slice(0, maxItems).map((agent) => `- \\`${agent.name}\\`: ${agent.description}`);\n\tif (agents.length <= maxItems) {\n\t\treturn listed.join(\"\\n\");\n\t}\n\n\treturn `${listed.join(\"\\n\")}\\n- ... and ${agents.length - maxItems} more`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sub-agents.d.ts","sourceRoot":"","sources":["../src/sub-agents.ts"],"names":[],"mappings":"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"}
|
package/dist/sub-agents.js
CHANGED
|
@@ -11,6 +11,8 @@ const DEFAULT_MAX_WALL_TIME_SEC = 300;
|
|
|
11
11
|
const DEFAULT_BASH_TIMEOUT_SEC = 120;
|
|
12
12
|
const MAX_SUB_AGENT_TASK_CHARS = 12000;
|
|
13
13
|
const MAX_SUB_AGENT_SYSTEM_PROMPT_CHARS = 16000;
|
|
14
|
+
const ALLOWED_CONTEXT_MODES = ["isolated", "contextual"];
|
|
15
|
+
const ALLOWED_MEMORY_MODES = ["none", "session", "relevant"];
|
|
14
16
|
function validateTextLength(value, maxChars, label) {
|
|
15
17
|
if (value.length <= maxChars) {
|
|
16
18
|
return undefined;
|
|
@@ -26,15 +28,87 @@ function validateSubAgentSystemPrompt(systemPrompt, label) {
|
|
|
26
28
|
export function getSubAgentsDir(workspaceDir) {
|
|
27
29
|
return join(workspaceDir, SUB_AGENTS_DIR_NAME);
|
|
28
30
|
}
|
|
31
|
+
function readOptionalTrimmedString(value) {
|
|
32
|
+
if (typeof value !== "string") {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
const trimmed = value.trim();
|
|
36
|
+
return trimmed ? trimmed : undefined;
|
|
37
|
+
}
|
|
29
38
|
function parseToolNames(raw) {
|
|
30
|
-
if (
|
|
39
|
+
if (raw === undefined || raw === null) {
|
|
31
40
|
return { tools: [...DEFAULT_SUB_AGENT_TOOLS] };
|
|
32
41
|
}
|
|
33
|
-
|
|
34
|
-
.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
42
|
+
if (typeof raw === "string") {
|
|
43
|
+
if (!raw.trim()) {
|
|
44
|
+
return { tools: [...DEFAULT_SUB_AGENT_TOOLS] };
|
|
45
|
+
}
|
|
46
|
+
const values = raw
|
|
47
|
+
.split(",")
|
|
48
|
+
.map((value) => value.trim())
|
|
49
|
+
.filter((value) => value.length > 0);
|
|
50
|
+
return validateToolNames(values);
|
|
51
|
+
}
|
|
52
|
+
if (Array.isArray(raw)) {
|
|
53
|
+
const invalidValue = raw.find((value) => typeof value !== "string");
|
|
54
|
+
if (invalidValue !== undefined) {
|
|
55
|
+
return { tools: [], error: 'Invalid "tools" frontmatter: expected a string or string[]' };
|
|
56
|
+
}
|
|
57
|
+
return validateToolNames(raw);
|
|
58
|
+
}
|
|
59
|
+
return { tools: [], error: 'Invalid "tools" frontmatter: expected a string or string[]' };
|
|
60
|
+
}
|
|
61
|
+
function parseStringList(raw, label) {
|
|
62
|
+
if (raw === undefined || raw === null) {
|
|
63
|
+
return { values: [] };
|
|
64
|
+
}
|
|
65
|
+
if (typeof raw === "string") {
|
|
66
|
+
if (!raw.trim()) {
|
|
67
|
+
return { values: [] };
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
values: Array.from(new Set(raw
|
|
71
|
+
.split(",")
|
|
72
|
+
.map((value) => value.trim())
|
|
73
|
+
.filter((value) => value.length > 0))),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
if (Array.isArray(raw)) {
|
|
77
|
+
const invalidValue = raw.find((value) => typeof value !== "string");
|
|
78
|
+
if (invalidValue !== undefined) {
|
|
79
|
+
return { values: [], error: `Invalid "${label}" frontmatter: expected a string or string[]` };
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
values: Array.from(new Set(raw.map((value) => value.trim()).filter((value) => value.length > 0))),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return { values: [], error: `Invalid "${label}" frontmatter: expected a string or string[]` };
|
|
86
|
+
}
|
|
87
|
+
function parseContextMode(raw) {
|
|
88
|
+
const normalized = readOptionalTrimmedString(raw);
|
|
89
|
+
if (!normalized) {
|
|
90
|
+
return { value: "isolated" };
|
|
91
|
+
}
|
|
92
|
+
if (ALLOWED_CONTEXT_MODES.includes(normalized)) {
|
|
93
|
+
return { value: normalized };
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
value: "isolated",
|
|
97
|
+
error: `Unknown contextMode "${normalized}". Allowed values: ${ALLOWED_CONTEXT_MODES.join(", ")}`,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function parseMemoryMode(raw, contextMode) {
|
|
101
|
+
const normalized = readOptionalTrimmedString(raw);
|
|
102
|
+
if (!normalized) {
|
|
103
|
+
return { value: contextMode === "contextual" ? "relevant" : "none" };
|
|
104
|
+
}
|
|
105
|
+
if (ALLOWED_MEMORY_MODES.includes(normalized)) {
|
|
106
|
+
return { value: normalized };
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
value: contextMode === "contextual" ? "relevant" : "none",
|
|
110
|
+
error: `Unknown memory "${normalized}". Allowed values: ${ALLOWED_MEMORY_MODES.join(", ")}`,
|
|
111
|
+
};
|
|
38
112
|
}
|
|
39
113
|
export function validateToolNames(values) {
|
|
40
114
|
if (!values || values.length === 0) {
|
|
@@ -59,7 +133,19 @@ export function validateToolNames(values) {
|
|
|
59
133
|
return { tools: tools.length > 0 ? tools : [...DEFAULT_SUB_AGENT_TOOLS] };
|
|
60
134
|
}
|
|
61
135
|
function parsePositiveInteger(raw, fallback) {
|
|
62
|
-
if (
|
|
136
|
+
if (raw === undefined || raw === null) {
|
|
137
|
+
return { value: fallback };
|
|
138
|
+
}
|
|
139
|
+
if (typeof raw === "number") {
|
|
140
|
+
if (!Number.isFinite(raw) || raw <= 0) {
|
|
141
|
+
return { value: fallback, warning: `Invalid numeric value "${String(raw)}", using default ${fallback}` };
|
|
142
|
+
}
|
|
143
|
+
return { value: Math.floor(raw) };
|
|
144
|
+
}
|
|
145
|
+
if (typeof raw !== "string") {
|
|
146
|
+
return { value: fallback, warning: `Invalid numeric value "${String(raw)}", using default ${fallback}` };
|
|
147
|
+
}
|
|
148
|
+
if (!raw.trim()) {
|
|
63
149
|
return { value: fallback };
|
|
64
150
|
}
|
|
65
151
|
const parsed = Number.parseInt(raw.trim(), 10);
|
|
@@ -116,8 +202,8 @@ export function discoverSubAgents(workspaceDir, availableModels) {
|
|
|
116
202
|
continue;
|
|
117
203
|
}
|
|
118
204
|
const { frontmatter, body } = parseFrontmatter(content);
|
|
119
|
-
const name = frontmatter.name
|
|
120
|
-
const description = frontmatter.description
|
|
205
|
+
const name = readOptionalTrimmedString(frontmatter.name);
|
|
206
|
+
const description = readOptionalTrimmedString(frontmatter.description);
|
|
121
207
|
if (!name || !description) {
|
|
122
208
|
warnings.push(`${entry.name}: missing required frontmatter fields "name" or "description"`);
|
|
123
209
|
continue;
|
|
@@ -131,6 +217,21 @@ export function discoverSubAgents(workspaceDir, availableModels) {
|
|
|
131
217
|
warnings.push(`${entry.name}: ${toolParse.error}`);
|
|
132
218
|
continue;
|
|
133
219
|
}
|
|
220
|
+
const contextMode = parseContextMode(frontmatter.contextMode);
|
|
221
|
+
if (contextMode.error) {
|
|
222
|
+
warnings.push(`${entry.name}: ${contextMode.error}`);
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
const memoryMode = parseMemoryMode(frontmatter.memory, contextMode.value);
|
|
226
|
+
if (memoryMode.error) {
|
|
227
|
+
warnings.push(`${entry.name}: ${memoryMode.error}`);
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
const parsedPaths = parseStringList(frontmatter.paths, "paths");
|
|
231
|
+
if (parsedPaths.error) {
|
|
232
|
+
warnings.push(`${entry.name}: ${parsedPaths.error}`);
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
134
235
|
const maxTurns = parsePositiveInteger(frontmatter.maxTurns, DEFAULT_MAX_TURNS);
|
|
135
236
|
const maxToolCalls = parsePositiveInteger(frontmatter.maxToolCalls, DEFAULT_MAX_TOOL_CALLS);
|
|
136
237
|
const maxWallTimeSec = parsePositiveInteger(frontmatter.maxWallTimeSec, DEFAULT_MAX_WALL_TIME_SEC);
|
|
@@ -140,7 +241,7 @@ export function discoverSubAgents(workspaceDir, availableModels) {
|
|
|
140
241
|
warnings.push(`${entry.name}: ${warning}`);
|
|
141
242
|
}
|
|
142
243
|
}
|
|
143
|
-
const modelRef = frontmatter.model
|
|
244
|
+
const modelRef = readOptionalTrimmedString(frontmatter.model);
|
|
144
245
|
let model;
|
|
145
246
|
if (modelRef) {
|
|
146
247
|
const resolved = resolveModelReference(modelRef, availableModels);
|
|
@@ -172,6 +273,9 @@ export function discoverSubAgents(workspaceDir, availableModels) {
|
|
|
172
273
|
maxToolCalls: maxToolCalls.value,
|
|
173
274
|
maxWallTimeSec: maxWallTimeSec.value,
|
|
174
275
|
bashTimeoutSec: bashTimeoutSec.value,
|
|
276
|
+
contextMode: contextMode.value,
|
|
277
|
+
memory: memoryMode.value,
|
|
278
|
+
paths: parsedPaths.values,
|
|
175
279
|
filePath,
|
|
176
280
|
source: "predefined",
|
|
177
281
|
});
|
|
@@ -207,6 +311,21 @@ export function resolveSubAgentConfig(availableModels, currentModel, predefinedA
|
|
|
207
311
|
const maxToolCalls = resolvePositiveOverride(overrides.maxToolCalls, baseConfig?.maxToolCalls ?? DEFAULT_MAX_TOOL_CALLS);
|
|
208
312
|
const maxWallTimeSec = resolvePositiveOverride(overrides.maxWallTimeSec, baseConfig?.maxWallTimeSec ?? DEFAULT_MAX_WALL_TIME_SEC);
|
|
209
313
|
const bashTimeoutSec = resolvePositiveOverride(overrides.bashTimeoutSec, baseConfig?.bashTimeoutSec ?? DEFAULT_BASH_TIMEOUT_SEC);
|
|
314
|
+
const contextModeOverride = overrides.contextMode ? parseContextMode(overrides.contextMode) : undefined;
|
|
315
|
+
if (contextModeOverride?.error) {
|
|
316
|
+
return { error: contextModeOverride.error };
|
|
317
|
+
}
|
|
318
|
+
const contextMode = contextModeOverride?.value ?? baseConfig?.contextMode ?? "isolated";
|
|
319
|
+
const memoryOverride = overrides.memory ? parseMemoryMode(overrides.memory, contextMode) : undefined;
|
|
320
|
+
if (memoryOverride?.error) {
|
|
321
|
+
return { error: memoryOverride.error };
|
|
322
|
+
}
|
|
323
|
+
const memory = memoryOverride?.value ?? baseConfig?.memory ?? (contextMode === "contextual" ? "relevant" : "none");
|
|
324
|
+
const pathsOverride = overrides.paths ? parseStringList(overrides.paths, "paths") : undefined;
|
|
325
|
+
if (pathsOverride?.error) {
|
|
326
|
+
return { error: pathsOverride.error };
|
|
327
|
+
}
|
|
328
|
+
const paths = pathsOverride?.values ?? baseConfig?.paths ?? [];
|
|
210
329
|
const systemPrompt = overrides.systemPrompt?.trim() || baseConfig?.systemPrompt || "";
|
|
211
330
|
if (!systemPrompt) {
|
|
212
331
|
return { error: "Sub-agent system prompt cannot be empty." };
|
|
@@ -229,6 +348,9 @@ export function resolveSubAgentConfig(availableModels, currentModel, predefinedA
|
|
|
229
348
|
maxToolCalls,
|
|
230
349
|
maxWallTimeSec,
|
|
231
350
|
bashTimeoutSec,
|
|
351
|
+
contextMode,
|
|
352
|
+
memory,
|
|
353
|
+
paths,
|
|
232
354
|
filePath: baseConfig?.filePath,
|
|
233
355
|
source: baseConfig ? "predefined" : "inline",
|
|
234
356
|
},
|
package/dist/sub-agents.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sub-agents.js","sourceRoot":"","sources":["../src/sub-agents.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEjE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,4BAA4B,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACtF,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,uBAAuB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAC3E,MAAM,uBAAuB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAU,CAAC;AAC1D,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAC7B,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAClC,MAAM,yBAAyB,GAAG,GAAG,CAAC;AACtC,MAAM,wBAAwB,GAAG,GAAG,CAAC;AACrC,MAAM,wBAAwB,GAAG,KAAK,CAAC;AACvC,MAAM,iCAAiC,GAAG,KAAK,CAAC;AA0ChD,SAAS,kBAAkB,CAAC,KAAa,EAAE,QAAgB,EAAE,KAAa,EAAsB;IAC/F,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,OAAO,GAAG,KAAK,YAAY,QAAQ,oBAAoB,KAAK,CAAC,MAAM,IAAI,CAAC;AAAA,CACxE;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAY,EAAsB;IACtE,OAAO,kBAAkB,CAAC,IAAI,EAAE,wBAAwB,EAAE,gBAAgB,CAAC,CAAC;AAAA,CAC5E;AAED,SAAS,4BAA4B,CAAC,YAAoB,EAAE,KAAa,EAAsB;IAC9F,OAAO,kBAAkB,CAAC,YAAY,EAAE,iCAAiC,EAAE,KAAK,CAAC,CAAC;AAAA,CAClF;AAED,MAAM,UAAU,eAAe,CAAC,YAAoB,EAAU;IAC7D,OAAO,IAAI,CAAC,YAAY,EAAE,mBAAmB,CAAC,CAAC;AAAA,CAC/C;AAED,SAAS,cAAc,CAAC,GAAuB,EAAiD;IAC/F,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;QACzB,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,uBAAuB,CAAC,EAAE,CAAC;IAChD,CAAC;IAED,MAAM,MAAM,GAAG,GAAG;SAChB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SAC5B,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEtC,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAAA,CACjC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAA4B,EAAiD;IAC9G,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,uBAAuB,CAAC,EAAE,CAAC;IAChD,CAAC;IAED,MAAM,KAAK,GAAuB,EAAE,CAAC;IACrC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YACzC,SAAS;QACV,CAAC;QACD,IAAI,CAAC,uBAAuB,CAAC,QAAQ,CAAC,UAA8B,CAAC,EAAE,CAAC;YACvE,OAAO;gBACN,KAAK,EAAE,EAAE;gBACT,KAAK,EAAE,iBAAiB,UAAU,qBAAqB,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;aAC3F,CAAC;QACH,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,UAA8B,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,uBAAuB,CAAC,EAAE,CAAC;AAAA,CAC1E;AAED,SAAS,oBAAoB,CAAC,GAAuB,EAAE,QAAgB,EAAuC;IAC7G,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;QACzB,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IAC5B,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAC/C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QAC7C,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,0BAA0B,GAAG,oBAAoB,QAAQ,EAAE,EAAE,CAAC;IAClG,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAAA,CACzB;AAED,SAAS,uBAAuB,CAAC,KAAyB,EAAE,QAAgB,EAAU;IACrF,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QAClE,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAAA,CACzB;AAED,SAAS,qBAAqB,CAC7B,QAAgB,EAChB,eAA6B,EACY;IACzC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,4BAA4B,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACrF,IAAI,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IACzB,CAAC;IACD,IAAI,SAAS,EAAE,CAAC;QACf,OAAO,EAAE,KAAK,EAAE,oBAAoB,QAAQ,uCAAuC,EAAE,CAAC;IACvF,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,oBAAoB,QAAQ,yCAAyC,EAAE,CAAC;AAAA,CACxF;AAED,MAAM,UAAU,iBAAiB,CAAC,YAAoB,EAAE,eAA6B,EAA2B;IAC/G,MAAM,SAAS,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC;IAChD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAChD,CAAC;IAED,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAqB,EAAE,CAAC;IACpC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,IAAI,OAAyB,CAAC;IAC9B,IAAI,CAAC;QACJ,OAAO,GAAG,WAAW,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;aACvD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC;aAC3F,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO;YACN,SAAS;YACT,MAAM,EAAE,EAAE;YACV,QAAQ,EAAE,CAAC,wCAAwC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;SAC7G,CAAC;IACH,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,OAAO,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC;YACJ,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,QAAQ,CAAC,IAAI,CACZ,GAAG,KAAK,CAAC,IAAI,0BAA0B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAChG,CAAC;YACF,SAAS;QACV,CAAC;QAED,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAyB,OAAO,CAAC,CAAC;QAChF,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;QACtC,MAAM,WAAW,GAAG,WAAW,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC;QAEpD,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAC3B,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,+DAA+D,CAAC,CAAC;YAC5F,SAAS;QACV,CAAC;QAED,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,+BAA+B,IAAI,WAAW,CAAC,CAAC;YAC3E,SAAS;QACV,CAAC;QAED,MAAM,SAAS,GAAG,cAAc,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACpD,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;YACrB,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC;YACnD,SAAS;QACV,CAAC;QAED,MAAM,QAAQ,GAAG,oBAAoB,CAAC,WAAW,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;QAC/E,MAAM,YAAY,GAAG,oBAAoB,CAAC,WAAW,CAAC,YAAY,EAAE,sBAAsB,CAAC,CAAC;QAC5F,MAAM,cAAc,GAAG,oBAAoB,CAAC,WAAW,CAAC,cAAc,EAAE,yBAAyB,CAAC,CAAC;QACnG,MAAM,cAAc,GAAG,oBAAoB,CAAC,WAAW,CAAC,cAAc,EAAE,wBAAwB,CAAC,CAAC;QAElG,KAAK,MAAM,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;YAChH,IAAI,OAAO,EAAE,CAAC;gBACb,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;YAC5C,CAAC;QACF,CAAC;QAED,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;QAC3C,IAAI,KAA6B,CAAC;QAClC,IAAI,QAAQ,EAAE,CAAC;YACd,MAAM,QAAQ,GAAG,qBAAqB,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;YAClE,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;gBACrB,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;gBAClD,SAAS;YACV,CAAC;YACD,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;QACxB,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,WAAW,EAAE,CAAC;YAClB,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,4BAA4B,CAAC,CAAC;YACzD,SAAS;QACV,CAAC;QACD,MAAM,iBAAiB,GAAG,4BAA4B,CAAC,WAAW,EAAE,yBAAyB,CAAC,CAAC;QAC/F,IAAI,iBAAiB,EAAE,CAAC;YACvB,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC,CAAC;YACrD,SAAS;QACV,CAAC;QAED,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpB,MAAM,CAAC,IAAI,CAAC;YACX,IAAI;YACJ,WAAW;YACX,YAAY,EAAE,WAAW;YACzB,KAAK,EAAE,SAAS,CAAC,KAAK;YACtB,KAAK;YACL,QAAQ,EAAE,QAAQ,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACvE,QAAQ,EAAE,QAAQ,CAAC,KAAK;YACxB,YAAY,EAAE,YAAY,CAAC,KAAK;YAChC,cAAc,EAAE,cAAc,CAAC,KAAK;YACpC,cAAc,EAAE,cAAc,CAAC,KAAK;YACpC,QAAQ;YACR,MAAM,EAAE,YAAY;SACpB,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAAA,CACvC;AAED,MAAM,UAAU,qBAAqB,CACpC,eAA6B,EAC7B,YAAwB,EACxB,gBAAkC,EAClC,SAAsC,EACgB;IACtD,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAClH,IAAI,SAAS,CAAC,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;QACpC,MAAM,SAAS,GAAG,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAChH,OAAO,EAAE,KAAK,EAAE,sBAAsB,SAAS,CAAC,KAAK,4BAA4B,SAAS,GAAG,EAAE,CAAC;IACjG,CAAC;IAED,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC,SAAS,CAAC,YAAY,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QAChF,OAAO,EAAE,KAAK,EAAE,mEAAmE,EAAE,CAAC;IACvF,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK;QAC5B,CAAC,CAAC,iBAAiB,CAAC,SAAS,CAAC,KAAK,CAAC;QACpC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,IAAI,CAAC,GAAG,uBAAuB,CAAC,EAAE,CAAC;IAChE,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;IAED,IAAI,KAAK,GAAG,UAAU,EAAE,KAAK,CAAC;IAC9B,IAAI,QAAQ,GAAG,UAAU,EAAE,QAAQ,CAAC;IACpC,IAAI,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,qBAAqB,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,eAAe,CAAC,CAAC;QAChF,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;YACrB,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,CAAC;QACD,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;QACvB,QAAQ,GAAG,oBAAoB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,QAAQ,GAAG,uBAAuB,CAAC,SAAS,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,IAAI,iBAAiB,CAAC,CAAC;IACxG,MAAM,YAAY,GAAG,uBAAuB,CAC3C,SAAS,CAAC,YAAY,EACtB,UAAU,EAAE,YAAY,IAAI,sBAAsB,CAClD,CAAC;IACF,MAAM,cAAc,GAAG,uBAAuB,CAC7C,SAAS,CAAC,cAAc,EACxB,UAAU,EAAE,cAAc,IAAI,yBAAyB,CACvD,CAAC;IACF,MAAM,cAAc,GAAG,uBAAuB,CAC7C,SAAS,CAAC,cAAc,EACxB,UAAU,EAAE,cAAc,IAAI,wBAAwB,CACtD,CAAC;IAEF,MAAM,YAAY,GAAG,SAAS,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,UAAU,EAAE,YAAY,IAAI,EAAE,CAAC;IACtF,IAAI,CAAC,YAAY,EAAE,CAAC;QACnB,OAAO,EAAE,KAAK,EAAE,0CAA0C,EAAE,CAAC;IAC9D,CAAC;IACD,IAAI,SAAS,CAAC,YAAY,EAAE,IAAI,EAAE,EAAE,CAAC;QACpC,MAAM,iBAAiB,GAAG,4BAA4B,CACrD,SAAS,CAAC,YAAY,CAAC,IAAI,EAAE,EAC7B,+BAA+B,CAC/B,CAAC;QACF,IAAI,iBAAiB,EAAE,CAAC;YACvB,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC;QACrC,CAAC;IACF,CAAC;IAED,OAAO;QACN,MAAM,EAAE;YACP,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,UAAU,EAAE,IAAI,IAAI,kBAAkB;YACtE,WAAW,EAAE,UAAU,EAAE,WAAW,IAAI,kBAAkB;YAC1D,YAAY;YACZ,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,KAAK,EAAE,KAAK,IAAI,YAAY;YAC5B,QAAQ,EAAE,QAAQ,IAAI,oBAAoB,CAAC,KAAK,IAAI,YAAY,CAAC;YACjE,QAAQ;YACR,YAAY;YACZ,cAAc;YACd,cAAc;YACd,QAAQ,EAAE,UAAU,EAAE,QAAQ;YAC9B,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ;SAC5C;KACD,CAAC;AAAA,CACF;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAwB,EAAE,QAAQ,GAAW,EAAE,EAAU;IAC3F,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC;IACf,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IACrG,IAAI,MAAM,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,MAAM,CAAC,MAAM,GAAG,QAAQ,OAAO,CAAC;AAAA,CAC1E","sourcesContent":["import type { Api, Model } from \"@mariozechner/pi-ai\";\nimport { parseFrontmatter } from \"@mariozechner/pi-coding-agent\";\nimport type { Dirent } from \"fs\";\nimport { existsSync, readdirSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { findExactModelReferenceMatch, formatModelReference } from \"./model-utils.js\";\nimport { SUB_AGENTS_DIR_NAME } from \"./paths.js\";\n\nconst ALLOWED_SUB_AGENT_TOOLS = [\"read\", \"bash\", \"edit\", \"write\"] as const;\nconst DEFAULT_SUB_AGENT_TOOLS = [\"read\", \"bash\"] as const;\nconst DEFAULT_MAX_TURNS = 24;\nconst DEFAULT_MAX_TOOL_CALLS = 48;\nconst DEFAULT_MAX_WALL_TIME_SEC = 300;\nconst DEFAULT_BASH_TIMEOUT_SEC = 120;\nconst MAX_SUB_AGENT_TASK_CHARS = 12000;\nconst MAX_SUB_AGENT_SYSTEM_PROMPT_CHARS = 16000;\n\nexport type SubAgentToolName = (typeof ALLOWED_SUB_AGENT_TOOLS)[number];\n\nexport interface SubAgentConfig {\n\tname: string;\n\tdescription: string;\n\tsystemPrompt: string;\n\ttools: SubAgentToolName[];\n\tmodel?: Model<Api>;\n\tmodelRef?: string;\n\tmaxTurns: number;\n\tmaxToolCalls: number;\n\tmaxWallTimeSec: number;\n\tbashTimeoutSec: number;\n\tfilePath?: string;\n\tsource: \"predefined\" | \"inline\";\n}\n\nexport interface ResolvedSubAgentConfig extends Omit<SubAgentConfig, \"model\" | \"modelRef\"> {\n\tmodel: Model<Api>;\n\tmodelRef: string;\n}\n\nexport interface SubAgentDiscoveryResult {\n\tdirectory: string;\n\tagents: SubAgentConfig[];\n\twarnings: string[];\n}\n\nexport interface SubAgentInvocationOverrides {\n\tagent?: string;\n\tname?: string;\n\tsystemPrompt?: string;\n\ttools?: string[];\n\tmodel?: string;\n\tmaxTurns?: number;\n\tmaxToolCalls?: number;\n\tmaxWallTimeSec?: number;\n\tbashTimeoutSec?: number;\n}\n\nfunction validateTextLength(value: string, maxChars: number, label: string): string | undefined {\n\tif (value.length <= maxChars) {\n\t\treturn undefined;\n\t}\n\treturn `${label} exceeds ${maxChars} characters (got ${value.length}).`;\n}\n\nexport function validateSubAgentTask(task: string): string | undefined {\n\treturn validateTextLength(task, MAX_SUB_AGENT_TASK_CHARS, \"Sub-agent task\");\n}\n\nfunction validateSubAgentSystemPrompt(systemPrompt: string, label: string): string | undefined {\n\treturn validateTextLength(systemPrompt, MAX_SUB_AGENT_SYSTEM_PROMPT_CHARS, label);\n}\n\nexport function getSubAgentsDir(workspaceDir: string): string {\n\treturn join(workspaceDir, SUB_AGENTS_DIR_NAME);\n}\n\nfunction parseToolNames(raw: string | undefined): { tools: SubAgentToolName[]; error?: string } {\n\tif (!raw || !raw.trim()) {\n\t\treturn { tools: [...DEFAULT_SUB_AGENT_TOOLS] };\n\t}\n\n\tconst values = raw\n\t\t.split(\",\")\n\t\t.map((value) => value.trim())\n\t\t.filter((value) => value.length > 0);\n\n\treturn validateToolNames(values);\n}\n\nexport function validateToolNames(values: string[] | undefined): { tools: SubAgentToolName[]; error?: string } {\n\tif (!values || values.length === 0) {\n\t\treturn { tools: [...DEFAULT_SUB_AGENT_TOOLS] };\n\t}\n\n\tconst tools: SubAgentToolName[] = [];\n\tconst seen = new Set<string>();\n\tfor (const value of values) {\n\t\tconst normalized = value.trim();\n\t\tif (!normalized || seen.has(normalized)) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (!ALLOWED_SUB_AGENT_TOOLS.includes(normalized as SubAgentToolName)) {\n\t\t\treturn {\n\t\t\t\ttools: [],\n\t\t\t\terror: `Unknown tool \"${normalized}\". Allowed tools: ${ALLOWED_SUB_AGENT_TOOLS.join(\", \")}`,\n\t\t\t};\n\t\t}\n\t\tseen.add(normalized);\n\t\ttools.push(normalized as SubAgentToolName);\n\t}\n\n\treturn { tools: tools.length > 0 ? tools : [...DEFAULT_SUB_AGENT_TOOLS] };\n}\n\nfunction parsePositiveInteger(raw: string | undefined, fallback: number): { value: number; warning?: string } {\n\tif (!raw || !raw.trim()) {\n\t\treturn { value: fallback };\n\t}\n\n\tconst parsed = Number.parseInt(raw.trim(), 10);\n\tif (!Number.isFinite(parsed) || parsed <= 0) {\n\t\treturn { value: fallback, warning: `Invalid numeric value \"${raw}\", using default ${fallback}` };\n\t}\n\n\treturn { value: parsed };\n}\n\nfunction resolvePositiveOverride(value: number | undefined, fallback: number): number {\n\tif (!Number.isFinite(value) || value === undefined || value <= 0) {\n\t\treturn fallback;\n\t}\n\treturn Math.floor(value);\n}\n\nfunction resolveModelReference(\n\tmodelRef: string,\n\tavailableModels: Model<Api>[],\n): { model?: Model<Api>; error?: string } {\n\tconst { match, ambiguous } = findExactModelReferenceMatch(modelRef, availableModels);\n\tif (match) {\n\t\treturn { model: match };\n\t}\n\tif (ambiguous) {\n\t\treturn { error: `Model reference \"${modelRef}\" is ambiguous. Use provider/modelId.` };\n\t}\n\treturn { error: `Model reference \"${modelRef}\" was not found among available models.` };\n}\n\nexport function discoverSubAgents(workspaceDir: string, availableModels: Model<Api>[]): SubAgentDiscoveryResult {\n\tconst directory = getSubAgentsDir(workspaceDir);\n\tif (!existsSync(directory)) {\n\t\treturn { directory, agents: [], warnings: [] };\n\t}\n\n\tconst warnings: string[] = [];\n\tconst agents: SubAgentConfig[] = [];\n\tconst seenNames = new Set<string>();\n\tlet entries: Dirent<string>[];\n\ttry {\n\t\tentries = readdirSync(directory, { withFileTypes: true })\n\t\t\t.filter((entry) => entry.name.endsWith(\".md\") && (entry.isFile() || entry.isSymbolicLink()))\n\t\t\t.sort((a, b) => a.name.localeCompare(b.name));\n\t} catch (error) {\n\t\treturn {\n\t\t\tdirectory,\n\t\t\tagents: [],\n\t\t\twarnings: [`Failed to read sub-agents directory (${error instanceof Error ? error.message : String(error)})`],\n\t\t};\n\t}\n\n\tfor (const entry of entries) {\n\t\tconst filePath = join(directory, entry.name);\n\t\tlet content = \"\";\n\t\ttry {\n\t\t\tcontent = readFileSync(filePath, \"utf-8\");\n\t\t} catch (error) {\n\t\t\twarnings.push(\n\t\t\t\t`${entry.name}: failed to read file (${error instanceof Error ? error.message : String(error)})`,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst { frontmatter, body } = parseFrontmatter<Record<string, string>>(content);\n\t\tconst name = frontmatter.name?.trim();\n\t\tconst description = frontmatter.description?.trim();\n\n\t\tif (!name || !description) {\n\t\t\twarnings.push(`${entry.name}: missing required frontmatter fields \"name\" or \"description\"`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (seenNames.has(name)) {\n\t\t\twarnings.push(`${entry.name}: duplicate sub-agent name \"${name}\" ignored`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst toolParse = parseToolNames(frontmatter.tools);\n\t\tif (toolParse.error) {\n\t\t\twarnings.push(`${entry.name}: ${toolParse.error}`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst maxTurns = parsePositiveInteger(frontmatter.maxTurns, DEFAULT_MAX_TURNS);\n\t\tconst maxToolCalls = parsePositiveInteger(frontmatter.maxToolCalls, DEFAULT_MAX_TOOL_CALLS);\n\t\tconst maxWallTimeSec = parsePositiveInteger(frontmatter.maxWallTimeSec, DEFAULT_MAX_WALL_TIME_SEC);\n\t\tconst bashTimeoutSec = parsePositiveInteger(frontmatter.bashTimeoutSec, DEFAULT_BASH_TIMEOUT_SEC);\n\n\t\tfor (const warning of [maxTurns.warning, maxToolCalls.warning, maxWallTimeSec.warning, bashTimeoutSec.warning]) {\n\t\t\tif (warning) {\n\t\t\t\twarnings.push(`${entry.name}: ${warning}`);\n\t\t\t}\n\t\t}\n\n\t\tconst modelRef = frontmatter.model?.trim();\n\t\tlet model: Model<Api> | undefined;\n\t\tif (modelRef) {\n\t\t\tconst resolved = resolveModelReference(modelRef, availableModels);\n\t\t\tif (!resolved.model) {\n\t\t\t\twarnings.push(`${entry.name}: ${resolved.error}`);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tmodel = resolved.model;\n\t\t}\n\n\t\tconst trimmedBody = body.trim();\n\t\tif (!trimmedBody) {\n\t\t\twarnings.push(`${entry.name}: empty system prompt body`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst promptLengthError = validateSubAgentSystemPrompt(trimmedBody, \"Sub-agent system prompt\");\n\t\tif (promptLengthError) {\n\t\t\twarnings.push(`${entry.name}: ${promptLengthError}`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tseenNames.add(name);\n\t\tagents.push({\n\t\t\tname,\n\t\t\tdescription,\n\t\t\tsystemPrompt: trimmedBody,\n\t\t\ttools: toolParse.tools,\n\t\t\tmodel,\n\t\t\tmodelRef: modelRef || (model ? formatModelReference(model) : undefined),\n\t\t\tmaxTurns: maxTurns.value,\n\t\t\tmaxToolCalls: maxToolCalls.value,\n\t\t\tmaxWallTimeSec: maxWallTimeSec.value,\n\t\t\tbashTimeoutSec: bashTimeoutSec.value,\n\t\t\tfilePath,\n\t\t\tsource: \"predefined\",\n\t\t});\n\t}\n\n\treturn { directory, agents, warnings };\n}\n\nexport function resolveSubAgentConfig(\n\tavailableModels: Model<Api>[],\n\tcurrentModel: Model<Api>,\n\tpredefinedAgents: SubAgentConfig[],\n\toverrides: SubAgentInvocationOverrides,\n): { config?: ResolvedSubAgentConfig; error?: string } {\n\tconst baseConfig = overrides.agent ? predefinedAgents.find((agent) => agent.name === overrides.agent) : undefined;\n\tif (overrides.agent && !baseConfig) {\n\t\tconst available = predefinedAgents.length > 0 ? predefinedAgents.map((agent) => agent.name).join(\", \") : \"none\";\n\t\treturn { error: `Unknown sub-agent \"${overrides.agent}\". Available sub-agents: ${available}.` };\n\t}\n\n\tif (!baseConfig && (!overrides.systemPrompt || !overrides.systemPrompt.trim())) {\n\t\treturn { error: 'Provide either \"agent\" or \"systemPrompt\" to define the sub-agent.' };\n\t}\n\n\tconst tools = overrides.tools\n\t\t? validateToolNames(overrides.tools)\n\t\t: { tools: baseConfig?.tools ?? [...DEFAULT_SUB_AGENT_TOOLS] };\n\tif (tools.error) {\n\t\treturn { error: tools.error };\n\t}\n\n\tlet model = baseConfig?.model;\n\tlet modelRef = baseConfig?.modelRef;\n\tif (overrides.model?.trim()) {\n\t\tconst resolved = resolveModelReference(overrides.model.trim(), availableModels);\n\t\tif (!resolved.model) {\n\t\t\treturn { error: resolved.error };\n\t\t}\n\t\tmodel = resolved.model;\n\t\tmodelRef = formatModelReference(resolved.model);\n\t}\n\n\tconst maxTurns = resolvePositiveOverride(overrides.maxTurns, baseConfig?.maxTurns ?? DEFAULT_MAX_TURNS);\n\tconst maxToolCalls = resolvePositiveOverride(\n\t\toverrides.maxToolCalls,\n\t\tbaseConfig?.maxToolCalls ?? DEFAULT_MAX_TOOL_CALLS,\n\t);\n\tconst maxWallTimeSec = resolvePositiveOverride(\n\t\toverrides.maxWallTimeSec,\n\t\tbaseConfig?.maxWallTimeSec ?? DEFAULT_MAX_WALL_TIME_SEC,\n\t);\n\tconst bashTimeoutSec = resolvePositiveOverride(\n\t\toverrides.bashTimeoutSec,\n\t\tbaseConfig?.bashTimeoutSec ?? DEFAULT_BASH_TIMEOUT_SEC,\n\t);\n\n\tconst systemPrompt = overrides.systemPrompt?.trim() || baseConfig?.systemPrompt || \"\";\n\tif (!systemPrompt) {\n\t\treturn { error: \"Sub-agent system prompt cannot be empty.\" };\n\t}\n\tif (overrides.systemPrompt?.trim()) {\n\t\tconst promptLengthError = validateSubAgentSystemPrompt(\n\t\t\toverrides.systemPrompt.trim(),\n\t\t\t\"Inline sub-agent systemPrompt\",\n\t\t);\n\t\tif (promptLengthError) {\n\t\t\treturn { error: promptLengthError };\n\t\t}\n\t}\n\n\treturn {\n\t\tconfig: {\n\t\t\tname: overrides.name?.trim() || baseConfig?.name || \"dynamic-subagent\",\n\t\t\tdescription: baseConfig?.description || \"Inline sub-agent\",\n\t\t\tsystemPrompt,\n\t\t\ttools: tools.tools,\n\t\t\tmodel: model ?? currentModel,\n\t\t\tmodelRef: modelRef ?? formatModelReference(model ?? currentModel),\n\t\t\tmaxTurns,\n\t\t\tmaxToolCalls,\n\t\t\tmaxWallTimeSec,\n\t\t\tbashTimeoutSec,\n\t\t\tfilePath: baseConfig?.filePath,\n\t\t\tsource: baseConfig ? \"predefined\" : \"inline\",\n\t\t},\n\t};\n}\n\nexport function formatSubAgentList(agents: SubAgentConfig[], maxItems: number = 12): string {\n\tif (agents.length === 0) {\n\t\treturn \"none\";\n\t}\n\n\tconst listed = agents.slice(0, maxItems).map((agent) => `- \\`${agent.name}\\`: ${agent.description}`);\n\tif (agents.length <= maxItems) {\n\t\treturn listed.join(\"\\n\");\n\t}\n\n\treturn `${listed.join(\"\\n\")}\\n- ... and ${agents.length - maxItems} more`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sub-agents.js","sourceRoot":"","sources":["../src/sub-agents.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api, Model } from \"@mariozechner/pi-ai\";\nimport { parseFrontmatter } from \"@mariozechner/pi-coding-agent\";\nimport type { Dirent } from \"fs\";\nimport { existsSync, readdirSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { findExactModelReferenceMatch, formatModelReference } from \"./model-utils.js\";\nimport { SUB_AGENTS_DIR_NAME } from \"./paths.js\";\n\nconst ALLOWED_SUB_AGENT_TOOLS = [\"read\", \"bash\", \"edit\", \"write\"] as const;\nconst DEFAULT_SUB_AGENT_TOOLS = [\"read\", \"bash\"] as const;\nconst DEFAULT_MAX_TURNS = 24;\nconst DEFAULT_MAX_TOOL_CALLS = 48;\nconst DEFAULT_MAX_WALL_TIME_SEC = 300;\nconst DEFAULT_BASH_TIMEOUT_SEC = 120;\nconst MAX_SUB_AGENT_TASK_CHARS = 12000;\nconst MAX_SUB_AGENT_SYSTEM_PROMPT_CHARS = 16000;\nconst ALLOWED_CONTEXT_MODES = [\"isolated\", \"contextual\"] as const;\nconst ALLOWED_MEMORY_MODES = [\"none\", \"session\", \"relevant\"] as const;\n\nexport type SubAgentToolName = (typeof ALLOWED_SUB_AGENT_TOOLS)[number];\nexport type SubAgentContextMode = (typeof ALLOWED_CONTEXT_MODES)[number];\nexport type SubAgentMemoryMode = (typeof ALLOWED_MEMORY_MODES)[number];\n\nexport interface SubAgentConfig {\n\tname: string;\n\tdescription: string;\n\tsystemPrompt: string;\n\ttools: SubAgentToolName[];\n\tmodel?: Model<Api>;\n\tmodelRef?: string;\n\tmaxTurns: number;\n\tmaxToolCalls: number;\n\tmaxWallTimeSec: number;\n\tbashTimeoutSec: number;\n\tcontextMode: SubAgentContextMode;\n\tmemory: SubAgentMemoryMode;\n\tpaths: string[];\n\tfilePath?: string;\n\tsource: \"predefined\" | \"inline\";\n}\n\nexport interface ResolvedSubAgentConfig extends Omit<SubAgentConfig, \"model\" | \"modelRef\"> {\n\tmodel: Model<Api>;\n\tmodelRef: string;\n}\n\nexport interface SubAgentDiscoveryResult {\n\tdirectory: string;\n\tagents: SubAgentConfig[];\n\twarnings: string[];\n}\n\nexport interface SubAgentInvocationOverrides {\n\tagent?: string;\n\tname?: string;\n\tsystemPrompt?: string;\n\ttools?: string[];\n\tmodel?: string;\n\tmaxTurns?: number;\n\tmaxToolCalls?: number;\n\tmaxWallTimeSec?: number;\n\tbashTimeoutSec?: number;\n\tcontextMode?: string;\n\tmemory?: string;\n\tpaths?: string[];\n}\n\nfunction validateTextLength(value: string, maxChars: number, label: string): string | undefined {\n\tif (value.length <= maxChars) {\n\t\treturn undefined;\n\t}\n\treturn `${label} exceeds ${maxChars} characters (got ${value.length}).`;\n}\n\nexport function validateSubAgentTask(task: string): string | undefined {\n\treturn validateTextLength(task, MAX_SUB_AGENT_TASK_CHARS, \"Sub-agent task\");\n}\n\nfunction validateSubAgentSystemPrompt(systemPrompt: string, label: string): string | undefined {\n\treturn validateTextLength(systemPrompt, MAX_SUB_AGENT_SYSTEM_PROMPT_CHARS, label);\n}\n\nexport function getSubAgentsDir(workspaceDir: string): string {\n\treturn join(workspaceDir, SUB_AGENTS_DIR_NAME);\n}\n\nfunction readOptionalTrimmedString(value: unknown): string | undefined {\n\tif (typeof value !== \"string\") {\n\t\treturn undefined;\n\t}\n\n\tconst trimmed = value.trim();\n\treturn trimmed ? trimmed : undefined;\n}\n\nfunction parseToolNames(raw: unknown): { tools: SubAgentToolName[]; error?: string } {\n\tif (raw === undefined || raw === null) {\n\t\treturn { tools: [...DEFAULT_SUB_AGENT_TOOLS] };\n\t}\n\n\tif (typeof raw === \"string\") {\n\t\tif (!raw.trim()) {\n\t\t\treturn { tools: [...DEFAULT_SUB_AGENT_TOOLS] };\n\t\t}\n\n\t\tconst values = raw\n\t\t\t.split(\",\")\n\t\t\t.map((value) => value.trim())\n\t\t\t.filter((value) => value.length > 0);\n\n\t\treturn validateToolNames(values);\n\t}\n\n\tif (Array.isArray(raw)) {\n\t\tconst invalidValue = raw.find((value) => typeof value !== \"string\");\n\t\tif (invalidValue !== undefined) {\n\t\t\treturn { tools: [], error: 'Invalid \"tools\" frontmatter: expected a string or string[]' };\n\t\t}\n\t\treturn validateToolNames(raw);\n\t}\n\n\treturn { tools: [], error: 'Invalid \"tools\" frontmatter: expected a string or string[]' };\n}\n\nfunction parseStringList(raw: unknown, label: string): { values: string[]; error?: string } {\n\tif (raw === undefined || raw === null) {\n\t\treturn { values: [] };\n\t}\n\n\tif (typeof raw === \"string\") {\n\t\tif (!raw.trim()) {\n\t\t\treturn { values: [] };\n\t\t}\n\n\t\treturn {\n\t\t\tvalues: Array.from(\n\t\t\t\tnew Set(\n\t\t\t\t\traw\n\t\t\t\t\t\t.split(\",\")\n\t\t\t\t\t\t.map((value) => value.trim())\n\t\t\t\t\t\t.filter((value) => value.length > 0),\n\t\t\t\t),\n\t\t\t),\n\t\t};\n\t}\n\n\tif (Array.isArray(raw)) {\n\t\tconst invalidValue = raw.find((value) => typeof value !== \"string\");\n\t\tif (invalidValue !== undefined) {\n\t\t\treturn { values: [], error: `Invalid \"${label}\" frontmatter: expected a string or string[]` };\n\t\t}\n\n\t\treturn {\n\t\t\tvalues: Array.from(new Set(raw.map((value) => value.trim()).filter((value) => value.length > 0))),\n\t\t};\n\t}\n\n\treturn { values: [], error: `Invalid \"${label}\" frontmatter: expected a string or string[]` };\n}\n\nfunction parseContextMode(raw: unknown): { value: SubAgentContextMode; error?: string } {\n\tconst normalized = readOptionalTrimmedString(raw);\n\tif (!normalized) {\n\t\treturn { value: \"isolated\" };\n\t}\n\tif (ALLOWED_CONTEXT_MODES.includes(normalized as SubAgentContextMode)) {\n\t\treturn { value: normalized as SubAgentContextMode };\n\t}\n\treturn {\n\t\tvalue: \"isolated\",\n\t\terror: `Unknown contextMode \"${normalized}\". Allowed values: ${ALLOWED_CONTEXT_MODES.join(\", \")}`,\n\t};\n}\n\nfunction parseMemoryMode(\n\traw: unknown,\n\tcontextMode: SubAgentContextMode,\n): { value: SubAgentMemoryMode; error?: string } {\n\tconst normalized = readOptionalTrimmedString(raw);\n\tif (!normalized) {\n\t\treturn { value: contextMode === \"contextual\" ? \"relevant\" : \"none\" };\n\t}\n\tif (ALLOWED_MEMORY_MODES.includes(normalized as SubAgentMemoryMode)) {\n\t\treturn { value: normalized as SubAgentMemoryMode };\n\t}\n\treturn {\n\t\tvalue: contextMode === \"contextual\" ? \"relevant\" : \"none\",\n\t\terror: `Unknown memory \"${normalized}\". Allowed values: ${ALLOWED_MEMORY_MODES.join(\", \")}`,\n\t};\n}\n\nexport function validateToolNames(values: string[] | undefined): { tools: SubAgentToolName[]; error?: string } {\n\tif (!values || values.length === 0) {\n\t\treturn { tools: [...DEFAULT_SUB_AGENT_TOOLS] };\n\t}\n\n\tconst tools: SubAgentToolName[] = [];\n\tconst seen = new Set<string>();\n\tfor (const value of values) {\n\t\tconst normalized = value.trim();\n\t\tif (!normalized || seen.has(normalized)) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (!ALLOWED_SUB_AGENT_TOOLS.includes(normalized as SubAgentToolName)) {\n\t\t\treturn {\n\t\t\t\ttools: [],\n\t\t\t\terror: `Unknown tool \"${normalized}\". Allowed tools: ${ALLOWED_SUB_AGENT_TOOLS.join(\", \")}`,\n\t\t\t};\n\t\t}\n\t\tseen.add(normalized);\n\t\ttools.push(normalized as SubAgentToolName);\n\t}\n\n\treturn { tools: tools.length > 0 ? tools : [...DEFAULT_SUB_AGENT_TOOLS] };\n}\n\nfunction parsePositiveInteger(raw: unknown, fallback: number): { value: number; warning?: string } {\n\tif (raw === undefined || raw === null) {\n\t\treturn { value: fallback };\n\t}\n\n\tif (typeof raw === \"number\") {\n\t\tif (!Number.isFinite(raw) || raw <= 0) {\n\t\t\treturn { value: fallback, warning: `Invalid numeric value \"${String(raw)}\", using default ${fallback}` };\n\t\t}\n\t\treturn { value: Math.floor(raw) };\n\t}\n\n\tif (typeof raw !== \"string\") {\n\t\treturn { value: fallback, warning: `Invalid numeric value \"${String(raw)}\", using default ${fallback}` };\n\t}\n\n\tif (!raw.trim()) {\n\t\treturn { value: fallback };\n\t}\n\n\tconst parsed = Number.parseInt(raw.trim(), 10);\n\tif (!Number.isFinite(parsed) || parsed <= 0) {\n\t\treturn { value: fallback, warning: `Invalid numeric value \"${raw}\", using default ${fallback}` };\n\t}\n\n\treturn { value: parsed };\n}\n\nfunction resolvePositiveOverride(value: number | undefined, fallback: number): number {\n\tif (!Number.isFinite(value) || value === undefined || value <= 0) {\n\t\treturn fallback;\n\t}\n\treturn Math.floor(value);\n}\n\nfunction resolveModelReference(\n\tmodelRef: string,\n\tavailableModels: Model<Api>[],\n): { model?: Model<Api>; error?: string } {\n\tconst { match, ambiguous } = findExactModelReferenceMatch(modelRef, availableModels);\n\tif (match) {\n\t\treturn { model: match };\n\t}\n\tif (ambiguous) {\n\t\treturn { error: `Model reference \"${modelRef}\" is ambiguous. Use provider/modelId.` };\n\t}\n\treturn { error: `Model reference \"${modelRef}\" was not found among available models.` };\n}\n\nexport function discoverSubAgents(workspaceDir: string, availableModels: Model<Api>[]): SubAgentDiscoveryResult {\n\tconst directory = getSubAgentsDir(workspaceDir);\n\tif (!existsSync(directory)) {\n\t\treturn { directory, agents: [], warnings: [] };\n\t}\n\n\tconst warnings: string[] = [];\n\tconst agents: SubAgentConfig[] = [];\n\tconst seenNames = new Set<string>();\n\tlet entries: Dirent<string>[];\n\ttry {\n\t\tentries = readdirSync(directory, { withFileTypes: true })\n\t\t\t.filter((entry) => entry.name.endsWith(\".md\") && (entry.isFile() || entry.isSymbolicLink()))\n\t\t\t.sort((a, b) => a.name.localeCompare(b.name));\n\t} catch (error) {\n\t\treturn {\n\t\t\tdirectory,\n\t\t\tagents: [],\n\t\t\twarnings: [`Failed to read sub-agents directory (${error instanceof Error ? error.message : String(error)})`],\n\t\t};\n\t}\n\n\tfor (const entry of entries) {\n\t\tconst filePath = join(directory, entry.name);\n\t\tlet content = \"\";\n\t\ttry {\n\t\t\tcontent = readFileSync(filePath, \"utf-8\");\n\t\t} catch (error) {\n\t\t\twarnings.push(\n\t\t\t\t`${entry.name}: failed to read file (${error instanceof Error ? error.message : String(error)})`,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst { frontmatter, body } = parseFrontmatter<Record<string, unknown>>(content);\n\t\tconst name = readOptionalTrimmedString(frontmatter.name);\n\t\tconst description = readOptionalTrimmedString(frontmatter.description);\n\n\t\tif (!name || !description) {\n\t\t\twarnings.push(`${entry.name}: missing required frontmatter fields \"name\" or \"description\"`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (seenNames.has(name)) {\n\t\t\twarnings.push(`${entry.name}: duplicate sub-agent name \"${name}\" ignored`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst toolParse = parseToolNames(frontmatter.tools);\n\t\tif (toolParse.error) {\n\t\t\twarnings.push(`${entry.name}: ${toolParse.error}`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst contextMode = parseContextMode(frontmatter.contextMode);\n\t\tif (contextMode.error) {\n\t\t\twarnings.push(`${entry.name}: ${contextMode.error}`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst memoryMode = parseMemoryMode(frontmatter.memory, contextMode.value);\n\t\tif (memoryMode.error) {\n\t\t\twarnings.push(`${entry.name}: ${memoryMode.error}`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst parsedPaths = parseStringList(frontmatter.paths, \"paths\");\n\t\tif (parsedPaths.error) {\n\t\t\twarnings.push(`${entry.name}: ${parsedPaths.error}`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst maxTurns = parsePositiveInteger(frontmatter.maxTurns, DEFAULT_MAX_TURNS);\n\t\tconst maxToolCalls = parsePositiveInteger(frontmatter.maxToolCalls, DEFAULT_MAX_TOOL_CALLS);\n\t\tconst maxWallTimeSec = parsePositiveInteger(frontmatter.maxWallTimeSec, DEFAULT_MAX_WALL_TIME_SEC);\n\t\tconst bashTimeoutSec = parsePositiveInteger(frontmatter.bashTimeoutSec, DEFAULT_BASH_TIMEOUT_SEC);\n\n\t\tfor (const warning of [maxTurns.warning, maxToolCalls.warning, maxWallTimeSec.warning, bashTimeoutSec.warning]) {\n\t\t\tif (warning) {\n\t\t\t\twarnings.push(`${entry.name}: ${warning}`);\n\t\t\t}\n\t\t}\n\n\t\tconst modelRef = readOptionalTrimmedString(frontmatter.model);\n\t\tlet model: Model<Api> | undefined;\n\t\tif (modelRef) {\n\t\t\tconst resolved = resolveModelReference(modelRef, availableModels);\n\t\t\tif (!resolved.model) {\n\t\t\t\twarnings.push(`${entry.name}: ${resolved.error}`);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tmodel = resolved.model;\n\t\t}\n\n\t\tconst trimmedBody = body.trim();\n\t\tif (!trimmedBody) {\n\t\t\twarnings.push(`${entry.name}: empty system prompt body`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst promptLengthError = validateSubAgentSystemPrompt(trimmedBody, \"Sub-agent system prompt\");\n\t\tif (promptLengthError) {\n\t\t\twarnings.push(`${entry.name}: ${promptLengthError}`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tseenNames.add(name);\n\t\tagents.push({\n\t\t\tname,\n\t\t\tdescription,\n\t\t\tsystemPrompt: trimmedBody,\n\t\t\ttools: toolParse.tools,\n\t\t\tmodel,\n\t\t\tmodelRef: modelRef || (model ? formatModelReference(model) : undefined),\n\t\t\tmaxTurns: maxTurns.value,\n\t\t\tmaxToolCalls: maxToolCalls.value,\n\t\t\tmaxWallTimeSec: maxWallTimeSec.value,\n\t\t\tbashTimeoutSec: bashTimeoutSec.value,\n\t\t\tcontextMode: contextMode.value,\n\t\t\tmemory: memoryMode.value,\n\t\t\tpaths: parsedPaths.values,\n\t\t\tfilePath,\n\t\t\tsource: \"predefined\",\n\t\t});\n\t}\n\n\treturn { directory, agents, warnings };\n}\n\nexport function resolveSubAgentConfig(\n\tavailableModels: Model<Api>[],\n\tcurrentModel: Model<Api>,\n\tpredefinedAgents: SubAgentConfig[],\n\toverrides: SubAgentInvocationOverrides,\n): { config?: ResolvedSubAgentConfig; error?: string } {\n\tconst baseConfig = overrides.agent ? predefinedAgents.find((agent) => agent.name === overrides.agent) : undefined;\n\tif (overrides.agent && !baseConfig) {\n\t\tconst available = predefinedAgents.length > 0 ? predefinedAgents.map((agent) => agent.name).join(\", \") : \"none\";\n\t\treturn { error: `Unknown sub-agent \"${overrides.agent}\". Available sub-agents: ${available}.` };\n\t}\n\n\tif (!baseConfig && (!overrides.systemPrompt || !overrides.systemPrompt.trim())) {\n\t\treturn { error: 'Provide either \"agent\" or \"systemPrompt\" to define the sub-agent.' };\n\t}\n\n\tconst tools = overrides.tools\n\t\t? validateToolNames(overrides.tools)\n\t\t: { tools: baseConfig?.tools ?? [...DEFAULT_SUB_AGENT_TOOLS] };\n\tif (tools.error) {\n\t\treturn { error: tools.error };\n\t}\n\n\tlet model = baseConfig?.model;\n\tlet modelRef = baseConfig?.modelRef;\n\tif (overrides.model?.trim()) {\n\t\tconst resolved = resolveModelReference(overrides.model.trim(), availableModels);\n\t\tif (!resolved.model) {\n\t\t\treturn { error: resolved.error };\n\t\t}\n\t\tmodel = resolved.model;\n\t\tmodelRef = formatModelReference(resolved.model);\n\t}\n\n\tconst maxTurns = resolvePositiveOverride(overrides.maxTurns, baseConfig?.maxTurns ?? DEFAULT_MAX_TURNS);\n\tconst maxToolCalls = resolvePositiveOverride(\n\t\toverrides.maxToolCalls,\n\t\tbaseConfig?.maxToolCalls ?? DEFAULT_MAX_TOOL_CALLS,\n\t);\n\tconst maxWallTimeSec = resolvePositiveOverride(\n\t\toverrides.maxWallTimeSec,\n\t\tbaseConfig?.maxWallTimeSec ?? DEFAULT_MAX_WALL_TIME_SEC,\n\t);\n\tconst bashTimeoutSec = resolvePositiveOverride(\n\t\toverrides.bashTimeoutSec,\n\t\tbaseConfig?.bashTimeoutSec ?? DEFAULT_BASH_TIMEOUT_SEC,\n\t);\n\tconst contextModeOverride = overrides.contextMode ? parseContextMode(overrides.contextMode) : undefined;\n\tif (contextModeOverride?.error) {\n\t\treturn { error: contextModeOverride.error };\n\t}\n\tconst contextMode = contextModeOverride?.value ?? baseConfig?.contextMode ?? \"isolated\";\n\n\tconst memoryOverride = overrides.memory ? parseMemoryMode(overrides.memory, contextMode) : undefined;\n\tif (memoryOverride?.error) {\n\t\treturn { error: memoryOverride.error };\n\t}\n\tconst memory = memoryOverride?.value ?? baseConfig?.memory ?? (contextMode === \"contextual\" ? \"relevant\" : \"none\");\n\n\tconst pathsOverride = overrides.paths ? parseStringList(overrides.paths, \"paths\") : undefined;\n\tif (pathsOverride?.error) {\n\t\treturn { error: pathsOverride.error };\n\t}\n\tconst paths = pathsOverride?.values ?? baseConfig?.paths ?? [];\n\n\tconst systemPrompt = overrides.systemPrompt?.trim() || baseConfig?.systemPrompt || \"\";\n\tif (!systemPrompt) {\n\t\treturn { error: \"Sub-agent system prompt cannot be empty.\" };\n\t}\n\tif (overrides.systemPrompt?.trim()) {\n\t\tconst promptLengthError = validateSubAgentSystemPrompt(\n\t\t\toverrides.systemPrompt.trim(),\n\t\t\t\"Inline sub-agent systemPrompt\",\n\t\t);\n\t\tif (promptLengthError) {\n\t\t\treturn { error: promptLengthError };\n\t\t}\n\t}\n\n\treturn {\n\t\tconfig: {\n\t\t\tname: overrides.name?.trim() || baseConfig?.name || \"dynamic-subagent\",\n\t\t\tdescription: baseConfig?.description || \"Inline sub-agent\",\n\t\t\tsystemPrompt,\n\t\t\ttools: tools.tools,\n\t\t\tmodel: model ?? currentModel,\n\t\t\tmodelRef: modelRef ?? formatModelReference(model ?? currentModel),\n\t\t\tmaxTurns,\n\t\t\tmaxToolCalls,\n\t\t\tmaxWallTimeSec,\n\t\t\tbashTimeoutSec,\n\t\t\tcontextMode,\n\t\t\tmemory,\n\t\t\tpaths,\n\t\t\tfilePath: baseConfig?.filePath,\n\t\t\tsource: baseConfig ? \"predefined\" : \"inline\",\n\t\t},\n\t};\n}\n\nexport function formatSubAgentList(agents: SubAgentConfig[], maxItems: number = 12): string {\n\tif (agents.length === 0) {\n\t\treturn \"none\";\n\t}\n\n\tconst listed = agents.slice(0, maxItems).map((agent) => `- \\`${agent.name}\\`: ${agent.description}`);\n\tif (agents.length <= maxItems) {\n\t\treturn listed.join(\"\\n\");\n\t}\n\n\treturn `${listed.join(\"\\n\")}\\n- ... and ${agents.length - maxItems} more`;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attach.d.ts","sourceRoot":"","sources":["../../src/tools/attach.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAI7D,QAAA,MAAM,YAAY;;;;EAIhB,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEjF;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC,OAAO,YAAY,CAAC,CAiC1F"
|
|
1
|
+
{"version":3,"file":"attach.d.ts","sourceRoot":"","sources":["../../src/tools/attach.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAI7D,QAAA,MAAM,YAAY;;;;EAIhB,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEjF;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC,OAAO,YAAY,CAAC,CAiC1F"}
|
package/dist/tools/attach.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attach.js","sourceRoot":"","sources":["../../src/tools/attach.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,MAAM,CAAC;AAExD,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC;IAChC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,0DAA0D,EAAE,CAAC;IAC/F,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,4BAA4B,EAAE,CAAC;IAChE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,2CAA2C,EAAE,CAAC,CAAC;CAC/F,CAAC,CAAC;AAIH;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAyB
|
|
1
|
+
{"version":3,"file":"attach.js","sourceRoot":"","sources":["../../src/tools/attach.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,MAAM,CAAC;AAExD,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC;IAChC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,0DAA0D,EAAE,CAAC;IAC/F,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,4BAA4B,EAAE,CAAC;IAChE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,2CAA2C,EAAE,CAAC,CAAC;CAC/F,CAAC,CAAC;AAIH;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAyB;IACzD,OAAO;QACN,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,QAAQ;QACf,WAAW,EACV,2IAA2I;QAC5I,UAAU,EAAE,YAAY;QACxB,OAAO,EAAE,KAAK,EACb,WAAmB,EACnB,EAAE,IAAI,EAAE,KAAK,EAAmD,EAChE,MAAoB,EACnB,EAAE;YACH,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CACd,gHAAgH,CAChH,CAAC;YACH,CAAC;YAED,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;gBACrB,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACtC,CAAC;YAED,MAAM,YAAY,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;YACvC,MAAM,QAAQ,GAAG,KAAK,IAAI,QAAQ,CAAC,YAAY,CAAC,CAAC;YAEjD,MAAM,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;YAEvC,OAAO;gBACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,kBAAkB,QAAQ,EAAE,EAAE,CAAC;gBACxE,OAAO,EAAE,SAAS;aAClB,CAAC;QACH,CAAC;KACD,CAAC;AACH,CAAC","sourcesContent":["import type { AgentTool } from \"@mariozechner/pi-agent-core\";\nimport { Type } from \"@sinclair/typebox\";\nimport { basename, resolve as resolvePath } from \"path\";\n\nconst attachSchema = Type.Object({\n\tlabel: Type.String({ description: \"Brief description of what you're sharing (shown to user)\" }),\n\tpath: Type.String({ description: \"Path to the file to attach\" }),\n\ttitle: Type.Optional(Type.String({ description: \"Title for the file (defaults to filename)\" })),\n});\n\nexport type UploadFunction = (filePath: string, title?: string) => Promise<void>;\n\n/**\n * Create the attach tool. If no uploadFn is provided, the tool will throw\n * an informative error guiding the LLM to use alternative approaches.\n */\nexport function createAttachTool(uploadFn?: UploadFunction): AgentTool<typeof attachSchema> {\n\treturn {\n\t\tname: \"attach\",\n\t\tlabel: \"attach\",\n\t\tdescription:\n\t\t\t\"Attach a file to your response. Use this to share files, images, or documents with the user. Only files from /workspace/ can be attached.\",\n\t\tparameters: attachSchema,\n\t\texecute: async (\n\t\t\t_toolCallId: string,\n\t\t\t{ path, title }: { label: string; path: string; title?: string },\n\t\t\tsignal?: AbortSignal,\n\t\t) => {\n\t\t\tif (!uploadFn) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"File upload is not supported in DingTalk mode. Output file content as text instead, or use bash to host files.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (signal?.aborted) {\n\t\t\t\tthrow new Error(\"Operation aborted\");\n\t\t\t}\n\n\t\t\tconst absolutePath = resolvePath(path);\n\t\t\tconst fileName = title || basename(absolutePath);\n\n\t\t\tawait uploadFn(absolutePath, fileName);\n\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\" as const, text: `Attached file: ${fileName}` }],\n\t\t\t\tdetails: undefined,\n\t\t\t};\n\t\t},\n\t};\n}\n"]}
|
package/dist/tools/bash.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAW9C,QAAA,MAAM,UAAU;;;;EAId,CAAC;AAOH,MAAM,WAAW,eAAe;IAC/B,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,GAAE,eAAoB,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAqE9G"
|
|
1
|
+
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAW9C,QAAA,MAAM,UAAU;;;;EAId,CAAC;AAOH,MAAM,WAAW,eAAe;IAC/B,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,GAAE,eAAoB,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAqE9G"}
|
package/dist/tools/bash.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash.js","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,UAAU,EAAyB,YAAY,EAAE,MAAM,eAAe,CAAC;AAEtH;;GAEG;AACH,SAAS,eAAe
|
|
1
|
+
{"version":3,"file":"bash.js","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { createWriteStream } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { AgentTool } from \"@mariozechner/pi-agent-core\";\nimport { Type } from \"@sinclair/typebox\";\nimport type { Executor } from \"../sandbox.js\";\nimport { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, type TruncationResult, truncateTail } from \"./truncate.js\";\n\n/**\n * Generate a unique temp file path for bash output\n */\nfunction getTempFilePath(): string {\n\tconst id = randomBytes(8).toString(\"hex\");\n\treturn join(tmpdir(), `pipiclaw-bash-${id}.log`);\n}\n\nconst bashSchema = Type.Object({\n\tlabel: Type.String({ description: \"Brief description of what this command does (shown to user)\" }),\n\tcommand: Type.String({ description: \"Bash command to execute\" }),\n\ttimeout: Type.Optional(Type.Number({ description: \"Timeout in seconds (optional, no default timeout)\" })),\n});\n\ninterface BashToolDetails {\n\ttruncation?: TruncationResult;\n\tfullOutputPath?: string;\n}\n\nexport interface BashToolOptions {\n\tdefaultTimeoutSeconds?: number;\n}\n\nexport function createBashTool(executor: Executor, options: BashToolOptions = {}): AgentTool<typeof bashSchema> {\n\treturn {\n\t\tname: \"bash\",\n\t\tlabel: \"bash\",\n\t\tdescription: `Execute a bash command in the current working directory. Returns stdout and stderr. Output is truncated to last ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). If truncated, full output is saved to a temp file. Optionally provide a timeout in seconds.`,\n\t\tparameters: bashSchema,\n\t\texecute: async (\n\t\t\t_toolCallId: string,\n\t\t\t{ command, timeout }: { label: string; command: string; timeout?: number },\n\t\t\tsignal?: AbortSignal,\n\t\t) => {\n\t\t\t// Track output for potential temp file writing\n\t\t\tlet tempFilePath: string | undefined;\n\t\t\tlet tempFileStream: ReturnType<typeof createWriteStream> | undefined;\n\n\t\t\tconst effectiveTimeout = timeout ?? options.defaultTimeoutSeconds;\n\t\t\tconst result = await executor.exec(command, { timeout: effectiveTimeout, signal });\n\t\t\tlet output = \"\";\n\t\t\tif (result.stdout) output += result.stdout;\n\t\t\tif (result.stderr) {\n\t\t\t\tif (output) output += \"\\n\";\n\t\t\t\toutput += result.stderr;\n\t\t\t}\n\n\t\t\tconst totalBytes = Buffer.byteLength(output, \"utf-8\");\n\n\t\t\t// Write to temp file if output exceeds limit\n\t\t\tif (totalBytes > DEFAULT_MAX_BYTES) {\n\t\t\t\ttempFilePath = getTempFilePath();\n\t\t\t\ttempFileStream = createWriteStream(tempFilePath);\n\t\t\t\ttempFileStream.write(output);\n\t\t\t\ttempFileStream.end();\n\t\t\t}\n\n\t\t\t// Apply tail truncation\n\t\t\tconst truncation = truncateTail(output);\n\t\t\tlet outputText = truncation.content || \"(no output)\";\n\n\t\t\t// Build details with truncation info\n\t\t\tlet details: BashToolDetails | undefined;\n\n\t\t\tif (truncation.truncated) {\n\t\t\t\tdetails = {\n\t\t\t\t\ttruncation,\n\t\t\t\t\tfullOutputPath: tempFilePath,\n\t\t\t\t};\n\n\t\t\t\t// Build actionable notice\n\t\t\t\tconst startLine = truncation.totalLines - truncation.outputLines + 1;\n\t\t\t\tconst endLine = truncation.totalLines;\n\n\t\t\t\tif (truncation.lastLinePartial) {\n\t\t\t\t\t// Edge case: last line alone > 50KB\n\t\t\t\t\tconst lastLineSize = formatSize(Buffer.byteLength(output.split(\"\\n\").pop() || \"\", \"utf-8\"));\n\t\t\t\t\toutputText += `\\n\\n[Showing last ${formatSize(truncation.outputBytes)} of line ${endLine} (line is ${lastLineSize}). Full output: ${tempFilePath}]`;\n\t\t\t\t} else if (truncation.truncatedBy === \"lines\") {\n\t\t\t\t\toutputText += `\\n\\n[Showing lines ${startLine}-${endLine} of ${truncation.totalLines}. Full output: ${tempFilePath}]`;\n\t\t\t\t} else {\n\t\t\t\t\toutputText += `\\n\\n[Showing lines ${startLine}-${endLine} of ${truncation.totalLines} (${formatSize(DEFAULT_MAX_BYTES)} limit). Full output: ${tempFilePath}]`;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (result.code !== 0) {\n\t\t\t\tthrow new Error(`${outputText}\\n\\nCommand exited with code ${result.code}`.trim());\n\t\t\t}\n\n\t\t\treturn { content: [{ type: \"text\", text: outputText }], details };\n\t\t},\n\t};\n}\n"]}
|
package/dist/tools/edit.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/tools/edit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAG7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAuF9C,QAAA,MAAM,UAAU;;;;;EAKd,CAAC;AAEH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CA4D/E"
|
|
1
|
+
{"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/tools/edit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAG7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAuF9C,QAAA,MAAM,UAAU;;;;;EAKd,CAAC;AAEH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CA4D/E"}
|
package/dist/tools/edit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/tools/edit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentTool } from \"@mariozechner/pi-agent-core\";\nimport { Type } from \"@sinclair/typebox\";\nimport * as Diff from \"diff\";\nimport type { Executor } from \"../sandbox.js\";\nimport { shellEscape } from \"../shell-escape.js\";\nimport { writeContent } from \"./write-content.js\";\n\n/**\n * Generate a unified diff string with line numbers and context\n */\nfunction generateDiffString(oldContent: string, newContent: string, contextLines = 4): string {\n\tconst parts = Diff.diffLines(oldContent, newContent);\n\tconst output: string[] = [];\n\n\tconst oldLines = oldContent.split(\"\\n\");\n\tconst newLines = newContent.split(\"\\n\");\n\tconst maxLineNum = Math.max(oldLines.length, newLines.length);\n\tconst lineNumWidth = String(maxLineNum).length;\n\n\tlet oldLineNum = 1;\n\tlet newLineNum = 1;\n\tlet lastWasChange = false;\n\n\tfor (let i = 0; i < parts.length; i++) {\n\t\tconst part = parts[i];\n\t\tconst raw = part.value.split(\"\\n\");\n\t\tif (raw[raw.length - 1] === \"\") {\n\t\t\traw.pop();\n\t\t}\n\n\t\tif (part.added || part.removed) {\n\t\t\tfor (const line of raw) {\n\t\t\t\tif (part.added) {\n\t\t\t\t\tconst lineNum = String(newLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(`+${lineNum} ${line}`);\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t} else {\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(`-${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tlastWasChange = true;\n\t\t} else {\n\t\t\tconst nextPartIsChange = i < parts.length - 1 && (parts[i + 1].added || parts[i + 1].removed);\n\n\t\t\tif (lastWasChange || nextPartIsChange) {\n\t\t\t\tlet linesToShow = raw;\n\t\t\t\tlet skipStart = 0;\n\t\t\t\tlet skipEnd = 0;\n\n\t\t\t\tif (!lastWasChange) {\n\t\t\t\t\tskipStart = Math.max(0, raw.length - contextLines);\n\t\t\t\t\tlinesToShow = raw.slice(skipStart);\n\t\t\t\t}\n\n\t\t\t\tif (!nextPartIsChange && linesToShow.length > contextLines) {\n\t\t\t\t\tskipEnd = linesToShow.length - contextLines;\n\t\t\t\t\tlinesToShow = linesToShow.slice(0, contextLines);\n\t\t\t\t}\n\n\t\t\t\tif (skipStart > 0) {\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t}\n\n\t\t\t\tfor (const line of linesToShow) {\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t}\n\n\t\t\t\tif (skipEnd > 0) {\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t}\n\n\t\t\t\toldLineNum += skipStart + skipEnd;\n\t\t\t\tnewLineNum += skipStart + skipEnd;\n\t\t\t} else {\n\t\t\t\toldLineNum += raw.length;\n\t\t\t\tnewLineNum += raw.length;\n\t\t\t}\n\n\t\t\tlastWasChange = false;\n\t\t}\n\t}\n\n\treturn output.join(\"\\n\");\n}\n\nconst editSchema = Type.Object({\n\tlabel: Type.String({ description: \"Brief description of the edit you're making (shown to user)\" }),\n\tpath: Type.String({ description: \"Path to the file to edit (relative or absolute)\" }),\n\toldText: Type.String({ description: \"Exact text to find and replace (must match exactly)\" }),\n\tnewText: Type.String({ description: \"New text to replace the old text with\" }),\n});\n\nexport function createEditTool(executor: Executor): AgentTool<typeof editSchema> {\n\treturn {\n\t\tname: \"edit\",\n\t\tlabel: \"edit\",\n\t\tdescription:\n\t\t\t\"Edit a file by replacing exact text. The oldText must match exactly (including whitespace). Use this for precise, surgical edits.\",\n\t\tparameters: editSchema,\n\t\texecute: async (\n\t\t\t_toolCallId: string,\n\t\t\t{ path, oldText, newText }: { label: string; path: string; oldText: string; newText: string },\n\t\t\tsignal?: AbortSignal,\n\t\t) => {\n\t\t\t// Read the file\n\t\t\tconst readResult = await executor.exec(`cat ${shellEscape(path)}`, { signal });\n\t\t\tif (readResult.code !== 0) {\n\t\t\t\tthrow new Error(readResult.stderr || `File not found: ${path}`);\n\t\t\t}\n\n\t\t\tconst content = readResult.stdout;\n\n\t\t\t// Check if old text exists\n\t\t\tif (!content.includes(oldText)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Could not find the exact text in ${path}. The old text must match exactly including all whitespace and newlines.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Count occurrences\n\t\t\tconst occurrences = content.split(oldText).length - 1;\n\n\t\t\tif (occurrences > 1) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Found ${occurrences} occurrences of the text in ${path}. The text must be unique. Please provide more context to make it unique.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Perform replacement\n\t\t\tconst index = content.indexOf(oldText);\n\t\t\tconst newContent = content.substring(0, index) + newText + content.substring(index + oldText.length);\n\n\t\t\tif (content === newContent) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No changes made to ${path}. The replacement produced identical content. This might indicate an issue with special characters or the text not existing as expected.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Write the file back\n\t\t\tawait writeContent(executor, path, newContent, signal);\n\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: `Successfully replaced text in ${path}. Changed ${oldText.length} characters to ${newText.length} characters.`,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdetails: { diff: generateDiffString(content, newContent) },\n\t\t\t};\n\t\t},\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/tools/edit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentTool } from \"@mariozechner/pi-agent-core\";\nimport { Type } from \"@sinclair/typebox\";\nimport * as Diff from \"diff\";\nimport type { Executor } from \"../sandbox.js\";\nimport { shellEscape } from \"../shell-escape.js\";\nimport { writeContent } from \"./write-content.js\";\n\n/**\n * Generate a unified diff string with line numbers and context\n */\nfunction generateDiffString(oldContent: string, newContent: string, contextLines = 4): string {\n\tconst parts = Diff.diffLines(oldContent, newContent);\n\tconst output: string[] = [];\n\n\tconst oldLines = oldContent.split(\"\\n\");\n\tconst newLines = newContent.split(\"\\n\");\n\tconst maxLineNum = Math.max(oldLines.length, newLines.length);\n\tconst lineNumWidth = String(maxLineNum).length;\n\n\tlet oldLineNum = 1;\n\tlet newLineNum = 1;\n\tlet lastWasChange = false;\n\n\tfor (let i = 0; i < parts.length; i++) {\n\t\tconst part = parts[i];\n\t\tconst raw = part.value.split(\"\\n\");\n\t\tif (raw[raw.length - 1] === \"\") {\n\t\t\traw.pop();\n\t\t}\n\n\t\tif (part.added || part.removed) {\n\t\t\tfor (const line of raw) {\n\t\t\t\tif (part.added) {\n\t\t\t\t\tconst lineNum = String(newLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(`+${lineNum} ${line}`);\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t} else {\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(`-${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tlastWasChange = true;\n\t\t} else {\n\t\t\tconst nextPartIsChange = i < parts.length - 1 && (parts[i + 1].added || parts[i + 1].removed);\n\n\t\t\tif (lastWasChange || nextPartIsChange) {\n\t\t\t\tlet linesToShow = raw;\n\t\t\t\tlet skipStart = 0;\n\t\t\t\tlet skipEnd = 0;\n\n\t\t\t\tif (!lastWasChange) {\n\t\t\t\t\tskipStart = Math.max(0, raw.length - contextLines);\n\t\t\t\t\tlinesToShow = raw.slice(skipStart);\n\t\t\t\t}\n\n\t\t\t\tif (!nextPartIsChange && linesToShow.length > contextLines) {\n\t\t\t\t\tskipEnd = linesToShow.length - contextLines;\n\t\t\t\t\tlinesToShow = linesToShow.slice(0, contextLines);\n\t\t\t\t}\n\n\t\t\t\tif (skipStart > 0) {\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t}\n\n\t\t\t\tfor (const line of linesToShow) {\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t}\n\n\t\t\t\tif (skipEnd > 0) {\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t}\n\n\t\t\t\toldLineNum += skipStart + skipEnd;\n\t\t\t\tnewLineNum += skipStart + skipEnd;\n\t\t\t} else {\n\t\t\t\toldLineNum += raw.length;\n\t\t\t\tnewLineNum += raw.length;\n\t\t\t}\n\n\t\t\tlastWasChange = false;\n\t\t}\n\t}\n\n\treturn output.join(\"\\n\");\n}\n\nconst editSchema = Type.Object({\n\tlabel: Type.String({ description: \"Brief description of the edit you're making (shown to user)\" }),\n\tpath: Type.String({ description: \"Path to the file to edit (relative or absolute)\" }),\n\toldText: Type.String({ description: \"Exact text to find and replace (must match exactly)\" }),\n\tnewText: Type.String({ description: \"New text to replace the old text with\" }),\n});\n\nexport function createEditTool(executor: Executor): AgentTool<typeof editSchema> {\n\treturn {\n\t\tname: \"edit\",\n\t\tlabel: \"edit\",\n\t\tdescription:\n\t\t\t\"Edit a file by replacing exact text. The oldText must match exactly (including whitespace). Use this for precise, surgical edits.\",\n\t\tparameters: editSchema,\n\t\texecute: async (\n\t\t\t_toolCallId: string,\n\t\t\t{ path, oldText, newText }: { label: string; path: string; oldText: string; newText: string },\n\t\t\tsignal?: AbortSignal,\n\t\t) => {\n\t\t\t// Read the file\n\t\t\tconst readResult = await executor.exec(`cat ${shellEscape(path)}`, { signal });\n\t\t\tif (readResult.code !== 0) {\n\t\t\t\tthrow new Error(readResult.stderr || `File not found: ${path}`);\n\t\t\t}\n\n\t\t\tconst content = readResult.stdout;\n\n\t\t\t// Check if old text exists\n\t\t\tif (!content.includes(oldText)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Could not find the exact text in ${path}. The old text must match exactly including all whitespace and newlines.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Count occurrences\n\t\t\tconst occurrences = content.split(oldText).length - 1;\n\n\t\t\tif (occurrences > 1) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Found ${occurrences} occurrences of the text in ${path}. The text must be unique. Please provide more context to make it unique.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Perform replacement\n\t\t\tconst index = content.indexOf(oldText);\n\t\t\tconst newContent = content.substring(0, index) + newText + content.substring(index + oldText.length);\n\n\t\t\tif (content === newContent) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No changes made to ${path}. The replacement produced identical content. This might indicate an issue with special characters or the text not existing as expected.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Write the file back\n\t\t\tawait writeContent(executor, path, newContent, signal);\n\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: `Successfully replaced text in ${path}. Changed ${oldText.length} characters to ${newText.length} characters.`,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdetails: { diff: generateDiffString(content, newContent) },\n\t\t\t};\n\t\t},\n\t};\n}\n"]}
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
2
|
import type { Api, Model } from "@mariozechner/pi-ai";
|
|
3
|
+
import type { PipiclawMemoryRecallSettings } from "../context.js";
|
|
3
4
|
import type { Executor, SandboxConfig } from "../sandbox.js";
|
|
4
5
|
import type { SubAgentDiscoveryResult } from "../sub-agents.js";
|
|
5
6
|
export interface CreatePipiclawToolsOptions {
|
|
@@ -8,10 +9,12 @@ export interface CreatePipiclawToolsOptions {
|
|
|
8
9
|
getAvailableModels: () => Model<Api>[];
|
|
9
10
|
resolveApiKey: (model: Model<Api>) => Promise<string>;
|
|
10
11
|
workspaceDir: string;
|
|
12
|
+
channelDir: string;
|
|
11
13
|
workspacePath: string;
|
|
12
14
|
channelId: string;
|
|
13
15
|
sandboxConfig: SandboxConfig;
|
|
14
16
|
getSubAgentDiscovery: () => SubAgentDiscoveryResult;
|
|
17
|
+
getMemoryRecallSettings: () => PipiclawMemoryRecallSettings;
|
|
15
18
|
}
|
|
16
19
|
export declare function createPipiclawBaseTools(executor: Executor): AgentTool<any>[];
|
|
17
20
|
export declare function createPipiclawTools(options: CreatePipiclawToolsOptions): AgentTool<any>[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAOhE,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,EAAE,QAAQ,CAAC;IACnB,eAAe,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,kBAAkB,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;IACvC,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,aAAa,CAAC;IAC7B,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAOhE,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,EAAE,QAAQ,CAAC;IACnB,eAAe,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,kBAAkB,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;IACvC,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,aAAa,CAAC;IAC7B,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;IACpD,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;CAC5D;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE,CAE5E;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE,CAoBzF"}
|
package/dist/tools/index.js
CHANGED
|
@@ -16,7 +16,9 @@ export function createPipiclawTools(options) {
|
|
|
16
16
|
getAvailableModels: options.getAvailableModels,
|
|
17
17
|
resolveApiKey: options.resolveApiKey,
|
|
18
18
|
workspaceDir: options.workspaceDir,
|
|
19
|
+
channelDir: options.channelDir,
|
|
19
20
|
getSubAgentDiscovery: options.getSubAgentDiscovery,
|
|
21
|
+
getMemoryRecallSettings: options.getMemoryRecallSettings,
|
|
20
22
|
runtimeContext: {
|
|
21
23
|
workspacePath: options.workspacePath,
|
|
22
24
|
channelId: options.channelId,
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAgB7C,MAAM,UAAU,uBAAuB,CAAC,QAAkB;IACzD,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC;AAClH,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAmC;IACtE,MAAM,SAAS,GAAG,uBAAuB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5D,OAAO;QACN,GAAG,SAAS;QACZ,kBAAkB,CAAC;YAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,eAAe,EAAE,OAAO,CAAC,eAAe;YACxC,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;YAC9C,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;YAClD,uBAAuB,EAAE,OAAO,CAAC,uBAAuB;YACxD,cAAc,EAAE;gBACf,aAAa,EAAE,OAAO,CAAC,aAAa;gBACpC,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE;aACrG;SACD,CAAC;KACF,CAAC;AACH,CAAC","sourcesContent":["import type { AgentTool } from \"@mariozechner/pi-agent-core\";\nimport type { Api, Model } from \"@mariozechner/pi-ai\";\nimport type { PipiclawMemoryRecallSettings } from \"../context.js\";\nimport type { Executor, SandboxConfig } from \"../sandbox.js\";\nimport type { SubAgentDiscoveryResult } from \"../sub-agents.js\";\nimport { createBashTool } from \"./bash.js\";\nimport { createEditTool } from \"./edit.js\";\nimport { createReadTool } from \"./read.js\";\nimport { createSubAgentTool } from \"./subagent.js\";\nimport { createWriteTool } from \"./write.js\";\n\nexport interface CreatePipiclawToolsOptions {\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\tworkspacePath: string;\n\tchannelId: string;\n\tsandboxConfig: SandboxConfig;\n\tgetSubAgentDiscovery: () => SubAgentDiscoveryResult;\n\tgetMemoryRecallSettings: () => PipiclawMemoryRecallSettings;\n}\n\nexport function createPipiclawBaseTools(executor: Executor): AgentTool<any>[] {\n\treturn [createReadTool(executor), createBashTool(executor), createEditTool(executor), createWriteTool(executor)];\n}\n\nexport function createPipiclawTools(options: CreatePipiclawToolsOptions): AgentTool<any>[] {\n\tconst baseTools = createPipiclawBaseTools(options.executor);\n\treturn [\n\t\t...baseTools,\n\t\tcreateSubAgentTool({\n\t\t\texecutor: options.executor,\n\t\t\tgetCurrentModel: options.getCurrentModel,\n\t\t\tgetAvailableModels: options.getAvailableModels,\n\t\t\tresolveApiKey: options.resolveApiKey,\n\t\t\tworkspaceDir: options.workspaceDir,\n\t\t\tchannelDir: options.channelDir,\n\t\t\tgetSubAgentDiscovery: options.getSubAgentDiscovery,\n\t\t\tgetMemoryRecallSettings: options.getMemoryRecallSettings,\n\t\t\truntimeContext: {\n\t\t\t\tworkspacePath: options.workspacePath,\n\t\t\t\tchannelId: options.channelId,\n\t\t\t\tsandbox: options.sandboxConfig.type === \"host\" ? \"host\" : `docker:${options.sandboxConfig.container}`,\n\t\t\t},\n\t\t}),\n\t];\n}\n"]}
|