pilotswarm-sdk 0.1.3
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/dist/agent-loader.d.ts +61 -0
- package/dist/agent-loader.d.ts.map +1 -0
- package/dist/agent-loader.js +212 -0
- package/dist/agent-loader.js.map +1 -0
- package/dist/artifact-tools.d.ts +31 -0
- package/dist/artifact-tools.d.ts.map +1 -0
- package/dist/artifact-tools.js +190 -0
- package/dist/artifact-tools.js.map +1 -0
- package/dist/blob-store.d.ts +73 -0
- package/dist/blob-store.d.ts.map +1 -0
- package/dist/blob-store.js +220 -0
- package/dist/blob-store.js.map +1 -0
- package/dist/client.d.ts +159 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +676 -0
- package/dist/client.js.map +1 -0
- package/dist/cms.d.ts +129 -0
- package/dist/cms.d.ts.map +1 -0
- package/dist/cms.js +313 -0
- package/dist/cms.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/managed-session.d.ts +70 -0
- package/dist/managed-session.d.ts.map +1 -0
- package/dist/managed-session.js +717 -0
- package/dist/managed-session.js.map +1 -0
- package/dist/management-client.d.ts +171 -0
- package/dist/management-client.d.ts.map +1 -0
- package/dist/management-client.js +401 -0
- package/dist/management-client.js.map +1 -0
- package/dist/mcp-loader.d.ts +50 -0
- package/dist/mcp-loader.d.ts.map +1 -0
- package/dist/mcp-loader.js +83 -0
- package/dist/mcp-loader.js.map +1 -0
- package/dist/model-providers.d.ts +143 -0
- package/dist/model-providers.d.ts.map +1 -0
- package/dist/model-providers.js +228 -0
- package/dist/model-providers.js.map +1 -0
- package/dist/orchestration-registry.d.ts +7 -0
- package/dist/orchestration-registry.d.ts.map +1 -0
- package/dist/orchestration-registry.js +49 -0
- package/dist/orchestration-registry.js.map +1 -0
- package/dist/orchestration.d.ts +36 -0
- package/dist/orchestration.d.ts.map +1 -0
- package/dist/orchestration.js +1357 -0
- package/dist/orchestration.js.map +1 -0
- package/dist/orchestration_1_0_0.d.ts +20 -0
- package/dist/orchestration_1_0_0.d.ts.map +1 -0
- package/dist/orchestration_1_0_0.js +497 -0
- package/dist/orchestration_1_0_0.js.map +1 -0
- package/dist/orchestration_1_0_1.d.ts +19 -0
- package/dist/orchestration_1_0_1.d.ts.map +1 -0
- package/dist/orchestration_1_0_1.js +546 -0
- package/dist/orchestration_1_0_1.js.map +1 -0
- package/dist/orchestration_1_0_10.d.ts +36 -0
- package/dist/orchestration_1_0_10.d.ts.map +1 -0
- package/dist/orchestration_1_0_10.js +1253 -0
- package/dist/orchestration_1_0_10.js.map +1 -0
- package/dist/orchestration_1_0_11.d.ts +36 -0
- package/dist/orchestration_1_0_11.d.ts.map +1 -0
- package/dist/orchestration_1_0_11.js +1255 -0
- package/dist/orchestration_1_0_11.js.map +1 -0
- package/dist/orchestration_1_0_12.d.ts +36 -0
- package/dist/orchestration_1_0_12.d.ts.map +1 -0
- package/dist/orchestration_1_0_12.js +1250 -0
- package/dist/orchestration_1_0_12.js.map +1 -0
- package/dist/orchestration_1_0_13.d.ts +36 -0
- package/dist/orchestration_1_0_13.d.ts.map +1 -0
- package/dist/orchestration_1_0_13.js +1260 -0
- package/dist/orchestration_1_0_13.js.map +1 -0
- package/dist/orchestration_1_0_14.d.ts +36 -0
- package/dist/orchestration_1_0_14.d.ts.map +1 -0
- package/dist/orchestration_1_0_14.js +1258 -0
- package/dist/orchestration_1_0_14.js.map +1 -0
- package/dist/orchestration_1_0_15.d.ts +36 -0
- package/dist/orchestration_1_0_15.d.ts.map +1 -0
- package/dist/orchestration_1_0_15.js +1266 -0
- package/dist/orchestration_1_0_15.js.map +1 -0
- package/dist/orchestration_1_0_16.d.ts +36 -0
- package/dist/orchestration_1_0_16.d.ts.map +1 -0
- package/dist/orchestration_1_0_16.js +1275 -0
- package/dist/orchestration_1_0_16.js.map +1 -0
- package/dist/orchestration_1_0_17.d.ts +36 -0
- package/dist/orchestration_1_0_17.d.ts.map +1 -0
- package/dist/orchestration_1_0_17.js +1314 -0
- package/dist/orchestration_1_0_17.js.map +1 -0
- package/dist/orchestration_1_0_18.d.ts +36 -0
- package/dist/orchestration_1_0_18.d.ts.map +1 -0
- package/dist/orchestration_1_0_18.js +1328 -0
- package/dist/orchestration_1_0_18.js.map +1 -0
- package/dist/orchestration_1_0_19.d.ts +36 -0
- package/dist/orchestration_1_0_19.d.ts.map +1 -0
- package/dist/orchestration_1_0_19.js +1324 -0
- package/dist/orchestration_1_0_19.js.map +1 -0
- package/dist/orchestration_1_0_2.d.ts +19 -0
- package/dist/orchestration_1_0_2.d.ts.map +1 -0
- package/dist/orchestration_1_0_2.js +749 -0
- package/dist/orchestration_1_0_2.js.map +1 -0
- package/dist/orchestration_1_0_20.d.ts +36 -0
- package/dist/orchestration_1_0_20.d.ts.map +1 -0
- package/dist/orchestration_1_0_20.js +1347 -0
- package/dist/orchestration_1_0_20.js.map +1 -0
- package/dist/orchestration_1_0_3.d.ts +19 -0
- package/dist/orchestration_1_0_3.d.ts.map +1 -0
- package/dist/orchestration_1_0_3.js +826 -0
- package/dist/orchestration_1_0_3.js.map +1 -0
- package/dist/orchestration_1_0_4.d.ts +19 -0
- package/dist/orchestration_1_0_4.d.ts.map +1 -0
- package/dist/orchestration_1_0_4.js +1020 -0
- package/dist/orchestration_1_0_4.js.map +1 -0
- package/dist/orchestration_1_0_5.d.ts +19 -0
- package/dist/orchestration_1_0_5.d.ts.map +1 -0
- package/dist/orchestration_1_0_5.js +1027 -0
- package/dist/orchestration_1_0_5.js.map +1 -0
- package/dist/orchestration_1_0_6.d.ts +19 -0
- package/dist/orchestration_1_0_6.d.ts.map +1 -0
- package/dist/orchestration_1_0_6.js +1034 -0
- package/dist/orchestration_1_0_6.js.map +1 -0
- package/dist/orchestration_1_0_7.d.ts +19 -0
- package/dist/orchestration_1_0_7.d.ts.map +1 -0
- package/dist/orchestration_1_0_7.js +1085 -0
- package/dist/orchestration_1_0_7.js.map +1 -0
- package/dist/orchestration_1_0_8.d.ts +36 -0
- package/dist/orchestration_1_0_8.d.ts.map +1 -0
- package/dist/orchestration_1_0_8.js +1106 -0
- package/dist/orchestration_1_0_8.js.map +1 -0
- package/dist/orchestration_1_0_9.d.ts +36 -0
- package/dist/orchestration_1_0_9.d.ts.map +1 -0
- package/dist/orchestration_1_0_9.js +1207 -0
- package/dist/orchestration_1_0_9.js.map +1 -0
- package/dist/prompt-layering.d.ts +16 -0
- package/dist/prompt-layering.d.ts.map +1 -0
- package/dist/prompt-layering.js +60 -0
- package/dist/prompt-layering.js.map +1 -0
- package/dist/resourcemgr-tools.d.ts +27 -0
- package/dist/resourcemgr-tools.d.ts.map +1 -0
- package/dist/resourcemgr-tools.js +638 -0
- package/dist/resourcemgr-tools.js.map +1 -0
- package/dist/session-dumper.d.ts +26 -0
- package/dist/session-dumper.d.ts.map +1 -0
- package/dist/session-dumper.js +272 -0
- package/dist/session-dumper.js.map +1 -0
- package/dist/session-manager.d.ts +152 -0
- package/dist/session-manager.d.ts.map +1 -0
- package/dist/session-manager.js +493 -0
- package/dist/session-manager.js.map +1 -0
- package/dist/session-proxy.d.ts +68 -0
- package/dist/session-proxy.d.ts.map +1 -0
- package/dist/session-proxy.js +665 -0
- package/dist/session-proxy.js.map +1 -0
- package/dist/session-store.d.ts +35 -0
- package/dist/session-store.d.ts.map +1 -0
- package/dist/session-store.js +88 -0
- package/dist/session-store.js.map +1 -0
- package/dist/skills.d.ts +31 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +93 -0
- package/dist/skills.js.map +1 -0
- package/dist/sweeper-tools.d.ts +28 -0
- package/dist/sweeper-tools.d.ts.map +1 -0
- package/dist/sweeper-tools.js +332 -0
- package/dist/sweeper-tools.js.map +1 -0
- package/dist/types.d.ts +498 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/worker.d.ts +128 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +562 -0
- package/dist/worker.js.map +1 -0
- package/package.json +74 -0
- package/plugins/mgmt/agents/pilotswarm.agent.md +59 -0
- package/plugins/mgmt/agents/resourcemgr.agent.md +111 -0
- package/plugins/mgmt/agents/sweeper.agent.md +67 -0
- package/plugins/mgmt/skills/resourcemgr/SKILL.md +41 -0
- package/plugins/mgmt/skills/resourcemgr/tools.json +1 -0
- package/plugins/mgmt/skills/sweeper/SKILL.md +44 -0
- package/plugins/mgmt/skills/sweeper/tools.json +1 -0
- package/plugins/system/agents/default.agent.md +58 -0
- package/plugins/system/skills/durable-timers/SKILL.md +39 -0
- package/plugins/system/skills/sub-agents/SKILL.md +75 -0
|
@@ -0,0 +1,717 @@
|
|
|
1
|
+
import { defineTool } from "@github/copilot-sdk";
|
|
2
|
+
/**
|
|
3
|
+
* ManagedSession — wraps a CopilotSession and provides the interface
|
|
4
|
+
* that the orchestration calls into (via SessionProxy).
|
|
5
|
+
*
|
|
6
|
+
* Key design decisions:
|
|
7
|
+
* 1. Uses send() + on() internally, never sendAndWait().
|
|
8
|
+
* 2. runTurn() returns a TurnResult to the orchestration — the orchestration
|
|
9
|
+
* decides what to do with wait/input_required/completed.
|
|
10
|
+
* 3. The session stays alive in memory across runTurn() calls.
|
|
11
|
+
* 4. Abort is cooperative — the orchestration cancels via race, which
|
|
12
|
+
* triggers abort() on this session.
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export class ManagedSession {
|
|
17
|
+
sessionId;
|
|
18
|
+
copilotSession;
|
|
19
|
+
config;
|
|
20
|
+
constructor(sessionId, copilotSession, config) {
|
|
21
|
+
this.sessionId = sessionId;
|
|
22
|
+
this.copilotSession = copilotSession;
|
|
23
|
+
this.config = config;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* System tool definitions for session creation.
|
|
27
|
+
* These are registered at createSession time so the LLM sees them.
|
|
28
|
+
* Handlers are placeholder stubs — real handlers are set per-turn in runTurn().
|
|
29
|
+
*/
|
|
30
|
+
static systemToolDefs() {
|
|
31
|
+
const waitTool = defineTool("wait", {
|
|
32
|
+
description: "REQUIRED: The ONLY way to wait, pause, sleep, or delay. " +
|
|
33
|
+
"You MUST call this tool whenever you need to wait, pause, delay, " +
|
|
34
|
+
"poll, check back later, schedule a future action, or implement " +
|
|
35
|
+
"any recurring/periodic task. NEVER use bash sleep, setTimeout, " +
|
|
36
|
+
"setInterval, cron, or any other timing mechanism. This tool " +
|
|
37
|
+
"enables durable waiting that survives process restarts.",
|
|
38
|
+
parameters: {
|
|
39
|
+
type: "object",
|
|
40
|
+
properties: {
|
|
41
|
+
seconds: { type: "number", description: "How long to wait in seconds" },
|
|
42
|
+
reason: { type: "string", description: "Why you're waiting" },
|
|
43
|
+
},
|
|
44
|
+
required: ["seconds"],
|
|
45
|
+
},
|
|
46
|
+
handler: async () => "stub",
|
|
47
|
+
});
|
|
48
|
+
const askUserTool = defineTool("ask_user", {
|
|
49
|
+
description: "Ask the user a question and wait for their response. " +
|
|
50
|
+
"Use this when you need clarification or user input before proceeding.",
|
|
51
|
+
parameters: {
|
|
52
|
+
type: "object",
|
|
53
|
+
properties: {
|
|
54
|
+
question: { type: "string", description: "The question to ask the user" },
|
|
55
|
+
choices: {
|
|
56
|
+
type: "array",
|
|
57
|
+
items: { type: "string" },
|
|
58
|
+
description: "Optional list of choices for the user",
|
|
59
|
+
},
|
|
60
|
+
allowFreeform: {
|
|
61
|
+
type: "boolean",
|
|
62
|
+
description: "Whether to allow freeform text input (default: true)",
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
required: ["question"],
|
|
66
|
+
},
|
|
67
|
+
handler: async () => "stub",
|
|
68
|
+
});
|
|
69
|
+
const listModelsTool = defineTool("list_available_models", {
|
|
70
|
+
description: "List all available LLM models across all configured providers. " +
|
|
71
|
+
"Returns each model's exact qualified name (provider:model), description, and cost tier. " +
|
|
72
|
+
"This output is the authoritative source for model selection. " +
|
|
73
|
+
"Use this when choosing the best model for a sub-agent task, or when the user asks about available models. " +
|
|
74
|
+
"If you plan to pass spawn_agent(model=...), you must choose an exact provider:model value from this list and must not invent or shorten names. " +
|
|
75
|
+
"When choosing a model for a sub-agent, prefer lower-cost models for simple tasks " +
|
|
76
|
+
"and higher-cost models for complex reasoning tasks.",
|
|
77
|
+
parameters: {
|
|
78
|
+
type: "object",
|
|
79
|
+
properties: {},
|
|
80
|
+
},
|
|
81
|
+
handler: async () => "stub",
|
|
82
|
+
});
|
|
83
|
+
return [waitTool, askUserTool, listModelsTool];
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Sub-agent tool definitions.
|
|
87
|
+
* These are the LLM-visible tools for spawning and managing sub-agents.
|
|
88
|
+
* Like wait/ask_user, handlers are stubs — real handlers set per-turn in runTurn().
|
|
89
|
+
*/
|
|
90
|
+
static subAgentToolDefs() {
|
|
91
|
+
const spawnAgentTool = defineTool("spawn_agent", {
|
|
92
|
+
description: "Spawn an autonomous sub-agent to work on a task in parallel. " +
|
|
93
|
+
"The sub-agent is a full Copilot session with its own conversation and tools. " +
|
|
94
|
+
"Returns an agent ID you can use to check status, send messages, or wait for completion. " +
|
|
95
|
+
"IMPORTANT: Only spawn agents for tasks that MUST run independently and in parallel " +
|
|
96
|
+
"(e.g. separate data sources to monitor, independent work streams). " +
|
|
97
|
+
"Do NOT spawn agents for summarization, reporting, or coordination \u2014 handle those yourself. " +
|
|
98
|
+
"Each agent adds cost, so minimize the number of agents. " +
|
|
99
|
+
"For KNOWN agents, pass agent_name (e.g. agent_name=\"sweeper\"). The agent's prompt, tools, and task load automatically. " +
|
|
100
|
+
"For CUSTOM agents (ad-hoc tasks), pass task instead. " +
|
|
101
|
+
"Call list_agents to see all available named agents. " +
|
|
102
|
+
"By default, sub-agents inherit the parent's model. " +
|
|
103
|
+
"If you want to override the model, call list_available_models first and use only an exact provider:model value returned there. " +
|
|
104
|
+
"Never invent, guess, or shorten model names.",
|
|
105
|
+
parameters: {
|
|
106
|
+
type: "object",
|
|
107
|
+
properties: {
|
|
108
|
+
agent_name: {
|
|
109
|
+
type: "string",
|
|
110
|
+
description: "Name of a known agent to spawn (from list_agents). The agent's system message, tools, and initial prompt are loaded automatically. Do NOT also pass task or system_message.",
|
|
111
|
+
},
|
|
112
|
+
task: {
|
|
113
|
+
type: "string",
|
|
114
|
+
description: "For custom agents only: a clear description of what the sub-agent should do. This becomes the agent's first prompt. Do NOT use this for known agents — use agent_name instead.",
|
|
115
|
+
},
|
|
116
|
+
model: {
|
|
117
|
+
type: "string",
|
|
118
|
+
description: "Optional exact provider:model override from list_available_models (e.g. 'azure-openai:gpt-4.1-mini'). Do not invent or shorten model names. If omitted, inherits parent's model.",
|
|
119
|
+
},
|
|
120
|
+
system_message: {
|
|
121
|
+
type: "string",
|
|
122
|
+
description: "Optional custom system message for the sub-agent. If omitted, inherits the parent's system message.",
|
|
123
|
+
},
|
|
124
|
+
tool_names: {
|
|
125
|
+
type: "array",
|
|
126
|
+
items: { type: "string" },
|
|
127
|
+
description: "Optional list of tool names the sub-agent should have access to. If omitted, inherits the parent's tools.",
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
handler: async () => "stub",
|
|
132
|
+
});
|
|
133
|
+
const messageAgentTool = defineTool("message_agent", {
|
|
134
|
+
description: "Send a message to a running sub-agent. " +
|
|
135
|
+
"The message is enqueued as a prompt for the sub-agent's next turn.",
|
|
136
|
+
parameters: {
|
|
137
|
+
type: "object",
|
|
138
|
+
properties: {
|
|
139
|
+
agent_id: { type: "string", description: "The sub-agent's ID (returned by spawn_agent)" },
|
|
140
|
+
message: { type: "string", description: "The message to send to the sub-agent" },
|
|
141
|
+
},
|
|
142
|
+
required: ["agent_id", "message"],
|
|
143
|
+
},
|
|
144
|
+
handler: async () => "stub",
|
|
145
|
+
});
|
|
146
|
+
const checkAgentsTool = defineTool("check_agents", {
|
|
147
|
+
description: "Check the current status and latest output of all sub-agents. " +
|
|
148
|
+
"Returns each agent's ID, task, status (running/completed/failed), and result.",
|
|
149
|
+
parameters: {
|
|
150
|
+
type: "object",
|
|
151
|
+
properties: {},
|
|
152
|
+
},
|
|
153
|
+
handler: async () => "stub",
|
|
154
|
+
});
|
|
155
|
+
const waitForAgentsTool = defineTool("wait_for_agents", {
|
|
156
|
+
description: "Block until one or more sub-agents complete. " +
|
|
157
|
+
"Returns the final results of the completed agents. " +
|
|
158
|
+
"If no agent_ids are specified, waits for ALL active sub-agents.",
|
|
159
|
+
parameters: {
|
|
160
|
+
type: "object",
|
|
161
|
+
properties: {
|
|
162
|
+
agent_ids: {
|
|
163
|
+
type: "array",
|
|
164
|
+
items: { type: "string" },
|
|
165
|
+
description: "Optional list of specific agent IDs to wait for. If omitted, waits for all.",
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
handler: async () => "stub",
|
|
170
|
+
});
|
|
171
|
+
const listSessionsTool = defineTool("list_sessions", {
|
|
172
|
+
description: "List all active sessions in the system. " +
|
|
173
|
+
"Returns each session's ID, title, status, parent, and iteration count. " +
|
|
174
|
+
"Use this to discover other running sessions, find sibling agents, or survey the system.",
|
|
175
|
+
parameters: {
|
|
176
|
+
type: "object",
|
|
177
|
+
properties: {},
|
|
178
|
+
},
|
|
179
|
+
handler: async () => "stub",
|
|
180
|
+
});
|
|
181
|
+
return [spawnAgentTool, messageAgentTool, checkAgentsTool, waitForAgentsTool, listSessionsTool,
|
|
182
|
+
...ManagedSession._childManagementToolDefs()];
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Child management tool definitions (complete, cancel, delete).
|
|
186
|
+
* Separated for clarity but included in subAgentToolDefs().
|
|
187
|
+
*/
|
|
188
|
+
static _childManagementToolDefs() {
|
|
189
|
+
const completeAgentTool = defineTool("complete_agent", {
|
|
190
|
+
description: "Gracefully complete a running sub-agent. " +
|
|
191
|
+
"Sends a /done command to the sub-agent, causing it to finish and send its final result back. " +
|
|
192
|
+
"Use this when a sub-agent has accomplished its task and should stop.",
|
|
193
|
+
parameters: {
|
|
194
|
+
type: "object",
|
|
195
|
+
properties: {
|
|
196
|
+
agent_id: { type: "string", description: "The sub-agent's ID (returned by spawn_agent)" },
|
|
197
|
+
},
|
|
198
|
+
required: ["agent_id"],
|
|
199
|
+
},
|
|
200
|
+
handler: async () => "stub",
|
|
201
|
+
});
|
|
202
|
+
const cancelAgentTool = defineTool("cancel_agent", {
|
|
203
|
+
description: "Cancel a running sub-agent immediately. " +
|
|
204
|
+
"The sub-agent's orchestration is terminated without a graceful shutdown. " +
|
|
205
|
+
"Optionally provide a reason for the cancellation.",
|
|
206
|
+
parameters: {
|
|
207
|
+
type: "object",
|
|
208
|
+
properties: {
|
|
209
|
+
agent_id: { type: "string", description: "The sub-agent's ID (returned by spawn_agent)" },
|
|
210
|
+
reason: { type: "string", description: "Optional reason for cancellation" },
|
|
211
|
+
},
|
|
212
|
+
required: ["agent_id"],
|
|
213
|
+
},
|
|
214
|
+
handler: async () => "stub",
|
|
215
|
+
});
|
|
216
|
+
const deleteAgentTool = defineTool("delete_agent", {
|
|
217
|
+
description: "Cancel and delete a sub-agent entirely. " +
|
|
218
|
+
"ONLY works for sub-agents spawned and tracked by THIS current session via spawn_agent. " +
|
|
219
|
+
"It does NOT work for arbitrary sessions discovered elsewhere in the system. " +
|
|
220
|
+
"Terminates the orchestration and removes the session from the catalog. " +
|
|
221
|
+
"Use this only to clean up your own spawned sub-agents you no longer need.",
|
|
222
|
+
parameters: {
|
|
223
|
+
type: "object",
|
|
224
|
+
properties: {
|
|
225
|
+
agent_id: { type: "string", description: "The sub-agent's ID (returned by spawn_agent)" },
|
|
226
|
+
reason: { type: "string", description: "Optional reason for deletion" },
|
|
227
|
+
},
|
|
228
|
+
required: ["agent_id"],
|
|
229
|
+
},
|
|
230
|
+
handler: async () => "stub",
|
|
231
|
+
});
|
|
232
|
+
return [completeAgentTool, cancelAgentTool, deleteAgentTool];
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Run one LLM turn.
|
|
236
|
+
*
|
|
237
|
+
* The wait tool is injected automatically. If the LLM calls wait()
|
|
238
|
+
* with seconds > waitThreshold, we abort the session and return
|
|
239
|
+
* a "wait" result so the orchestration can schedule a durable timer.
|
|
240
|
+
*
|
|
241
|
+
* Similarly, if onUserInputRequest fires, we abort and return
|
|
242
|
+
* "input_required" so the orchestration can wait for the user's answer.
|
|
243
|
+
*/
|
|
244
|
+
async runTurn(prompt, opts) {
|
|
245
|
+
const turnState = {
|
|
246
|
+
pendingActions: [],
|
|
247
|
+
session: this.copilotSession,
|
|
248
|
+
waitThreshold: this.config.waitThreshold ?? 30,
|
|
249
|
+
};
|
|
250
|
+
// Build system tools (wait tool + ask_user tool)
|
|
251
|
+
const waitTool = defineTool("wait", {
|
|
252
|
+
description: "REQUIRED: The ONLY way to wait, pause, sleep, or delay. " +
|
|
253
|
+
"You MUST call this tool whenever you need to wait, pause, delay, " +
|
|
254
|
+
"poll, check back later, schedule a future action, or implement " +
|
|
255
|
+
"any recurring/periodic task. NEVER use bash sleep, setTimeout, " +
|
|
256
|
+
"setInterval, cron, or any other timing mechanism. This tool " +
|
|
257
|
+
"enables durable waiting that survives process restarts.",
|
|
258
|
+
parameters: {
|
|
259
|
+
type: "object",
|
|
260
|
+
properties: {
|
|
261
|
+
seconds: { type: "number", description: "How long to wait in seconds" },
|
|
262
|
+
reason: { type: "string", description: "Why you're waiting" },
|
|
263
|
+
},
|
|
264
|
+
required: ["seconds"],
|
|
265
|
+
},
|
|
266
|
+
handler: async (args) => {
|
|
267
|
+
const reason = args.reason ?? "unspecified";
|
|
268
|
+
if (args.seconds <= turnState.waitThreshold) {
|
|
269
|
+
await new Promise(r => setTimeout(r, args.seconds * 1000));
|
|
270
|
+
return `Waited for ${args.seconds} seconds. The wait is complete, you may continue.`;
|
|
271
|
+
}
|
|
272
|
+
turnState.pendingActions.push({ type: "wait", seconds: args.seconds, reason });
|
|
273
|
+
if (turnState.session)
|
|
274
|
+
turnState.session.abort();
|
|
275
|
+
return "aborted";
|
|
276
|
+
},
|
|
277
|
+
});
|
|
278
|
+
const askUserTool = defineTool("ask_user", {
|
|
279
|
+
description: "Ask the user a question and wait for their response. " +
|
|
280
|
+
"Use this when you need clarification or user input before proceeding.",
|
|
281
|
+
parameters: {
|
|
282
|
+
type: "object",
|
|
283
|
+
properties: {
|
|
284
|
+
question: { type: "string", description: "The question to ask the user" },
|
|
285
|
+
choices: {
|
|
286
|
+
type: "array",
|
|
287
|
+
items: { type: "string" },
|
|
288
|
+
description: "Optional list of choices for the user",
|
|
289
|
+
},
|
|
290
|
+
allowFreeform: {
|
|
291
|
+
type: "boolean",
|
|
292
|
+
description: "Whether to allow freeform text input (default: true)",
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
required: ["question"],
|
|
296
|
+
},
|
|
297
|
+
handler: async (args) => {
|
|
298
|
+
turnState.pendingActions.push({
|
|
299
|
+
type: "input_required",
|
|
300
|
+
question: args.question,
|
|
301
|
+
choices: args.choices,
|
|
302
|
+
allowFreeform: args.allowFreeform ?? true,
|
|
303
|
+
});
|
|
304
|
+
if (turnState.session)
|
|
305
|
+
turnState.session.abort();
|
|
306
|
+
return "aborted";
|
|
307
|
+
},
|
|
308
|
+
});
|
|
309
|
+
// list_available_models — returns data inline (no abort/continuation needed)
|
|
310
|
+
const listModelsTool = defineTool("list_available_models", {
|
|
311
|
+
description: "List all available LLM models across all configured providers. " +
|
|
312
|
+
"Returns each model's exact qualified name (provider:model), description, and cost tier. " +
|
|
313
|
+
"This output is the authoritative source for model selection. " +
|
|
314
|
+
"Use this when choosing the best model for a sub-agent task, or when the user asks about available models. " +
|
|
315
|
+
"If you plan to pass spawn_agent(model=...), you must choose an exact provider:model value from this list and must not invent or shorten names. " +
|
|
316
|
+
"When choosing a model for a sub-agent, prefer lower-cost models for simple tasks " +
|
|
317
|
+
"and higher-cost models for complex reasoning tasks.",
|
|
318
|
+
parameters: {
|
|
319
|
+
type: "object",
|
|
320
|
+
properties: {},
|
|
321
|
+
},
|
|
322
|
+
handler: async () => {
|
|
323
|
+
return opts?.modelSummary || "No model providers configured.";
|
|
324
|
+
},
|
|
325
|
+
});
|
|
326
|
+
// Build sub-agent tools
|
|
327
|
+
const spawnAgentTool = defineTool("spawn_agent", {
|
|
328
|
+
description: "Spawn a sub-agent. For KNOWN agents, pass agent_name ONLY (e.g. agent_name=\"sweeper\"). " +
|
|
329
|
+
"The agent's system message, tools, and initial prompt are loaded automatically from agent_name. " +
|
|
330
|
+
"Do NOT pass task or system_message when using agent_name. " +
|
|
331
|
+
"Call list_agents to see all available named agents. " +
|
|
332
|
+
"For CUSTOM agents (ad-hoc tasks), pass task instead — no agent_name is needed. " +
|
|
333
|
+
"Any task you can describe can be spawned as a custom agent; you do not need a skill or pre-configured definition. " +
|
|
334
|
+
"If you want a different model, call list_available_models first and use only an exact provider:model value from that list. " +
|
|
335
|
+
"Never invent, guess, or shorten model names.",
|
|
336
|
+
parameters: {
|
|
337
|
+
type: "object",
|
|
338
|
+
properties: {
|
|
339
|
+
agent_name: {
|
|
340
|
+
type: "string",
|
|
341
|
+
description: "Name of a known agent to spawn (from list_agents). The agent's prompt, tools, and task load automatically. Do NOT also pass task or system_message.",
|
|
342
|
+
},
|
|
343
|
+
task: {
|
|
344
|
+
type: "string",
|
|
345
|
+
description: "For custom agents only: a clear description of what the sub-agent should do. Any task can be spawned — no pre-configured agent or skill is required.",
|
|
346
|
+
},
|
|
347
|
+
model: {
|
|
348
|
+
type: "string",
|
|
349
|
+
description: "Optional exact provider:model override from list_available_models. Do not invent or shorten model names.",
|
|
350
|
+
},
|
|
351
|
+
system_message: {
|
|
352
|
+
type: "string",
|
|
353
|
+
description: "Optional custom system message. Only for custom agents.",
|
|
354
|
+
},
|
|
355
|
+
tool_names: {
|
|
356
|
+
type: "array",
|
|
357
|
+
items: { type: "string" },
|
|
358
|
+
description: "Optional tool names list. Only for custom agents.",
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
},
|
|
362
|
+
handler: async (args) => {
|
|
363
|
+
if (!args.agent_name && !args.task) {
|
|
364
|
+
return "Error: either agent_name or task is required.";
|
|
365
|
+
}
|
|
366
|
+
turnState.pendingActions.push({
|
|
367
|
+
type: "spawn_agent",
|
|
368
|
+
task: args.task || "",
|
|
369
|
+
model: args.model,
|
|
370
|
+
systemMessage: args.system_message,
|
|
371
|
+
toolNames: args.tool_names,
|
|
372
|
+
agentName: args.agent_name,
|
|
373
|
+
});
|
|
374
|
+
if (turnState.session)
|
|
375
|
+
turnState.session.abort();
|
|
376
|
+
return "aborted";
|
|
377
|
+
},
|
|
378
|
+
});
|
|
379
|
+
const messageAgentTool = defineTool("message_agent", {
|
|
380
|
+
description: "Send a message to a running sub-agent. " +
|
|
381
|
+
"The message is enqueued as a prompt for the sub-agent's next turn.",
|
|
382
|
+
parameters: {
|
|
383
|
+
type: "object",
|
|
384
|
+
properties: {
|
|
385
|
+
agent_id: { type: "string", description: "The sub-agent's ID (returned by spawn_agent)" },
|
|
386
|
+
message: { type: "string", description: "The message to send to the sub-agent" },
|
|
387
|
+
},
|
|
388
|
+
required: ["agent_id", "message"],
|
|
389
|
+
},
|
|
390
|
+
handler: async (args) => {
|
|
391
|
+
turnState.pendingActions.push({
|
|
392
|
+
type: "message_agent",
|
|
393
|
+
agentId: args.agent_id,
|
|
394
|
+
message: args.message,
|
|
395
|
+
});
|
|
396
|
+
if (turnState.session)
|
|
397
|
+
turnState.session.abort();
|
|
398
|
+
return "aborted";
|
|
399
|
+
},
|
|
400
|
+
});
|
|
401
|
+
const checkAgentsTool = defineTool("check_agents", {
|
|
402
|
+
description: "Check the current status and latest output of all sub-agents. " +
|
|
403
|
+
"Returns each agent's ID, task, status (running/completed/failed), and result.",
|
|
404
|
+
parameters: {
|
|
405
|
+
type: "object",
|
|
406
|
+
properties: {},
|
|
407
|
+
},
|
|
408
|
+
handler: async () => {
|
|
409
|
+
turnState.pendingActions.push({ type: "check_agents" });
|
|
410
|
+
if (turnState.session)
|
|
411
|
+
turnState.session.abort();
|
|
412
|
+
return "aborted";
|
|
413
|
+
},
|
|
414
|
+
});
|
|
415
|
+
const waitForAgentsTool = defineTool("wait_for_agents", {
|
|
416
|
+
description: "Block until one or more sub-agents complete. " +
|
|
417
|
+
"Returns the final results of the completed agents. " +
|
|
418
|
+
"If no agent_ids are specified, waits for ALL active sub-agents.",
|
|
419
|
+
parameters: {
|
|
420
|
+
type: "object",
|
|
421
|
+
properties: {
|
|
422
|
+
agent_ids: {
|
|
423
|
+
type: "array",
|
|
424
|
+
items: { type: "string" },
|
|
425
|
+
description: "Optional list of specific agent IDs to wait for. If omitted, waits for all.",
|
|
426
|
+
},
|
|
427
|
+
},
|
|
428
|
+
},
|
|
429
|
+
handler: async (args) => {
|
|
430
|
+
turnState.pendingActions.push({
|
|
431
|
+
type: "wait_for_agents",
|
|
432
|
+
agentIds: args.agent_ids ?? [],
|
|
433
|
+
});
|
|
434
|
+
if (turnState.session)
|
|
435
|
+
turnState.session.abort();
|
|
436
|
+
return "aborted";
|
|
437
|
+
},
|
|
438
|
+
});
|
|
439
|
+
const listSessionsTool = defineTool("list_sessions", {
|
|
440
|
+
description: "List all active sessions in the system. " +
|
|
441
|
+
"Returns each session's ID, title, status, parent, and iteration count. " +
|
|
442
|
+
"Use this to discover other running sessions, find sibling agents, or survey the system.",
|
|
443
|
+
parameters: {
|
|
444
|
+
type: "object",
|
|
445
|
+
properties: {},
|
|
446
|
+
},
|
|
447
|
+
handler: async () => {
|
|
448
|
+
turnState.pendingActions.push({ type: "list_sessions" });
|
|
449
|
+
if (turnState.session)
|
|
450
|
+
turnState.session.abort();
|
|
451
|
+
return "aborted";
|
|
452
|
+
},
|
|
453
|
+
});
|
|
454
|
+
const completeAgentTool = defineTool("complete_agent", {
|
|
455
|
+
description: "Gracefully complete a running sub-agent. " +
|
|
456
|
+
"Sends a /done command to the sub-agent, causing it to finish and send its final result back. " +
|
|
457
|
+
"Use this when a sub-agent has accomplished its task and should stop.",
|
|
458
|
+
parameters: {
|
|
459
|
+
type: "object",
|
|
460
|
+
properties: {
|
|
461
|
+
agent_id: { type: "string", description: "The sub-agent's ID (returned by spawn_agent)" },
|
|
462
|
+
},
|
|
463
|
+
required: ["agent_id"],
|
|
464
|
+
},
|
|
465
|
+
handler: async (args) => {
|
|
466
|
+
turnState.pendingActions.push({ type: "complete_agent", agentId: args.agent_id });
|
|
467
|
+
if (turnState.session)
|
|
468
|
+
turnState.session.abort();
|
|
469
|
+
return "aborted";
|
|
470
|
+
},
|
|
471
|
+
});
|
|
472
|
+
const cancelAgentTool = defineTool("cancel_agent", {
|
|
473
|
+
description: "Cancel a running sub-agent immediately. " +
|
|
474
|
+
"The sub-agent's orchestration is terminated without a graceful shutdown. " +
|
|
475
|
+
"Optionally provide a reason for the cancellation.",
|
|
476
|
+
parameters: {
|
|
477
|
+
type: "object",
|
|
478
|
+
properties: {
|
|
479
|
+
agent_id: { type: "string", description: "The sub-agent's ID (returned by spawn_agent)" },
|
|
480
|
+
reason: { type: "string", description: "Optional reason for cancellation" },
|
|
481
|
+
},
|
|
482
|
+
required: ["agent_id"],
|
|
483
|
+
},
|
|
484
|
+
handler: async (args) => {
|
|
485
|
+
turnState.pendingActions.push({ type: "cancel_agent", agentId: args.agent_id, reason: args.reason });
|
|
486
|
+
if (turnState.session)
|
|
487
|
+
turnState.session.abort();
|
|
488
|
+
return "aborted";
|
|
489
|
+
},
|
|
490
|
+
});
|
|
491
|
+
const deleteAgentTool = defineTool("delete_agent", {
|
|
492
|
+
description: "Cancel and delete a sub-agent entirely. " +
|
|
493
|
+
"Terminates the orchestration and removes the session from the catalog. " +
|
|
494
|
+
"Use this to clean up sub-agents you no longer need.",
|
|
495
|
+
parameters: {
|
|
496
|
+
type: "object",
|
|
497
|
+
properties: {
|
|
498
|
+
agent_id: { type: "string", description: "The sub-agent's ID (returned by spawn_agent)" },
|
|
499
|
+
reason: { type: "string", description: "Optional reason for deletion" },
|
|
500
|
+
},
|
|
501
|
+
required: ["agent_id"],
|
|
502
|
+
},
|
|
503
|
+
handler: async (args) => {
|
|
504
|
+
turnState.pendingActions.push({ type: "delete_agent", agentId: args.agent_id, reason: args.reason });
|
|
505
|
+
if (turnState.session)
|
|
506
|
+
turnState.session.abort();
|
|
507
|
+
return "aborted";
|
|
508
|
+
},
|
|
509
|
+
});
|
|
510
|
+
const SYSTEM_TOOL_NAMES = new Set(["wait", "ask_user", "list_available_models", "spawn_agent", "message_agent", "check_agents", "wait_for_agents", "list_sessions", "complete_agent", "cancel_agent", "delete_agent"]);
|
|
511
|
+
// Merge user tools with system tools
|
|
512
|
+
const userTools = this.config.tools ?? [];
|
|
513
|
+
// Wrap user tool handlers to augment invocation with the PilotSwarm
|
|
514
|
+
// durable session ID. The Copilot SDK's invocation.sessionId is an
|
|
515
|
+
// internal SDK session ID — we add durableSessionId so tool handlers
|
|
516
|
+
// can identify which durable session is calling without closures.
|
|
517
|
+
// Both IDs are available: invocation.sessionId (SDK) and
|
|
518
|
+
// invocation.durableSessionId (PilotSwarm).
|
|
519
|
+
const durableSessionId = this.sessionId;
|
|
520
|
+
const wrappedUserTools = userTools
|
|
521
|
+
.filter(t => {
|
|
522
|
+
const name = t.name;
|
|
523
|
+
return !SYSTEM_TOOL_NAMES.has(name);
|
|
524
|
+
})
|
|
525
|
+
.map(t => ({
|
|
526
|
+
...t,
|
|
527
|
+
handler: (args, invocation) => {
|
|
528
|
+
const augmented = { ...invocation, durableSessionId };
|
|
529
|
+
return t.handler(args, augmented);
|
|
530
|
+
},
|
|
531
|
+
}));
|
|
532
|
+
const allTools = [
|
|
533
|
+
...wrappedUserTools,
|
|
534
|
+
waitTool,
|
|
535
|
+
askUserTool,
|
|
536
|
+
listModelsTool,
|
|
537
|
+
spawnAgentTool,
|
|
538
|
+
messageAgentTool,
|
|
539
|
+
checkAgentsTool,
|
|
540
|
+
waitForAgentsTool,
|
|
541
|
+
listSessionsTool,
|
|
542
|
+
completeAgentTool,
|
|
543
|
+
cancelAgentTool,
|
|
544
|
+
deleteAgentTool,
|
|
545
|
+
];
|
|
546
|
+
// Re-register tools for this turn (may have changed)
|
|
547
|
+
this.copilotSession.registerTools(allTools);
|
|
548
|
+
// Collect the final assistant content and all events via on()
|
|
549
|
+
let finalContent;
|
|
550
|
+
const collectedEvents = [];
|
|
551
|
+
const unsubscribers = [];
|
|
552
|
+
const turnComplete = new Promise((resolve, reject) => {
|
|
553
|
+
// Catch-all event handler — captures every event and fires onEvent immediately.
|
|
554
|
+
unsubscribers.push(this.copilotSession.on((event) => {
|
|
555
|
+
const eventType = event.type ?? event.eventType ?? "unknown";
|
|
556
|
+
const eventData = event.data ?? event;
|
|
557
|
+
// Augment tool execution events with the durable session ID
|
|
558
|
+
// so CMS consumers can correlate tool calls to durable sessions.
|
|
559
|
+
if (eventType === "tool.execution_start" || eventType === "tool.execution_complete") {
|
|
560
|
+
if (typeof eventData === "object" && eventData !== null) {
|
|
561
|
+
eventData.durableSessionId = durableSessionId;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
const captured = { eventType, data: eventData };
|
|
565
|
+
collectedEvents.push(captured);
|
|
566
|
+
// Fire immediately so callers can write to CMS in real-time
|
|
567
|
+
if (opts?.onEvent) {
|
|
568
|
+
try {
|
|
569
|
+
opts.onEvent(captured);
|
|
570
|
+
}
|
|
571
|
+
catch { }
|
|
572
|
+
}
|
|
573
|
+
}));
|
|
574
|
+
// Capture the final assistant message
|
|
575
|
+
unsubscribers.push(this.copilotSession.on("assistant.message", (event) => {
|
|
576
|
+
finalContent = event.data?.content ?? finalContent;
|
|
577
|
+
}));
|
|
578
|
+
// Stream deltas to the caller if requested
|
|
579
|
+
if (opts?.onDelta) {
|
|
580
|
+
unsubscribers.push(this.copilotSession.on("assistant.message_delta", (event) => {
|
|
581
|
+
if (event.data?.deltaContent) {
|
|
582
|
+
opts.onDelta(event.data.deltaContent);
|
|
583
|
+
}
|
|
584
|
+
}));
|
|
585
|
+
}
|
|
586
|
+
// Notify caller of tool execution starts
|
|
587
|
+
if (opts?.onToolStart) {
|
|
588
|
+
unsubscribers.push(this.copilotSession.on("tool.execution_start", (event) => {
|
|
589
|
+
opts.onToolStart(event.data?.toolName ?? "unknown", event.data?.toolArgs);
|
|
590
|
+
}));
|
|
591
|
+
}
|
|
592
|
+
// session.idle = turn finished (normal completion or post-abort)
|
|
593
|
+
unsubscribers.push(this.copilotSession.on("session.idle", () => {
|
|
594
|
+
resolve();
|
|
595
|
+
}));
|
|
596
|
+
});
|
|
597
|
+
// Optional timeout race — disabled by default.
|
|
598
|
+
// Uses turnTimeoutMs from session config if set.
|
|
599
|
+
const TURN_TIMEOUT = this.config.turnTimeoutMs ?? 0;
|
|
600
|
+
const timeoutPromise = TURN_TIMEOUT > 0
|
|
601
|
+
? new Promise((_, reject) => {
|
|
602
|
+
setTimeout(() => reject(new Error("Turn timed out")), TURN_TIMEOUT);
|
|
603
|
+
})
|
|
604
|
+
: null;
|
|
605
|
+
try {
|
|
606
|
+
// Fire the prompt — non-blocking
|
|
607
|
+
await this.copilotSession.send({ prompt });
|
|
608
|
+
// Wait for session.idle, or timeout if explicitly enabled.
|
|
609
|
+
if (timeoutPromise) {
|
|
610
|
+
await Promise.race([turnComplete, timeoutPromise]);
|
|
611
|
+
}
|
|
612
|
+
else {
|
|
613
|
+
await turnComplete;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
catch (err) {
|
|
617
|
+
// Timeout — kill it
|
|
618
|
+
const errMsg = err.message ?? String(err);
|
|
619
|
+
if (errMsg.includes("timed out")) {
|
|
620
|
+
try {
|
|
621
|
+
this.copilotSession.abort();
|
|
622
|
+
}
|
|
623
|
+
catch { }
|
|
624
|
+
return {
|
|
625
|
+
type: "error",
|
|
626
|
+
message: "Copilot was taking too long to process and was killed.",
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
// Other send() errors — check if any handler aborted first
|
|
630
|
+
if (turnState.pendingActions.length === 0) {
|
|
631
|
+
return { type: "error", message: errMsg };
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
finally {
|
|
635
|
+
// Always clean up subscriptions
|
|
636
|
+
for (const unsub of unsubscribers)
|
|
637
|
+
unsub();
|
|
638
|
+
}
|
|
639
|
+
// Check what ended the turn
|
|
640
|
+
if (turnState.pendingActions.length > 0) {
|
|
641
|
+
const [firstAction, ...remainingActions] = turnState.pendingActions;
|
|
642
|
+
const queuedActions = remainingActions.length > 0 ? remainingActions : undefined;
|
|
643
|
+
switch (firstAction.type) {
|
|
644
|
+
case "input_required":
|
|
645
|
+
return { ...firstAction, events: collectedEvents, queuedActions };
|
|
646
|
+
case "wait":
|
|
647
|
+
return { ...firstAction, content: finalContent, events: collectedEvents, queuedActions };
|
|
648
|
+
case "spawn_agent":
|
|
649
|
+
return { ...firstAction, content: finalContent, events: collectedEvents, queuedActions };
|
|
650
|
+
case "message_agent":
|
|
651
|
+
case "check_agents":
|
|
652
|
+
case "wait_for_agents":
|
|
653
|
+
case "list_sessions":
|
|
654
|
+
case "complete_agent":
|
|
655
|
+
case "cancel_agent":
|
|
656
|
+
case "delete_agent":
|
|
657
|
+
return { ...firstAction, events: collectedEvents, queuedActions };
|
|
658
|
+
default:
|
|
659
|
+
break;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
// Check if the SDK emitted a session.error — if so, treat as an error
|
|
663
|
+
// even though session.idle fired (the SDK fires idle after retries exhaust).
|
|
664
|
+
const sessionError = collectedEvents.find(e => e.eventType === "session.error");
|
|
665
|
+
if (sessionError && !finalContent) {
|
|
666
|
+
const errData = sessionError.data ?? {};
|
|
667
|
+
const errMsg = errData.message ?? errData.stack ?? "Unknown session error";
|
|
668
|
+
return {
|
|
669
|
+
type: "error",
|
|
670
|
+
message: `Execution failed: ${errMsg}`,
|
|
671
|
+
events: collectedEvents,
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
return {
|
|
675
|
+
type: "completed",
|
|
676
|
+
content: finalContent ?? "(no response)",
|
|
677
|
+
events: collectedEvents,
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* Abort the current in-flight message.
|
|
682
|
+
* Session remains alive for future runTurn() calls.
|
|
683
|
+
*/
|
|
684
|
+
abort() {
|
|
685
|
+
this.copilotSession.abort();
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* Destroy the session — release resources, flush to disk.
|
|
689
|
+
*/
|
|
690
|
+
async destroy() {
|
|
691
|
+
await this.copilotSession.disconnect();
|
|
692
|
+
}
|
|
693
|
+
/**
|
|
694
|
+
* Get conversation messages from the underlying session.
|
|
695
|
+
*/
|
|
696
|
+
async getMessages() {
|
|
697
|
+
return this.copilotSession.getMessages();
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Update configuration for the next turn.
|
|
701
|
+
*/
|
|
702
|
+
updateConfig(config) {
|
|
703
|
+
if (config.model !== undefined)
|
|
704
|
+
this.config.model = config.model;
|
|
705
|
+
if (config.tools !== undefined)
|
|
706
|
+
this.config.tools = config.tools;
|
|
707
|
+
if (config.systemMessage !== undefined)
|
|
708
|
+
this.config.systemMessage = config.systemMessage;
|
|
709
|
+
if (config.waitThreshold !== undefined)
|
|
710
|
+
this.config.waitThreshold = config.waitThreshold;
|
|
711
|
+
}
|
|
712
|
+
/** Get the underlying CopilotSession (for direct access when needed). */
|
|
713
|
+
getCopilotSession() {
|
|
714
|
+
return this.copilotSession;
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
//# sourceMappingURL=managed-session.js.map
|