{"version":3,"file":"subagents.d.ts","sourceRoot":"","sources":["../../../../src/core/long-horizon/adaptive/subagents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAElF,MAAM,WAAW,qBAAqB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,qBAAqB,EAAE,MAAM,CAAC;CAC9B;AAED,eAAO,MAAM,uBAAuB,EAAE,qBAIrC,CAAC;AAEF,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,YAAY,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,CAAC,EAAE,qBAAqB,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;CACjC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,mBAAmB,GAAG,cAAc,CA2C5E;AAUD,yEAAyE;AACzE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,cAAc,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAcpH;AAED,mFAAmF;AACnF,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACX,YAAY,CAYd;AAED,0EAA0E;AAC1E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,iBAAiB,EAAE,GAAG,MAAM,EAAE,CAEhF;AAED,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,CAAC","sourcesContent":["/**\n * Isolated bounded subagents.\n *\n * First-class subagent runs: isolated context, bounded toolset, bounded budget,\n * bounded lifetime, cancellation propagation, durable start/finish events, and\n * structured output that the parent must validate before use. A subagent\n * cannot expand scope, cannot mutate/commit/publish by default, and cannot\n * recursively spawn children beyond explicit parent policy and depth limits.\n * All child consumption is charged to the parent budget via the ledger.\n */\n\nimport type { BudgetLedger } from \"./budget-ledger.js\";\nimport { appendEntry } from \"./budget-ledger.js\";\nimport type { SubagentRunRecord, SubagentSpec, SubagentStatus } from \"./types.js\";\n\nexport interface SubagentRuntimeConfig {\n\tmaxDepth: number;\n\tmaxTotalChildren: number;\n\tmaxConcurrentChildren: number;\n}\n\nexport const DEFAULT_SUBAGENT_CONFIG: SubagentRuntimeConfig = {\n\tmaxDepth: 1,\n\tmaxTotalChildren: 8,\n\tmaxConcurrentChildren: 2,\n};\n\nexport interface SubagentLaunchInput {\n\tspec: SubagentSpec;\n\tparentCanMutate: boolean;\n\tparentCanPublish: boolean;\n\tsiblingCount: number;\n\tactiveChildren: number;\n\tparentLedger: BudgetLedger;\n\tconfig?: SubagentRuntimeConfig;\n}\n\nexport interface LaunchDecision {\n\tallowed: boolean;\n\treasonCodes: string[];\n\trecord: SubagentRunRecord | null;\n}\n\n/**\n * Deterministically decide whether a subagent may launch under parent policy\n * and runtime limits (depth, total children, concurrency, budget, mutation).\n */\nexport function canLaunchSubagent(input: SubagentLaunchInput): LaunchDecision {\n\tconst config = input.config ?? DEFAULT_SUBAGENT_CONFIG;\n\tconst reasonCodes: string[] = [];\n\n\tif (input.spec.maxDepth > config.maxDepth) {\n\t\treasonCodes.push(\"SUBDEPTH_EXCEEDED\");\n\t}\n\tif (input.spec.allowSpawnSubagents && input.spec.maxDepth <= 0) {\n\t\treasonCodes.push(\"SUBDEPTH_EXHAUSTED\");\n\t}\n\tif (input.siblingCount >= config.maxTotalChildren) {\n\t\treasonCodes.push(\"MAX_TOTAL_CHILDREN\");\n\t}\n\tif (input.activeChildren >= config.maxConcurrentChildren) {\n\t\treasonCodes.push(\"MAX_CONCURRENT_CHILDREN\");\n\t}\n\t// A subagent that would mutate must be explicitly permitted by parent policy.\n\tif (input.spec.executionMode === \"mutate\" || input.spec.allowMutation) {\n\t\tif (!input.parentCanMutate) {\n\t\t\treasonCodes.push(\"MUTATION_DENIED\");\n\t\t}\n\t}\n\tif (input.parentCanPublish === false && input.spec.allowedTools.includes(\"publish\")) {\n\t\treasonCodes.push(\"PUBLISH_DENIED\");\n\t}\n\t// Child budget must not exceed what the parent can afford: we only permit a\n\t// launch if the child budget is defined and non-negative.\n\tif (budgetIsUnbounded(input.spec.budget)) {\n\t\treasonCodes.push(\"CHILD_BUDGET_UNBOUNDED\");\n\t}\n\n\tconst allowed = reasonCodes.length === 0;\n\tif (!allowed) {\n\t\treturn { allowed, reasonCodes, record: null };\n\t}\n\n\tconst record: SubagentRunRecord = Object.freeze({\n\t\tsubagentId: input.spec.subagentId,\n\t\tparentRunId: input.spec.parentRunId,\n\t\trole: input.spec.role,\n\t\tstatus: \"pending\",\n\t});\n\treturn { allowed, reasonCodes, record };\n}\n\nfunction budgetIsUnbounded(budget: Partial<import(\"./types.js\").ExecutionBudget>): boolean {\n\t// A subagent must carry at least one bounded budget dimension.\n\tfor (const v of Object.values(budget)) {\n\t\tif (typeof v === \"number\" && v > 0) return false;\n\t}\n\treturn true;\n}\n\n/** Advance a subagent record status (durable event), frozen snapshot. */\nexport function transitionSubagent(record: SubagentRunRecord, status: SubagentStatus, at?: string): SubagentRunRecord {\n\treturn Object.freeze({\n\t\tsubagentId: record.subagentId,\n\t\tparentRunId: record.parentRunId,\n\t\trole: record.role,\n\t\tstatus,\n\t\tstartedAt: record.startedAt ?? (status === \"running\" ? at : record.startedAt),\n\t\tfinishedAt:\n\t\t\tstatus === \"succeeded\" || status === \"failed\" || status === \"cancelled\" || status === \"timed_out\"\n\t\t\t\t? at\n\t\t\t\t: record.finishedAt,\n\t\tresultPayload: record.resultPayload,\n\t\tcancelRequested: status === \"cancelled\" ? true : record.cancelRequested,\n\t});\n}\n\n/** Charge a child's consumption to the parent budget (append-only, idempotent). */\nexport function chargeChildToParent(\n\tledger: BudgetLedger,\n\tchildId: string,\n\tresource: string,\n\tamount: number,\n\trunId: string,\n): BudgetLedger {\n\tconst result = appendEntry(ledger, {\n\t\tentryId: `${childId}:charge:${resource}`,\n\t\trunId,\n\t\trole: \"subagent\",\n\t\tresource: resource as never,\n\t\tamount,\n\t\testimatedOrActual: \"estimated\",\n\t\tsourceEventId: `${childId}:${resource}`,\n\t\trecordedAt: new Date(0).toISOString(),\n\t});\n\treturn result.ledger;\n}\n\n/** Deterministic ordering key for parallel read-only subagent results. */\nexport function parallelOrderKey(records: readonly SubagentRunRecord[]): string[] {\n\treturn records.map((r) => r.subagentId);\n}\n\nexport type { SubagentRunRecord, SubagentStatus };\n"]}