@yolk-sdk/agent 0.1.0-canary.52 → 0.1.0-canary.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/skillset/merge.d.mts +3 -3
- package/dist/skillset/name.d.mts +2 -2
- package/dist/skillset/name.d.mts.map +1 -1
- package/dist/tools/index.d.mts +2 -2
- package/dist/tools/task.d.mts +24 -11
- package/dist/tools/task.d.mts.map +1 -1
- package/dist/tools/task.mjs +52 -10
- package/dist/tools/task.mjs.map +1 -1
- package/package.json +1 -1
- package/src/tools/README.md +23 -3
- package/src/tools/index.ts +3 -0
- package/src/tools/task.ts +117 -14
package/README.md
CHANGED
|
@@ -389,7 +389,9 @@ Recommended setup:
|
|
|
389
389
|
- omit `task` from subagent toolsets
|
|
390
390
|
- include only tools that are safe for autonomous delegated work
|
|
391
391
|
- use `makeSubagentRunId(call.id)` for protocol-aligned run ids
|
|
392
|
-
-
|
|
392
|
+
- optionally configure model and reasoning-effort choices so the parent can select child runtime settings
|
|
393
|
+
- treat omitted `model` and `reasoning_effort` parameters as inheritance of host runtime settings
|
|
394
|
+
- return `makeTaskToolResult(...)` so UI can show subagent id, type, status, model, reasoning effort, and timing
|
|
393
395
|
|
|
394
396
|
Keep host-owned subagent execution wiring outside this package; pass only the package task contract across the boundary.
|
|
395
397
|
|
|
@@ -17,17 +17,16 @@ declare const mergeSkillsets: (sources: ReadonlyArray<SkillsetSource>) => Effect
|
|
|
17
17
|
skills: {
|
|
18
18
|
readonly name: string;
|
|
19
19
|
readonly description: string;
|
|
20
|
-
readonly location: string;
|
|
21
20
|
readonly content: string;
|
|
21
|
+
readonly location: string;
|
|
22
22
|
readonly source?: string | undefined;
|
|
23
23
|
}[];
|
|
24
24
|
commands: {
|
|
25
25
|
readonly name: string;
|
|
26
26
|
readonly hints: readonly string[];
|
|
27
27
|
readonly template: string;
|
|
28
|
-
readonly description?: string | undefined;
|
|
29
28
|
readonly source?: string | undefined;
|
|
30
|
-
readonly
|
|
29
|
+
readonly description?: string | undefined;
|
|
31
30
|
readonly arguments?: readonly {
|
|
32
31
|
readonly required: boolean;
|
|
33
32
|
readonly name: string;
|
|
@@ -35,6 +34,7 @@ declare const mergeSkillsets: (sources: ReadonlyArray<SkillsetSource>) => Effect
|
|
|
35
34
|
}[] | undefined;
|
|
36
35
|
readonly access?: "read" | "write" | "destructive" | undefined;
|
|
37
36
|
readonly fileRefs?: boolean | undefined;
|
|
37
|
+
readonly location?: string | undefined;
|
|
38
38
|
}[];
|
|
39
39
|
}, SkillsetError, never>;
|
|
40
40
|
//#endregion
|
package/dist/skillset/name.d.mts
CHANGED
|
@@ -3,8 +3,8 @@ import { Effect } from "effect";
|
|
|
3
3
|
|
|
4
4
|
//#region src/skillset/name.d.ts
|
|
5
5
|
declare const isValidSkillsetName: (name: string) => boolean;
|
|
6
|
-
declare const validateSkillsetName: (name: string) => Effect.Effect<
|
|
7
|
-
declare const validateDirectoryName: (expected: string, actual: string) => Effect.Effect<
|
|
6
|
+
declare const validateSkillsetName: (name: string) => Effect.Effect<string, never, never> | Effect.Effect<never, SkillsetError, never>;
|
|
7
|
+
declare const validateDirectoryName: (expected: string, actual: string) => Effect.Effect<string, never, never> | Effect.Effect<never, SkillsetError, never>;
|
|
8
8
|
//#endregion
|
|
9
9
|
export { isValidSkillsetName, validateDirectoryName, validateSkillsetName };
|
|
10
10
|
//# sourceMappingURL=name.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"name.d.mts","names":[],"sources":["../../src/skillset/name.ts"],"mappings":";;;;cAMa,mBAAA,GAAuB,IAAY;AAAA,cAGnC,oBAAA,GAAwB,IAAA,aAAY,MAAA,CAAA,MAAA,
|
|
1
|
+
{"version":3,"file":"name.d.mts","names":[],"sources":["../../src/skillset/name.ts"],"mappings":";;;;cAMa,mBAAA,GAAuB,IAAY;AAAA,cAGnC,oBAAA,GAAwB,IAAA,aAAY,MAAA,CAAA,MAAA,yBAAA,MAAA,CAAA,MAAA,QAAA,aAAA;AAAA,cAUpC,qBAAA,GAAyB,QAAA,UAAkB,MAAA,aAAc,MAAA,CAAA,MAAA,yBAAA,MAAA,CAAA,MAAA,QAAA,aAAA"}
|
package/dist/tools/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { EmptyToolParams, ModelVisibleToolError, ModelVisibleToolErrorInput, ModelVisibleToolErrorReason, ModelVisibleToolErrorStructuredContent, ModelVisibleToolErrorStructuredContentSchema, ResolvedToolSet, SchemaToolExecutionInput, ToolAccess, ToolExecutionInput, ToolMetadata, ToolModule, ToolRegistration, ToolRegistryError, makeTool, makeToolExecutorLayer, modelVisibleToolError, modelVisibleToolErrorResult, modelVisibleToolErrorStructuredContent, resolveTools } from "./registry.mjs";
|
|
2
2
|
import { QuestionExecutionInput, QuestionToolOptions, makeQuestionToolDef, makeQuestionToolModule, makeQuestionToolRegistration, questionToolName } from "./question.mjs";
|
|
3
|
-
import { TaskExecutionInput, TaskSubagentContext, TaskSubagentDefinition, TaskToolOptions, TaskToolParams, TaskToolResultInput, formatTaskResult, makeNonRecursiveTaskToolModule, makeTaskToolDef, makeTaskToolModule, makeTaskToolRegistration, makeTaskToolResult, subagentResultText, taskSubagentRunId, taskToolName } from "./task.mjs";
|
|
4
|
-
export { EmptyToolParams, ModelVisibleToolError, type ModelVisibleToolErrorInput, ModelVisibleToolErrorReason, type ModelVisibleToolErrorStructuredContent, ModelVisibleToolErrorStructuredContentSchema, type QuestionExecutionInput, type QuestionToolOptions, type ResolvedToolSet, type SchemaToolExecutionInput, type TaskExecutionInput, type TaskSubagentContext, type TaskSubagentDefinition, type TaskToolOptions, type TaskToolParams, type TaskToolResultInput, ToolAccess, type ToolExecutionInput, type ToolMetadata, type ToolModule, type ToolRegistration, ToolRegistryError, formatTaskResult, makeNonRecursiveTaskToolModule, makeQuestionToolDef, makeQuestionToolModule, makeQuestionToolRegistration, makeTaskToolDef, makeTaskToolModule, makeTaskToolRegistration, makeTaskToolResult, makeTool, makeToolExecutorLayer, modelVisibleToolError, modelVisibleToolErrorResult, modelVisibleToolErrorStructuredContent, questionToolName, resolveTools, subagentResultText, taskSubagentRunId, taskToolName };
|
|
3
|
+
import { TaskExecutionInput, TaskModelDefinition, TaskReasoningEffortDefinition, TaskRuntimeSelectionOptions, TaskSubagentContext, TaskSubagentDefinition, TaskToolOptions, TaskToolParams, TaskToolResultInput, formatTaskResult, makeNonRecursiveTaskToolModule, makeTaskToolDef, makeTaskToolModule, makeTaskToolRegistration, makeTaskToolResult, subagentResultText, taskSubagentRunId, taskToolName } from "./task.mjs";
|
|
4
|
+
export { EmptyToolParams, ModelVisibleToolError, type ModelVisibleToolErrorInput, ModelVisibleToolErrorReason, type ModelVisibleToolErrorStructuredContent, ModelVisibleToolErrorStructuredContentSchema, type QuestionExecutionInput, type QuestionToolOptions, type ResolvedToolSet, type SchemaToolExecutionInput, type TaskExecutionInput, type TaskModelDefinition, type TaskReasoningEffortDefinition, type TaskRuntimeSelectionOptions, type TaskSubagentContext, type TaskSubagentDefinition, type TaskToolOptions, type TaskToolParams, type TaskToolResultInput, ToolAccess, type ToolExecutionInput, type ToolMetadata, type ToolModule, type ToolRegistration, ToolRegistryError, formatTaskResult, makeNonRecursiveTaskToolModule, makeQuestionToolDef, makeQuestionToolModule, makeQuestionToolRegistration, makeTaskToolDef, makeTaskToolModule, makeTaskToolRegistration, makeTaskToolResult, makeTool, makeToolExecutorLayer, modelVisibleToolError, modelVisibleToolErrorResult, modelVisibleToolErrorStructuredContent, questionToolName, resolveTools, subagentResultText, taskSubagentRunId, taskToolName };
|
package/dist/tools/task.d.mts
CHANGED
|
@@ -1,21 +1,33 @@
|
|
|
1
1
|
import { ToolModule, ToolRegistration, ToolRegistryError } from "./registry.mjs";
|
|
2
2
|
import { Effect } from "effect";
|
|
3
|
-
import { AgentEvent, ToolCall, ToolResult } from "@yolk-sdk/agent/protocol";
|
|
4
|
-
import * as Schema from "effect/Schema";
|
|
3
|
+
import { AgentEvent, AgentReasoningEffort, ToolCall, ToolResult } from "@yolk-sdk/agent/protocol";
|
|
5
4
|
import { ToolError } from "@yolk-sdk/agent/loop";
|
|
6
5
|
|
|
7
6
|
//#region src/tools/task.d.ts
|
|
8
7
|
declare const taskToolName = "task";
|
|
9
|
-
|
|
10
|
-
readonly description:
|
|
11
|
-
readonly prompt:
|
|
12
|
-
readonly subagent_type:
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
type TaskToolParams = {
|
|
9
|
+
readonly description: string;
|
|
10
|
+
readonly prompt: string;
|
|
11
|
+
readonly subagent_type: string;
|
|
12
|
+
readonly model?: string;
|
|
13
|
+
readonly reasoning_effort?: AgentReasoningEffort;
|
|
14
|
+
};
|
|
15
15
|
type TaskSubagentDefinition = {
|
|
16
16
|
readonly name: string;
|
|
17
17
|
readonly description: string;
|
|
18
18
|
};
|
|
19
|
+
type TaskModelDefinition = {
|
|
20
|
+
readonly id: string;
|
|
21
|
+
readonly description: string;
|
|
22
|
+
};
|
|
23
|
+
type TaskReasoningEffortDefinition = {
|
|
24
|
+
readonly value: AgentReasoningEffort;
|
|
25
|
+
readonly description: string;
|
|
26
|
+
};
|
|
27
|
+
type TaskRuntimeSelectionOptions = {
|
|
28
|
+
readonly models?: ReadonlyArray<TaskModelDefinition>;
|
|
29
|
+
readonly reasoningEfforts?: ReadonlyArray<TaskReasoningEffortDefinition>;
|
|
30
|
+
};
|
|
19
31
|
type TaskSubagentContext = {
|
|
20
32
|
readonly subagent?: boolean;
|
|
21
33
|
};
|
|
@@ -24,7 +36,7 @@ type TaskExecutionInput<Context> = {
|
|
|
24
36
|
readonly context: Context;
|
|
25
37
|
readonly params: TaskToolParams;
|
|
26
38
|
};
|
|
27
|
-
type TaskToolOptions<Context> = {
|
|
39
|
+
type TaskToolOptions<Context> = TaskRuntimeSelectionOptions & {
|
|
28
40
|
readonly subagents: ReadonlyArray<TaskSubagentDefinition>;
|
|
29
41
|
readonly isEnabled?: (context: Context) => Effect.Effect<boolean, ToolRegistryError>;
|
|
30
42
|
readonly execute: (input: TaskExecutionInput<Context>) => Effect.Effect<ToolResult, ToolError>;
|
|
@@ -38,10 +50,11 @@ type TaskToolResultInput = {
|
|
|
38
50
|
readonly startedAtMs: number;
|
|
39
51
|
readonly endedAtMs: number;
|
|
40
52
|
readonly model: string;
|
|
53
|
+
readonly reasoningEffort?: AgentReasoningEffort;
|
|
41
54
|
readonly isError?: boolean;
|
|
42
55
|
};
|
|
43
56
|
declare const makeTaskToolRegistration: <Context>(options: TaskToolOptions<Context>) => ToolRegistration<Context>;
|
|
44
|
-
declare const makeTaskToolDef: (subagents: ReadonlyArray<TaskSubagentDefinition
|
|
57
|
+
declare const makeTaskToolDef: (subagents: ReadonlyArray<TaskSubagentDefinition>, runtimeSelections?: TaskRuntimeSelectionOptions) => import("@yolk-sdk/agent/protocol").ToolDef;
|
|
45
58
|
declare const makeTaskToolModule: <Context>(options: TaskToolOptions<Context>) => ToolModule<Context>;
|
|
46
59
|
declare const makeNonRecursiveTaskToolModule: <Context extends TaskSubagentContext>(options: TaskToolOptions<Context>) => ToolModule<Context>;
|
|
47
60
|
declare const formatTaskResult: (output: string) => string;
|
|
@@ -49,5 +62,5 @@ declare const taskSubagentRunId: (parentToolCallId: string) => string;
|
|
|
49
62
|
declare const subagentResultText: (events: ReadonlyArray<AgentEvent>) => string;
|
|
50
63
|
declare const makeTaskToolResult: (input: TaskToolResultInput) => ToolResult;
|
|
51
64
|
//#endregion
|
|
52
|
-
export { TaskExecutionInput, TaskSubagentContext, TaskSubagentDefinition, TaskToolOptions, TaskToolParams, TaskToolResultInput, formatTaskResult, makeNonRecursiveTaskToolModule, makeTaskToolDef, makeTaskToolModule, makeTaskToolRegistration, makeTaskToolResult, subagentResultText, taskSubagentRunId, taskToolName };
|
|
65
|
+
export { TaskExecutionInput, TaskModelDefinition, TaskReasoningEffortDefinition, TaskRuntimeSelectionOptions, TaskSubagentContext, TaskSubagentDefinition, TaskToolOptions, TaskToolParams, TaskToolResultInput, formatTaskResult, makeNonRecursiveTaskToolModule, makeTaskToolDef, makeTaskToolModule, makeTaskToolRegistration, makeTaskToolResult, subagentResultText, taskSubagentRunId, taskToolName };
|
|
53
66
|
//# sourceMappingURL=task.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task.d.mts","names":[],"sources":["../../src/tools/task.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"task.d.mts","names":[],"sources":["../../src/tools/task.ts"],"mappings":";;;;;;cAsBa,YAAA;AAAA,KAiBD,cAAA;EAAA,SACD,WAAA;EAAA,SACA,MAAA;EAAA,SACA,aAAA;EAAA,SACA,KAAA;EAAA,SACA,gBAAA,GAAmB,oBAAoB;AAAA;AAAA,KAGtC,sBAAA;EAAA,SACD,IAAA;EAAA,SACA,WAAW;AAAA;AAAA,KAGV,mBAAA;EAAA,SACD,EAAA;EAAA,SACA,WAAW;AAAA;AAAA,KAGV,6BAAA;EAAA,SACD,KAAA,EAAO,oBAAoB;EAAA,SAC3B,WAAA;AAAA;AAAA,KAGC,2BAAA;EAAA,SACD,MAAA,GAAS,aAAA,CAAc,mBAAA;EAAA,SACvB,gBAAA,GAAmB,aAAA,CAAc,6BAAA;AAAA;AAAA,KAGhC,mBAAA;EAAA,SACD,QAAQ;AAAA;AAAA,KAGP,kBAAA;EAAA,SACD,IAAA,EAAM,QAAA;EAAA,SACN,OAAA,EAAS,OAAA;EAAA,SACT,MAAA,EAAQ,cAAA;AAAA;AAAA,KAGP,eAAA,YAA2B,2BAAA;EAAA,SAC5B,SAAA,EAAW,aAAA,CAAc,sBAAA;EAAA,SACzB,SAAA,IAAa,OAAA,EAAS,OAAA,KAAY,MAAA,CAAO,MAAA,UAAgB,iBAAA;EAAA,SACzD,OAAA,GAAU,KAAA,EAAO,kBAAA,CAAmB,OAAA,MAAa,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,SAAA;AAAA;AAAA,KAG1E,mBAAA;EAAA,SACD,MAAA;EAAA,SACA,MAAA;EAAA,SACA,YAAA;EAAA,SACA,WAAA;EAAA,SACA,aAAA;EAAA,SACA,WAAA;EAAA,SACA,SAAA;EAAA,SACA,KAAA;EAAA,SACA,eAAA,GAAkB,oBAAoB;EAAA,SACtC,OAAA;AAAA;AAAA,cA2JE,wBAAA,YACX,OAAA,EAAS,eAAA,CAAgB,OAAA,MACxB,gBAAA,CAAiB,OAAA;AAAA,cAwBP,eAAA,GACX,SAAA,EAAW,aAAA,CAAc,sBAAA,GACzB,iBAAA,GAAmB,2BAAA,wCAAgC,OAAA;AAAA,cAQxC,kBAAA,YACX,OAAA,EAAS,eAAA,CAAgB,OAAA,MACxB,UAAA,CAAW,OAAA;AAAA,cAKD,8BAAA,mBAAkD,mBAAA,EAC7D,OAAA,EAAS,eAAA,CAAgB,OAAA,MACxB,UAAA,CAAW,OAAA;AAAA,cAWD,gBAAA,GAAoB,MAAc;AAAA,cAGlC,iBAAA,GAAiB,gBAAA;AAAA,cAQjB,kBAAA,GAAsB,MAAA,EAAQ,aAAa,CAAC,UAAA;AAAA,cAO5C,kBAAA,GAAsB,KAAA,EAAO,mBAAA,KAAmB,UAgBzD"}
|
package/dist/tools/task.mjs
CHANGED
|
@@ -5,11 +5,11 @@ import * as Schema from "effect/Schema";
|
|
|
5
5
|
import { ToolError } from "@yolk-sdk/agent/loop";
|
|
6
6
|
//#region src/tools/task.ts
|
|
7
7
|
const taskToolName = "task";
|
|
8
|
-
const
|
|
8
|
+
const TaskToolBaseFields = {
|
|
9
9
|
description: Schema.String.pipe(Schema.annotate({ description: "A short 3-5 word description of the task." })),
|
|
10
10
|
prompt: Schema.String.pipe(Schema.annotate({ description: "The complete task instructions for the subagent, including all context it needs." })),
|
|
11
11
|
subagent_type: Schema.String.pipe(Schema.annotate({ description: "The specialized subagent type to use for this task." }))
|
|
12
|
-
}
|
|
12
|
+
};
|
|
13
13
|
const taskToolError = (message, cause) => new ToolError({
|
|
14
14
|
tool: taskToolName,
|
|
15
15
|
message,
|
|
@@ -20,10 +20,38 @@ const taskModelVisibleError = (message) => modelVisibleToolError({
|
|
|
20
20
|
message,
|
|
21
21
|
reason: "validation"
|
|
22
22
|
});
|
|
23
|
+
const enumRecord = (values) => Object.fromEntries(values.map((value) => [value, value]));
|
|
24
|
+
const optionalRuntimeSelection = (input) => Schema.optionalKey(Schema.Enum(enumRecord(input.values)).pipe(Schema.annotate({ description: input.description })));
|
|
25
|
+
const configuredTaskToolParams = (options) => {
|
|
26
|
+
const model = options.models === void 0 || options.models.length === 0 ? void 0 : optionalRuntimeSelection({
|
|
27
|
+
values: options.models.map((item) => item.id),
|
|
28
|
+
description: "Model for this subagent. Omit to inherit the host runtime model."
|
|
29
|
+
});
|
|
30
|
+
const reasoningEffort = options.reasoningEfforts === void 0 || options.reasoningEfforts.length === 0 ? void 0 : optionalRuntimeSelection({
|
|
31
|
+
values: options.reasoningEfforts.map((item) => item.value),
|
|
32
|
+
description: "Reasoning effort for this subagent. Omit to inherit the host runtime effort."
|
|
33
|
+
});
|
|
34
|
+
if (model !== void 0 && reasoningEffort !== void 0) return Schema.Struct({
|
|
35
|
+
...TaskToolBaseFields,
|
|
36
|
+
model,
|
|
37
|
+
reasoning_effort: reasoningEffort
|
|
38
|
+
});
|
|
39
|
+
if (model !== void 0) return Schema.Struct({
|
|
40
|
+
...TaskToolBaseFields,
|
|
41
|
+
model
|
|
42
|
+
});
|
|
43
|
+
if (reasoningEffort !== void 0) return Schema.Struct({
|
|
44
|
+
...TaskToolBaseFields,
|
|
45
|
+
reasoning_effort: reasoningEffort
|
|
46
|
+
});
|
|
47
|
+
return Schema.Struct(TaskToolBaseFields);
|
|
48
|
+
};
|
|
23
49
|
const trimmedTaskParams = (params) => ({
|
|
24
50
|
description: params.description.trim(),
|
|
25
51
|
prompt: params.prompt.trim(),
|
|
26
|
-
subagent_type: params.subagent_type.trim()
|
|
52
|
+
subagent_type: params.subagent_type.trim(),
|
|
53
|
+
...params.model === void 0 ? {} : { model: params.model },
|
|
54
|
+
...params.reasoning_effort === void 0 ? {} : { reasoning_effort: params.reasoning_effort }
|
|
27
55
|
});
|
|
28
56
|
const validateTaskParams = (params) => {
|
|
29
57
|
const trimmed = trimmedTaskParams(params);
|
|
@@ -38,19 +66,31 @@ const requireKnownSubagent = (subagents, name) => {
|
|
|
38
66
|
return subagent === void 0 ? Effect.fail(taskModelVisibleError(`Unknown subagent type: ${name}`)) : Effect.succeed(subagent);
|
|
39
67
|
};
|
|
40
68
|
const subagentDescription = (subagent) => `- ${subagent.name}: ${subagent.description}`;
|
|
41
|
-
const
|
|
69
|
+
const modelDescription = (model) => `- ${model.id}: ${model.description}`;
|
|
70
|
+
const reasoningEffortDescription = (effort) => `- ${effort.value}: ${effort.description}`;
|
|
71
|
+
const taskToolDescription = (options) => [
|
|
42
72
|
"Launch a new agent to handle complex, multistep tasks autonomously.",
|
|
43
73
|
"Use this when delegating focused work to a specialized subagent would save context or allow parallel exploration.",
|
|
44
74
|
"To run subagents in parallel, call this task tool multiple times in the same assistant response.",
|
|
45
75
|
"Yolk runs same-turn task calls concurrently automatically.",
|
|
46
76
|
"A fresh subagent only sees the prompt you provide, so include all required context.",
|
|
47
77
|
"Subagents can use their normal tools but cannot launch further task subagents in v1.",
|
|
48
|
-
subagents.length === 0 ? "No subagent types are currently available." : `Available subagent types:\n${subagents.map(subagentDescription).join("\n")}
|
|
49
|
-
|
|
78
|
+
options.subagents.length === 0 ? "No subagent types are currently available." : `Available subagent types:\n${options.subagents.map(subagentDescription).join("\n")}`,
|
|
79
|
+
options.models === void 0 || options.models.length === 0 ? void 0 : [
|
|
80
|
+
"Available subagent models:",
|
|
81
|
+
options.models.map(modelDescription).join("\n"),
|
|
82
|
+
"Omit model to inherit the host runtime model."
|
|
83
|
+
].join("\n"),
|
|
84
|
+
options.reasoningEfforts === void 0 || options.reasoningEfforts.length === 0 ? void 0 : [
|
|
85
|
+
"Available subagent reasoning efforts:",
|
|
86
|
+
options.reasoningEfforts.map(reasoningEffortDescription).join("\n"),
|
|
87
|
+
"Omit reasoning_effort to inherit the host runtime effort."
|
|
88
|
+
].join("\n")
|
|
89
|
+
].filter((section) => section !== void 0).join("\n\n");
|
|
50
90
|
const makeTaskToolRegistration = (options) => makeTool({
|
|
51
91
|
name: taskToolName,
|
|
52
|
-
description: taskToolDescription(options
|
|
53
|
-
parameters:
|
|
92
|
+
description: taskToolDescription(options),
|
|
93
|
+
parameters: configuredTaskToolParams(options),
|
|
54
94
|
access: "read",
|
|
55
95
|
isEnabled: options.isEnabled,
|
|
56
96
|
invalidParamsMessage: (error) => `Invalid task arguments: ${error instanceof Error ? error.message : String(error)}`,
|
|
@@ -65,8 +105,9 @@ const makeTaskToolRegistration = (options) => makeTool({
|
|
|
65
105
|
});
|
|
66
106
|
})
|
|
67
107
|
});
|
|
68
|
-
const makeTaskToolDef = (subagents) => makeTaskToolRegistration({
|
|
108
|
+
const makeTaskToolDef = (subagents, runtimeSelections = {}) => makeTaskToolRegistration({
|
|
69
109
|
subagents,
|
|
110
|
+
...runtimeSelections,
|
|
70
111
|
execute: ({ call }) => Effect.succeed(ToolResult.make({
|
|
71
112
|
toolCallId: call.id,
|
|
72
113
|
content: ""
|
|
@@ -106,7 +147,8 @@ const makeTaskToolResult = (input) => ToolResult.make({
|
|
|
106
147
|
ended_at_ms: input.endedAtMs,
|
|
107
148
|
duration_ms: Math.max(0, input.endedAtMs - input.startedAtMs),
|
|
108
149
|
status: input.isError === true ? "error" : "completed",
|
|
109
|
-
model: input.model
|
|
150
|
+
model: input.model,
|
|
151
|
+
...input.reasoningEffort === void 0 ? {} : { reasoning_effort: input.reasoningEffort }
|
|
110
152
|
}
|
|
111
153
|
});
|
|
112
154
|
//#endregion
|
package/dist/tools/task.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task.mjs","names":[],"sources":["../../src/tools/task.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport { ToolError } from '@yolk-sdk/agent/loop'\nimport {\n assistantContent,\n contentText,\n makeSubagentRunId,\n ToolResult,\n type AgentEvent,\n type AgentMessage,\n type ToolCall\n} from '@yolk-sdk/agent/protocol'\nimport {\n makeTool,\n modelVisibleToolError,\n type ModelVisibleToolError,\n type ToolModule,\n type ToolRegistration,\n type ToolRegistryError\n} from './registry.ts'\n\nexport const taskToolName = 'task'\n\nconst TaskToolParams = Schema.Struct({\n description: Schema.String.pipe(\n Schema.annotate({ description: 'A short 3-5 word description of the task.' })\n ),\n prompt: Schema.String.pipe(\n Schema.annotate({\n description:\n 'The complete task instructions for the subagent, including all context it needs.'\n })\n ),\n subagent_type: Schema.String.pipe(\n Schema.annotate({ description: 'The specialized subagent type to use for this task.' })\n )\n})\n\nexport type TaskToolParams = typeof TaskToolParams.Type\n\nexport type TaskSubagentDefinition = {\n readonly name: string\n readonly description: string\n}\n\nexport type TaskSubagentContext = {\n readonly subagent?: boolean\n}\n\nexport type TaskExecutionInput<Context> = {\n readonly call: ToolCall\n readonly context: Context\n readonly params: TaskToolParams\n}\n\nexport type TaskToolOptions<Context> = {\n readonly subagents: ReadonlyArray<TaskSubagentDefinition>\n readonly isEnabled?: (context: Context) => Effect.Effect<boolean, ToolRegistryError>\n readonly execute: (input: TaskExecutionInput<Context>) => Effect.Effect<ToolResult, ToolError>\n}\n\nexport type TaskToolResultInput = {\n readonly callId: string\n readonly output: string\n readonly subagentType: string\n readonly description: string\n readonly subagentRunId: string\n readonly startedAtMs: number\n readonly endedAtMs: number\n readonly model: string\n readonly isError?: boolean\n}\n\nconst taskToolError = (message: string, cause: ToolError['cause']) =>\n new ToolError({\n tool: taskToolName,\n message,\n cause\n })\n\nconst taskModelVisibleError = (message: string) =>\n modelVisibleToolError({\n tool: taskToolName,\n message,\n reason: 'validation'\n })\n\nconst trimmedTaskParams = (params: TaskToolParams) => ({\n description: params.description.trim(),\n prompt: params.prompt.trim(),\n subagent_type: params.subagent_type.trim()\n})\n\nconst validateTaskParams = (\n params: TaskToolParams\n): Effect.Effect<\n {\n readonly description: string\n readonly prompt: string\n readonly subagent_type: string\n },\n ModelVisibleToolError\n> => {\n const trimmed = trimmedTaskParams(params)\n\n if (trimmed.description.length === 0) {\n return Effect.fail(taskModelVisibleError('description must not be empty'))\n }\n\n if (trimmed.prompt.length === 0) {\n return Effect.fail(taskModelVisibleError('prompt must not be empty'))\n }\n\n if (trimmed.subagent_type.length === 0) {\n return Effect.fail(taskModelVisibleError('subagent_type must not be empty'))\n }\n\n return Effect.succeed(trimmed)\n}\n\nconst findSubagent = (subagents: ReadonlyArray<TaskSubagentDefinition>, name: string) =>\n subagents.find(subagent => subagent.name === name)\n\nconst requireKnownSubagent = (\n subagents: ReadonlyArray<TaskSubagentDefinition>,\n name: string\n): Effect.Effect<TaskSubagentDefinition, ModelVisibleToolError> => {\n const subagent = findSubagent(subagents, name)\n\n return subagent === undefined\n ? Effect.fail(taskModelVisibleError(`Unknown subagent type: ${name}`))\n : Effect.succeed(subagent)\n}\n\nconst subagentDescription = (subagent: TaskSubagentDefinition) =>\n `- ${subagent.name}: ${subagent.description}`\n\nconst taskToolDescription = (subagents: ReadonlyArray<TaskSubagentDefinition>) =>\n [\n 'Launch a new agent to handle complex, multistep tasks autonomously.',\n 'Use this when delegating focused work to a specialized subagent would save context or allow parallel exploration.',\n 'To run subagents in parallel, call this task tool multiple times in the same assistant response.',\n 'Yolk runs same-turn task calls concurrently automatically.',\n 'A fresh subagent only sees the prompt you provide, so include all required context.',\n 'Subagents can use their normal tools but cannot launch further task subagents in v1.',\n subagents.length === 0\n ? 'No subagent types are currently available.'\n : `Available subagent types:\\n${subagents.map(subagentDescription).join('\\n')}`\n ].join('\\n\\n')\n\nexport const makeTaskToolRegistration = <Context>(\n options: TaskToolOptions<Context>\n): ToolRegistration<Context> =>\n makeTool({\n name: taskToolName,\n description: taskToolDescription(options.subagents),\n parameters: TaskToolParams,\n access: 'read',\n isEnabled: options.isEnabled,\n invalidParamsMessage: error =>\n `Invalid task arguments: ${error instanceof Error ? error.message : String(error)}`,\n execute: ({ call, context, params }) =>\n Effect.gen(function* () {\n if (call.name !== taskToolName) {\n return yield* Effect.fail(\n taskToolError(`Tool is not configured: ${call.name}`, 'not_found')\n )\n }\n\n const normalizedParams = yield* validateTaskParams(params)\n yield* requireKnownSubagent(options.subagents, normalizedParams.subagent_type)\n\n return yield* options.execute({ call, context, params: normalizedParams })\n })\n })\n\nexport const makeTaskToolDef = (subagents: ReadonlyArray<TaskSubagentDefinition>) =>\n makeTaskToolRegistration({\n subagents,\n execute: ({ call }) => Effect.succeed(ToolResult.make({ toolCallId: call.id, content: '' }))\n }).def\n\nexport const makeTaskToolModule = <Context>(\n options: TaskToolOptions<Context>\n): ToolModule<Context> => ({\n id: 'task',\n tools: [makeTaskToolRegistration(options)]\n})\n\nexport const makeNonRecursiveTaskToolModule = <Context extends TaskSubagentContext>(\n options: TaskToolOptions<Context>\n): ToolModule<Context> =>\n makeTaskToolModule({\n ...options,\n isEnabled: context =>\n context.subagent === true\n ? Effect.succeed(false)\n : options.isEnabled === undefined\n ? Effect.succeed(true)\n : options.isEnabled(context)\n })\n\nexport const formatTaskResult = (output: string) =>\n ['<task_result>', output, '</task_result>'].join('\\n')\n\nexport const taskSubagentRunId = makeSubagentRunId\n\nconst latestAssistantText = (messages: ReadonlyArray<AgentMessage>) => {\n const assistant = [...messages].reverse().find(message => message._tag === 'Assistant')\n\n return assistant === undefined ? '' : contentText(assistantContent(assistant))\n}\n\nexport const subagentResultText = (events: ReadonlyArray<AgentEvent>) => {\n const messages = [...events].reverse().find(event => event._tag === 'AgentEnd')?.messages ?? []\n const text = latestAssistantText(messages).trim()\n\n return text.length === 0 ? 'Subagent completed without a final text response.' : text\n}\n\nexport const makeTaskToolResult = (input: TaskToolResultInput) =>\n ToolResult.make({\n toolCallId: input.callId,\n content: formatTaskResult(input.output),\n isError: input.isError,\n structuredContent: {\n subagent_run_id: input.subagentRunId,\n subagent_type: input.subagentType,\n description: input.description,\n started_at_ms: input.startedAtMs,\n ended_at_ms: input.endedAtMs,\n duration_ms: Math.max(0, input.endedAtMs - input.startedAtMs),\n status: input.isError === true ? 'error' : 'completed',\n model: input.model\n }\n })\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"task.mjs","names":[],"sources":["../../src/tools/task.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport { ToolError } from '@yolk-sdk/agent/loop'\nimport {\n assistantContent,\n contentText,\n makeSubagentRunId,\n ToolResult,\n type AgentEvent,\n type AgentMessage,\n type AgentReasoningEffort,\n type ToolCall\n} from '@yolk-sdk/agent/protocol'\nimport {\n makeTool,\n modelVisibleToolError,\n type ModelVisibleToolError,\n type ToolModule,\n type ToolRegistration,\n type ToolRegistryError\n} from './registry.ts'\n\nexport const taskToolName = 'task'\n\nconst TaskToolBaseFields = {\n description: Schema.String.pipe(\n Schema.annotate({ description: 'A short 3-5 word description of the task.' })\n ),\n prompt: Schema.String.pipe(\n Schema.annotate({\n description:\n 'The complete task instructions for the subagent, including all context it needs.'\n })\n ),\n subagent_type: Schema.String.pipe(\n Schema.annotate({ description: 'The specialized subagent type to use for this task.' })\n )\n}\n\nexport type TaskToolParams = {\n readonly description: string\n readonly prompt: string\n readonly subagent_type: string\n readonly model?: string\n readonly reasoning_effort?: AgentReasoningEffort\n}\n\nexport type TaskSubagentDefinition = {\n readonly name: string\n readonly description: string\n}\n\nexport type TaskModelDefinition = {\n readonly id: string\n readonly description: string\n}\n\nexport type TaskReasoningEffortDefinition = {\n readonly value: AgentReasoningEffort\n readonly description: string\n}\n\nexport type TaskRuntimeSelectionOptions = {\n readonly models?: ReadonlyArray<TaskModelDefinition>\n readonly reasoningEfforts?: ReadonlyArray<TaskReasoningEffortDefinition>\n}\n\nexport type TaskSubagentContext = {\n readonly subagent?: boolean\n}\n\nexport type TaskExecutionInput<Context> = {\n readonly call: ToolCall\n readonly context: Context\n readonly params: TaskToolParams\n}\n\nexport type TaskToolOptions<Context> = TaskRuntimeSelectionOptions & {\n readonly subagents: ReadonlyArray<TaskSubagentDefinition>\n readonly isEnabled?: (context: Context) => Effect.Effect<boolean, ToolRegistryError>\n readonly execute: (input: TaskExecutionInput<Context>) => Effect.Effect<ToolResult, ToolError>\n}\n\nexport type TaskToolResultInput = {\n readonly callId: string\n readonly output: string\n readonly subagentType: string\n readonly description: string\n readonly subagentRunId: string\n readonly startedAtMs: number\n readonly endedAtMs: number\n readonly model: string\n readonly reasoningEffort?: AgentReasoningEffort\n readonly isError?: boolean\n}\n\nconst taskToolError = (message: string, cause: ToolError['cause']) =>\n new ToolError({\n tool: taskToolName,\n message,\n cause\n })\n\nconst taskModelVisibleError = (message: string) =>\n modelVisibleToolError({\n tool: taskToolName,\n message,\n reason: 'validation'\n })\n\nconst enumRecord = <Value extends string>(\n values: ReadonlyArray<Value>\n): Readonly<Record<string, Value>> => Object.fromEntries(values.map(value => [value, value]))\n\nconst optionalRuntimeSelection = <Value extends string>(input: {\n readonly values: ReadonlyArray<Value>\n readonly description: string\n}) =>\n Schema.optionalKey(\n Schema.Enum(enumRecord(input.values)).pipe(Schema.annotate({ description: input.description }))\n )\n\nconst configuredTaskToolParams = (options: TaskRuntimeSelectionOptions) => {\n const model =\n options.models === undefined || options.models.length === 0\n ? undefined\n : optionalRuntimeSelection({\n values: options.models.map(item => item.id),\n description: 'Model for this subagent. Omit to inherit the host runtime model.'\n })\n const reasoningEffort =\n options.reasoningEfforts === undefined || options.reasoningEfforts.length === 0\n ? undefined\n : optionalRuntimeSelection({\n values: options.reasoningEfforts.map(item => item.value),\n description:\n 'Reasoning effort for this subagent. Omit to inherit the host runtime effort.'\n })\n\n if (model !== undefined && reasoningEffort !== undefined) {\n return Schema.Struct({\n ...TaskToolBaseFields,\n model,\n reasoning_effort: reasoningEffort\n })\n }\n\n if (model !== undefined) {\n return Schema.Struct({ ...TaskToolBaseFields, model })\n }\n\n if (reasoningEffort !== undefined) {\n return Schema.Struct({ ...TaskToolBaseFields, reasoning_effort: reasoningEffort })\n }\n\n return Schema.Struct(TaskToolBaseFields)\n}\n\nconst trimmedTaskParams = (params: TaskToolParams): TaskToolParams => ({\n description: params.description.trim(),\n prompt: params.prompt.trim(),\n subagent_type: params.subagent_type.trim(),\n ...(params.model === undefined ? {} : { model: params.model }),\n ...(params.reasoning_effort === undefined ? {} : { reasoning_effort: params.reasoning_effort })\n})\n\nconst validateTaskParams = (\n params: TaskToolParams\n): Effect.Effect<\n {\n readonly description: string\n readonly prompt: string\n readonly subagent_type: string\n },\n ModelVisibleToolError\n> => {\n const trimmed = trimmedTaskParams(params)\n\n if (trimmed.description.length === 0) {\n return Effect.fail(taskModelVisibleError('description must not be empty'))\n }\n\n if (trimmed.prompt.length === 0) {\n return Effect.fail(taskModelVisibleError('prompt must not be empty'))\n }\n\n if (trimmed.subagent_type.length === 0) {\n return Effect.fail(taskModelVisibleError('subagent_type must not be empty'))\n }\n\n return Effect.succeed(trimmed)\n}\n\nconst findSubagent = (subagents: ReadonlyArray<TaskSubagentDefinition>, name: string) =>\n subagents.find(subagent => subagent.name === name)\n\nconst requireKnownSubagent = (\n subagents: ReadonlyArray<TaskSubagentDefinition>,\n name: string\n): Effect.Effect<TaskSubagentDefinition, ModelVisibleToolError> => {\n const subagent = findSubagent(subagents, name)\n\n return subagent === undefined\n ? Effect.fail(taskModelVisibleError(`Unknown subagent type: ${name}`))\n : Effect.succeed(subagent)\n}\n\nconst subagentDescription = (subagent: TaskSubagentDefinition) =>\n `- ${subagent.name}: ${subagent.description}`\n\nconst modelDescription = (model: TaskModelDefinition) => `- ${model.id}: ${model.description}`\n\nconst reasoningEffortDescription = (effort: TaskReasoningEffortDefinition) =>\n `- ${effort.value}: ${effort.description}`\n\nconst taskToolDescription = (\n options: TaskRuntimeSelectionOptions & {\n readonly subagents: ReadonlyArray<TaskSubagentDefinition>\n }\n) =>\n [\n 'Launch a new agent to handle complex, multistep tasks autonomously.',\n 'Use this when delegating focused work to a specialized subagent would save context or allow parallel exploration.',\n 'To run subagents in parallel, call this task tool multiple times in the same assistant response.',\n 'Yolk runs same-turn task calls concurrently automatically.',\n 'A fresh subagent only sees the prompt you provide, so include all required context.',\n 'Subagents can use their normal tools but cannot launch further task subagents in v1.',\n options.subagents.length === 0\n ? 'No subagent types are currently available.'\n : `Available subagent types:\\n${options.subagents.map(subagentDescription).join('\\n')}`,\n options.models === undefined || options.models.length === 0\n ? undefined\n : [\n 'Available subagent models:',\n options.models.map(modelDescription).join('\\n'),\n 'Omit model to inherit the host runtime model.'\n ].join('\\n'),\n options.reasoningEfforts === undefined || options.reasoningEfforts.length === 0\n ? undefined\n : [\n 'Available subagent reasoning efforts:',\n options.reasoningEfforts.map(reasoningEffortDescription).join('\\n'),\n 'Omit reasoning_effort to inherit the host runtime effort.'\n ].join('\\n')\n ]\n .filter(section => section !== undefined)\n .join('\\n\\n')\n\nexport const makeTaskToolRegistration = <Context>(\n options: TaskToolOptions<Context>\n): ToolRegistration<Context> =>\n makeTool({\n name: taskToolName,\n description: taskToolDescription(options),\n parameters: configuredTaskToolParams(options),\n access: 'read',\n isEnabled: options.isEnabled,\n invalidParamsMessage: error =>\n `Invalid task arguments: ${error instanceof Error ? error.message : String(error)}`,\n execute: ({ call, context, params }) =>\n Effect.gen(function* () {\n if (call.name !== taskToolName) {\n return yield* Effect.fail(\n taskToolError(`Tool is not configured: ${call.name}`, 'not_found')\n )\n }\n\n const normalizedParams = yield* validateTaskParams(params)\n yield* requireKnownSubagent(options.subagents, normalizedParams.subagent_type)\n\n return yield* options.execute({ call, context, params: normalizedParams })\n })\n })\n\nexport const makeTaskToolDef = (\n subagents: ReadonlyArray<TaskSubagentDefinition>,\n runtimeSelections: TaskRuntimeSelectionOptions = {}\n) =>\n makeTaskToolRegistration({\n subagents,\n ...runtimeSelections,\n execute: ({ call }) => Effect.succeed(ToolResult.make({ toolCallId: call.id, content: '' }))\n }).def\n\nexport const makeTaskToolModule = <Context>(\n options: TaskToolOptions<Context>\n): ToolModule<Context> => ({\n id: 'task',\n tools: [makeTaskToolRegistration(options)]\n})\n\nexport const makeNonRecursiveTaskToolModule = <Context extends TaskSubagentContext>(\n options: TaskToolOptions<Context>\n): ToolModule<Context> =>\n makeTaskToolModule({\n ...options,\n isEnabled: context =>\n context.subagent === true\n ? Effect.succeed(false)\n : options.isEnabled === undefined\n ? Effect.succeed(true)\n : options.isEnabled(context)\n })\n\nexport const formatTaskResult = (output: string) =>\n ['<task_result>', output, '</task_result>'].join('\\n')\n\nexport const taskSubagentRunId = makeSubagentRunId\n\nconst latestAssistantText = (messages: ReadonlyArray<AgentMessage>) => {\n const assistant = [...messages].reverse().find(message => message._tag === 'Assistant')\n\n return assistant === undefined ? '' : contentText(assistantContent(assistant))\n}\n\nexport const subagentResultText = (events: ReadonlyArray<AgentEvent>) => {\n const messages = [...events].reverse().find(event => event._tag === 'AgentEnd')?.messages ?? []\n const text = latestAssistantText(messages).trim()\n\n return text.length === 0 ? 'Subagent completed without a final text response.' : text\n}\n\nexport const makeTaskToolResult = (input: TaskToolResultInput) =>\n ToolResult.make({\n toolCallId: input.callId,\n content: formatTaskResult(input.output),\n isError: input.isError,\n structuredContent: {\n subagent_run_id: input.subagentRunId,\n subagent_type: input.subagentType,\n description: input.description,\n started_at_ms: input.startedAtMs,\n ended_at_ms: input.endedAtMs,\n duration_ms: Math.max(0, input.endedAtMs - input.startedAtMs),\n status: input.isError === true ? 'error' : 'completed',\n model: input.model,\n ...(input.reasoningEffort === undefined ? {} : { reasoning_effort: input.reasoningEffort })\n }\n })\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yolk-sdk/agent",
|
|
3
|
-
"version": "0.1.0-canary.
|
|
3
|
+
"version": "0.1.0-canary.53",
|
|
4
4
|
"description": "Protocol, loop, runtime, client, compaction, tools, React, providers, OAuth, skillset, and voice primitives for building Yolk agents.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/src/tools/README.md
CHANGED
|
@@ -51,7 +51,11 @@ aborts, and implementation bugs outside typed tool execution.
|
|
|
51
51
|
|
|
52
52
|
`task` is the standard tool for delegating focused work to a subagent. The SDK owns the
|
|
53
53
|
tool schema, validation, event metadata shape, and result formatting. Host apps still own
|
|
54
|
-
execution: model
|
|
54
|
+
execution: available model/reasoning choices, provider layers, prompts, auth, concrete tools,
|
|
55
|
+
storage, and policy. When choices are configured, the tool exposes optional `model` and
|
|
56
|
+
`reasoning_effort` fields; omission lets the host inherit its current runtime settings. Model ids
|
|
57
|
+
are opaque host values. Reasoning effort values are `minimal`, `low`, `medium`, `high`, and
|
|
58
|
+
`xhigh`.
|
|
55
59
|
|
|
56
60
|
Use `makeNonRecursiveTaskToolModule` for the top-level agent so nested subagents do not receive
|
|
57
61
|
`task` again:
|
|
@@ -77,10 +81,20 @@ const taskToolModule = makeNonRecursiveTaskToolModule<ToolContext>({
|
|
|
77
81
|
{ name: 'general', description: 'Handle complex multi-step work.' },
|
|
78
82
|
{ name: 'explore', description: 'Explore code and docs.' }
|
|
79
83
|
],
|
|
84
|
+
models: [
|
|
85
|
+
{ id: 'gpt-5.5', description: 'Strong general-purpose model.' },
|
|
86
|
+
{ id: 'fast-model', description: 'Fast model for focused exploration.' }
|
|
87
|
+
],
|
|
88
|
+
reasoningEfforts: [
|
|
89
|
+
{ value: 'medium', description: 'Balanced default for normal exploration.' },
|
|
90
|
+
{ value: 'high', description: 'Use for difficult reasoning.' }
|
|
91
|
+
],
|
|
80
92
|
execute: ({ call, context, params }) =>
|
|
81
93
|
Effect.gen(function* () {
|
|
82
94
|
const startedAtMs = yield* Clock.currentTimeMillis
|
|
83
95
|
const subagentRunId = makeSubagentRunId(call.id)
|
|
96
|
+
const model = params.model ?? 'gpt-5.5'
|
|
97
|
+
const reasoningEffort = params.reasoning_effort ?? 'medium'
|
|
84
98
|
const subagentToolSet = yield* resolveSubagentToolSet({
|
|
85
99
|
...context,
|
|
86
100
|
subagent: true
|
|
@@ -89,7 +103,8 @@ const taskToolModule = makeNonRecursiveTaskToolModule<ToolContext>({
|
|
|
89
103
|
messages: [UserMessage.make({ content: params.prompt })],
|
|
90
104
|
systemPrompt: subagentSystemPrompt(params.subagent_type),
|
|
91
105
|
tools: subagentToolSet.tools,
|
|
92
|
-
model
|
|
106
|
+
model,
|
|
107
|
+
reasoningEffort
|
|
93
108
|
}).pipe(Stream.runCollect, Effect.provide(makeToolExecutorLayer(subagentToolSet)))
|
|
94
109
|
const endedAtMs = yield* Clock.currentTimeMillis
|
|
95
110
|
|
|
@@ -101,12 +116,17 @@ const taskToolModule = makeNonRecursiveTaskToolModule<ToolContext>({
|
|
|
101
116
|
subagentRunId,
|
|
102
117
|
startedAtMs,
|
|
103
118
|
endedAtMs,
|
|
104
|
-
model
|
|
119
|
+
model,
|
|
120
|
+
reasoningEffort
|
|
105
121
|
})
|
|
106
122
|
})
|
|
107
123
|
})
|
|
108
124
|
```
|
|
109
125
|
|
|
126
|
+
Host apps should advertise only runtime choices they can execute. If support depends on the
|
|
127
|
+
selected model, validate the model/reasoning combination before constructing the child provider
|
|
128
|
+
layer and return a model-visible error for unsupported combinations.
|
|
129
|
+
|
|
110
130
|
Host apps should usually resolve a smaller subagent toolset:
|
|
111
131
|
|
|
112
132
|
- include read/search tools that help delegated work
|
package/src/tools/index.ts
CHANGED
|
@@ -42,6 +42,9 @@ export type {
|
|
|
42
42
|
export type { QuestionExecutionInput, QuestionToolOptions } from './question.ts'
|
|
43
43
|
export type {
|
|
44
44
|
TaskExecutionInput,
|
|
45
|
+
TaskModelDefinition,
|
|
46
|
+
TaskReasoningEffortDefinition,
|
|
47
|
+
TaskRuntimeSelectionOptions,
|
|
45
48
|
TaskSubagentContext,
|
|
46
49
|
TaskSubagentDefinition,
|
|
47
50
|
TaskToolOptions,
|
package/src/tools/task.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
ToolResult,
|
|
9
9
|
type AgentEvent,
|
|
10
10
|
type AgentMessage,
|
|
11
|
+
type AgentReasoningEffort,
|
|
11
12
|
type ToolCall
|
|
12
13
|
} from '@yolk-sdk/agent/protocol'
|
|
13
14
|
import {
|
|
@@ -21,7 +22,7 @@ import {
|
|
|
21
22
|
|
|
22
23
|
export const taskToolName = 'task'
|
|
23
24
|
|
|
24
|
-
const
|
|
25
|
+
const TaskToolBaseFields = {
|
|
25
26
|
description: Schema.String.pipe(
|
|
26
27
|
Schema.annotate({ description: 'A short 3-5 word description of the task.' })
|
|
27
28
|
),
|
|
@@ -34,15 +35,36 @@ const TaskToolParams = Schema.Struct({
|
|
|
34
35
|
subagent_type: Schema.String.pipe(
|
|
35
36
|
Schema.annotate({ description: 'The specialized subagent type to use for this task.' })
|
|
36
37
|
)
|
|
37
|
-
}
|
|
38
|
+
}
|
|
38
39
|
|
|
39
|
-
export type TaskToolParams =
|
|
40
|
+
export type TaskToolParams = {
|
|
41
|
+
readonly description: string
|
|
42
|
+
readonly prompt: string
|
|
43
|
+
readonly subagent_type: string
|
|
44
|
+
readonly model?: string
|
|
45
|
+
readonly reasoning_effort?: AgentReasoningEffort
|
|
46
|
+
}
|
|
40
47
|
|
|
41
48
|
export type TaskSubagentDefinition = {
|
|
42
49
|
readonly name: string
|
|
43
50
|
readonly description: string
|
|
44
51
|
}
|
|
45
52
|
|
|
53
|
+
export type TaskModelDefinition = {
|
|
54
|
+
readonly id: string
|
|
55
|
+
readonly description: string
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export type TaskReasoningEffortDefinition = {
|
|
59
|
+
readonly value: AgentReasoningEffort
|
|
60
|
+
readonly description: string
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export type TaskRuntimeSelectionOptions = {
|
|
64
|
+
readonly models?: ReadonlyArray<TaskModelDefinition>
|
|
65
|
+
readonly reasoningEfforts?: ReadonlyArray<TaskReasoningEffortDefinition>
|
|
66
|
+
}
|
|
67
|
+
|
|
46
68
|
export type TaskSubagentContext = {
|
|
47
69
|
readonly subagent?: boolean
|
|
48
70
|
}
|
|
@@ -53,7 +75,7 @@ export type TaskExecutionInput<Context> = {
|
|
|
53
75
|
readonly params: TaskToolParams
|
|
54
76
|
}
|
|
55
77
|
|
|
56
|
-
export type TaskToolOptions<Context> = {
|
|
78
|
+
export type TaskToolOptions<Context> = TaskRuntimeSelectionOptions & {
|
|
57
79
|
readonly subagents: ReadonlyArray<TaskSubagentDefinition>
|
|
58
80
|
readonly isEnabled?: (context: Context) => Effect.Effect<boolean, ToolRegistryError>
|
|
59
81
|
readonly execute: (input: TaskExecutionInput<Context>) => Effect.Effect<ToolResult, ToolError>
|
|
@@ -68,6 +90,7 @@ export type TaskToolResultInput = {
|
|
|
68
90
|
readonly startedAtMs: number
|
|
69
91
|
readonly endedAtMs: number
|
|
70
92
|
readonly model: string
|
|
93
|
+
readonly reasoningEffort?: AgentReasoningEffort
|
|
71
94
|
readonly isError?: boolean
|
|
72
95
|
}
|
|
73
96
|
|
|
@@ -85,10 +108,60 @@ const taskModelVisibleError = (message: string) =>
|
|
|
85
108
|
reason: 'validation'
|
|
86
109
|
})
|
|
87
110
|
|
|
88
|
-
const
|
|
111
|
+
const enumRecord = <Value extends string>(
|
|
112
|
+
values: ReadonlyArray<Value>
|
|
113
|
+
): Readonly<Record<string, Value>> => Object.fromEntries(values.map(value => [value, value]))
|
|
114
|
+
|
|
115
|
+
const optionalRuntimeSelection = <Value extends string>(input: {
|
|
116
|
+
readonly values: ReadonlyArray<Value>
|
|
117
|
+
readonly description: string
|
|
118
|
+
}) =>
|
|
119
|
+
Schema.optionalKey(
|
|
120
|
+
Schema.Enum(enumRecord(input.values)).pipe(Schema.annotate({ description: input.description }))
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
const configuredTaskToolParams = (options: TaskRuntimeSelectionOptions) => {
|
|
124
|
+
const model =
|
|
125
|
+
options.models === undefined || options.models.length === 0
|
|
126
|
+
? undefined
|
|
127
|
+
: optionalRuntimeSelection({
|
|
128
|
+
values: options.models.map(item => item.id),
|
|
129
|
+
description: 'Model for this subagent. Omit to inherit the host runtime model.'
|
|
130
|
+
})
|
|
131
|
+
const reasoningEffort =
|
|
132
|
+
options.reasoningEfforts === undefined || options.reasoningEfforts.length === 0
|
|
133
|
+
? undefined
|
|
134
|
+
: optionalRuntimeSelection({
|
|
135
|
+
values: options.reasoningEfforts.map(item => item.value),
|
|
136
|
+
description:
|
|
137
|
+
'Reasoning effort for this subagent. Omit to inherit the host runtime effort.'
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
if (model !== undefined && reasoningEffort !== undefined) {
|
|
141
|
+
return Schema.Struct({
|
|
142
|
+
...TaskToolBaseFields,
|
|
143
|
+
model,
|
|
144
|
+
reasoning_effort: reasoningEffort
|
|
145
|
+
})
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (model !== undefined) {
|
|
149
|
+
return Schema.Struct({ ...TaskToolBaseFields, model })
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (reasoningEffort !== undefined) {
|
|
153
|
+
return Schema.Struct({ ...TaskToolBaseFields, reasoning_effort: reasoningEffort })
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return Schema.Struct(TaskToolBaseFields)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const trimmedTaskParams = (params: TaskToolParams): TaskToolParams => ({
|
|
89
160
|
description: params.description.trim(),
|
|
90
161
|
prompt: params.prompt.trim(),
|
|
91
|
-
subagent_type: params.subagent_type.trim()
|
|
162
|
+
subagent_type: params.subagent_type.trim(),
|
|
163
|
+
...(params.model === undefined ? {} : { model: params.model }),
|
|
164
|
+
...(params.reasoning_effort === undefined ? {} : { reasoning_effort: params.reasoning_effort })
|
|
92
165
|
})
|
|
93
166
|
|
|
94
167
|
const validateTaskParams = (
|
|
@@ -135,7 +208,16 @@ const requireKnownSubagent = (
|
|
|
135
208
|
const subagentDescription = (subagent: TaskSubagentDefinition) =>
|
|
136
209
|
`- ${subagent.name}: ${subagent.description}`
|
|
137
210
|
|
|
138
|
-
const
|
|
211
|
+
const modelDescription = (model: TaskModelDefinition) => `- ${model.id}: ${model.description}`
|
|
212
|
+
|
|
213
|
+
const reasoningEffortDescription = (effort: TaskReasoningEffortDefinition) =>
|
|
214
|
+
`- ${effort.value}: ${effort.description}`
|
|
215
|
+
|
|
216
|
+
const taskToolDescription = (
|
|
217
|
+
options: TaskRuntimeSelectionOptions & {
|
|
218
|
+
readonly subagents: ReadonlyArray<TaskSubagentDefinition>
|
|
219
|
+
}
|
|
220
|
+
) =>
|
|
139
221
|
[
|
|
140
222
|
'Launch a new agent to handle complex, multistep tasks autonomously.',
|
|
141
223
|
'Use this when delegating focused work to a specialized subagent would save context or allow parallel exploration.',
|
|
@@ -143,18 +225,34 @@ const taskToolDescription = (subagents: ReadonlyArray<TaskSubagentDefinition>) =
|
|
|
143
225
|
'Yolk runs same-turn task calls concurrently automatically.',
|
|
144
226
|
'A fresh subagent only sees the prompt you provide, so include all required context.',
|
|
145
227
|
'Subagents can use their normal tools but cannot launch further task subagents in v1.',
|
|
146
|
-
subagents.length === 0
|
|
228
|
+
options.subagents.length === 0
|
|
147
229
|
? 'No subagent types are currently available.'
|
|
148
|
-
: `Available subagent types:\n${subagents.map(subagentDescription).join('\n')}
|
|
149
|
-
|
|
230
|
+
: `Available subagent types:\n${options.subagents.map(subagentDescription).join('\n')}`,
|
|
231
|
+
options.models === undefined || options.models.length === 0
|
|
232
|
+
? undefined
|
|
233
|
+
: [
|
|
234
|
+
'Available subagent models:',
|
|
235
|
+
options.models.map(modelDescription).join('\n'),
|
|
236
|
+
'Omit model to inherit the host runtime model.'
|
|
237
|
+
].join('\n'),
|
|
238
|
+
options.reasoningEfforts === undefined || options.reasoningEfforts.length === 0
|
|
239
|
+
? undefined
|
|
240
|
+
: [
|
|
241
|
+
'Available subagent reasoning efforts:',
|
|
242
|
+
options.reasoningEfforts.map(reasoningEffortDescription).join('\n'),
|
|
243
|
+
'Omit reasoning_effort to inherit the host runtime effort.'
|
|
244
|
+
].join('\n')
|
|
245
|
+
]
|
|
246
|
+
.filter(section => section !== undefined)
|
|
247
|
+
.join('\n\n')
|
|
150
248
|
|
|
151
249
|
export const makeTaskToolRegistration = <Context>(
|
|
152
250
|
options: TaskToolOptions<Context>
|
|
153
251
|
): ToolRegistration<Context> =>
|
|
154
252
|
makeTool({
|
|
155
253
|
name: taskToolName,
|
|
156
|
-
description: taskToolDescription(options
|
|
157
|
-
parameters:
|
|
254
|
+
description: taskToolDescription(options),
|
|
255
|
+
parameters: configuredTaskToolParams(options),
|
|
158
256
|
access: 'read',
|
|
159
257
|
isEnabled: options.isEnabled,
|
|
160
258
|
invalidParamsMessage: error =>
|
|
@@ -174,9 +272,13 @@ export const makeTaskToolRegistration = <Context>(
|
|
|
174
272
|
})
|
|
175
273
|
})
|
|
176
274
|
|
|
177
|
-
export const makeTaskToolDef = (
|
|
275
|
+
export const makeTaskToolDef = (
|
|
276
|
+
subagents: ReadonlyArray<TaskSubagentDefinition>,
|
|
277
|
+
runtimeSelections: TaskRuntimeSelectionOptions = {}
|
|
278
|
+
) =>
|
|
178
279
|
makeTaskToolRegistration({
|
|
179
280
|
subagents,
|
|
281
|
+
...runtimeSelections,
|
|
180
282
|
execute: ({ call }) => Effect.succeed(ToolResult.make({ toolCallId: call.id, content: '' }))
|
|
181
283
|
}).def
|
|
182
284
|
|
|
@@ -231,6 +333,7 @@ export const makeTaskToolResult = (input: TaskToolResultInput) =>
|
|
|
231
333
|
ended_at_ms: input.endedAtMs,
|
|
232
334
|
duration_ms: Math.max(0, input.endedAtMs - input.startedAtMs),
|
|
233
335
|
status: input.isError === true ? 'error' : 'completed',
|
|
234
|
-
model: input.model
|
|
336
|
+
model: input.model,
|
|
337
|
+
...(input.reasoningEffort === undefined ? {} : { reasoning_effort: input.reasoningEffort })
|
|
235
338
|
}
|
|
236
339
|
})
|