refactor(subagent): split extension into modules
This commit is contained in:
65
src/tools.ts
Normal file
65
src/tools.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { Type } from "typebox";
|
||||
import { FINALIZE_TOOL_NAME } from "./constants.ts";
|
||||
import type { PromptConfig, SubagentFinalizePayload } from "./types.ts";
|
||||
import { FinalizeStatus } from "./types.ts";
|
||||
|
||||
// Resolve Tools - Use exactly one permission mode. approved_tools/allowed_tools
|
||||
// is a whitelist; denied_tools is a blacklist over the currently active tools.
|
||||
export function resolveTools(
|
||||
agent: PromptConfig,
|
||||
activeTools: string[],
|
||||
): string[] {
|
||||
const withoutDelegationTools = (tools: string[]) =>
|
||||
tools.filter((tool) => tool !== "subagent" && tool !== FINALIZE_TOOL_NAME);
|
||||
|
||||
const resolved =
|
||||
agent.approvedTools.length > 0
|
||||
? withoutDelegationTools([...new Set(agent.approvedTools)])
|
||||
: withoutDelegationTools(
|
||||
[...new Set(activeTools)].filter(
|
||||
(tool) => !new Set(agent.deniedTools).has(tool),
|
||||
),
|
||||
);
|
||||
|
||||
return [...new Set([...resolved, FINALIZE_TOOL_NAME])];
|
||||
}
|
||||
|
||||
// Validate Finalize Payload - Keep the parent contract strict and small.
|
||||
export function validateFinalizePayload(
|
||||
value: unknown,
|
||||
): SubagentFinalizePayload | null {
|
||||
if (!value || typeof value !== "object") return null;
|
||||
const payload = value as Record<string, unknown>;
|
||||
if (payload.status === FinalizeStatus.SUCCESS) {
|
||||
return typeof payload.result === "string" && payload.result.trim()
|
||||
? { status: FinalizeStatus.SUCCESS, result: payload.result }
|
||||
: null;
|
||||
}
|
||||
if (payload.status === FinalizeStatus.ERROR) {
|
||||
const result =
|
||||
typeof payload.result === "string" ? payload.result : undefined;
|
||||
return typeof payload.error === "string" && payload.error.trim()
|
||||
? { status: FinalizeStatus.ERROR, error: payload.error, result }
|
||||
: null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export const SubagentParams = Type.Object({
|
||||
agent: Type.String({
|
||||
description: "Name of the prompt-defined subagent to invoke",
|
||||
}),
|
||||
task: Type.String({ description: "Task to delegate to the subagent" }),
|
||||
sessionId: Type.Optional(
|
||||
Type.String({
|
||||
description:
|
||||
"Optional sticky subagent session id. Reuse to continue a previous subagent context.",
|
||||
}),
|
||||
),
|
||||
cwd: Type.Optional(
|
||||
Type.String({
|
||||
description:
|
||||
"Working directory for the subagent process. Defaults to current cwd.",
|
||||
}),
|
||||
),
|
||||
});
|
||||
Reference in New Issue
Block a user