@mastra/code-sdk 1.8.4-alpha.6 → 1.9.0-alpha.8
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 +190 -0
- package/dist/acp/agent.d.ts +30 -17
- package/dist/acp/agent.d.ts.map +1 -1
- package/dist/acp/agent.js +294 -103
- package/dist/acp/agent.js.map +1 -1
- package/dist/acp/errors.d.ts +3 -0
- package/dist/acp/errors.d.ts.map +1 -0
- package/dist/acp/errors.js +14 -0
- package/dist/acp/errors.js.map +1 -0
- package/dist/acp/event-mapper.d.ts +6 -1
- package/dist/acp/event-mapper.d.ts.map +1 -1
- package/dist/acp/event-mapper.js +116 -56
- package/dist/acp/event-mapper.js.map +1 -1
- package/dist/acp/index.d.ts +1 -4
- package/dist/acp/index.d.ts.map +1 -1
- package/dist/acp/index.js +6 -48
- package/dist/acp/index.js.map +1 -1
- package/dist/acp/runtime.d.ts +5 -0
- package/dist/acp/runtime.d.ts.map +1 -0
- package/dist/acp/runtime.js +80 -0
- package/dist/acp/runtime.js.map +1 -0
- package/dist/acp/server.d.ts +3 -6
- package/dist/acp/server.d.ts.map +1 -1
- package/dist/acp/server.js +22 -19
- package/dist/acp/server.js.map +1 -1
- package/dist/acp/skills.d.ts +6 -0
- package/dist/acp/skills.d.ts.map +1 -0
- package/dist/acp/skills.js +33 -0
- package/dist/acp/skills.js.map +1 -0
- package/dist/agents/model.js +1 -1
- package/dist/agents/prompts/agent-instructions.js +2 -2
- package/dist/agents/workspace.js +1 -1
- package/dist/analytics.js +2 -2
- package/dist/auth/providers/kimi-coding.js +1 -1
- package/dist/auth/storage.js +2 -2
- package/dist/clipboard/index.js +2 -2
- package/dist/headless/run-mc.d.ts.map +1 -1
- package/dist/headless/run-mc.js +14 -0
- package/dist/headless/run-mc.js.map +1 -1
- package/dist/hooks/config.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/lsp/server.js +1 -1
- package/dist/lsp/workspace.js +1 -1
- package/dist/mcp/config.js +1 -1
- package/dist/mcp/manager.d.ts.map +1 -1
- package/dist/mcp/manager.js +2 -1
- package/dist/mcp/manager.js.map +1 -1
- package/dist/mcp/state.js +1 -1
- package/dist/mcp/types.d.ts +2 -0
- package/dist/mcp/types.d.ts.map +1 -1
- package/dist/onboarding/settings.js +3 -3
- package/dist/plugins/dependencies.js +1 -1
- package/dist/plugins/install.js +1 -1
- package/dist/plugins/loader.js +3 -3
- package/dist/plugins/manager.js +1 -1
- package/dist/plugins/manifest.js +1 -1
- package/dist/plugins/package-link.js +1 -1
- package/dist/plugins/paths.js +1 -1
- package/dist/plugins/registry.js +1 -1
- package/dist/plugins/scaffold.js +1 -1
- package/dist/process-memory-diagnostics.js +2 -2
- package/dist/providers/amazon-bedrock-gateway.js +1 -1
- package/dist/providers/openai-codex.js +1 -1
- package/dist/schema.js +1 -1
- package/dist/tools/request-sandbox-access.js +5 -4
- package/dist/tools/request-sandbox-access.js.map +1 -1
- package/dist/utils/debug-log.js +1 -1
- package/dist/utils/project.js +3 -3
- package/dist/utils/signals-pubsub.js +1 -1
- package/dist/utils/slash-command-loader.js +1 -1
- package/dist/utils/slash-command-processor.js +1 -1
- package/dist/utils/storage-maintenance.js +1 -1
- package/dist/utils/thread-lock.js +1 -1
- package/dist/utils/update-check.js +2 -2
- package/dist/workflows/register-primitives.js +1 -1
- package/package.json +18 -14
package/dist/acp/agent.js
CHANGED
|
@@ -1,35 +1,58 @@
|
|
|
1
|
+
import { getAvailableThinkingLevelsForModel, isThinkingLevelSetting } from "../thinking.js";
|
|
2
|
+
import { getCurrentVersion } from "../utils/update-check.js";
|
|
3
|
+
import { withCleanupFailure } from "./errors.js";
|
|
1
4
|
import { handleAgentControllerEvent } from "./event-mapper.js";
|
|
2
|
-
import {
|
|
5
|
+
import { expandSkillCommand, listSkillCommands } from "./skills.js";
|
|
6
|
+
import { isAbsolute } from "path";
|
|
7
|
+
import { PROTOCOL_VERSION, RequestError } from "@agentclientprotocol/sdk";
|
|
3
8
|
//#region src/acp/agent.ts
|
|
4
|
-
/**
|
|
5
|
-
* ACP Agent implementation that wraps a mastracode Controller.
|
|
6
|
-
* Each instance represents one ACP connection from a client.
|
|
7
|
-
*/
|
|
9
|
+
/** One ACP connection, with an independent Mastra Code runtime for each conversation. */
|
|
8
10
|
var MastraCodeAcpAgent = class {
|
|
9
11
|
connection;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
getThreadIdOrThrow(sessionId) {
|
|
18
|
-
const threadId = this.sessionMap.get(sessionId);
|
|
19
|
-
if (!threadId) throw new Error(`Unknown ACP sessionId: ${sessionId}`);
|
|
20
|
-
return threadId;
|
|
21
|
-
}
|
|
22
|
-
constructor(connection, controller, session, modes) {
|
|
12
|
+
createSession;
|
|
13
|
+
sessions = /* @__PURE__ */ new Map();
|
|
14
|
+
pendingCreations = /* @__PURE__ */ new Set();
|
|
15
|
+
startupCleanupFailures = [];
|
|
16
|
+
disposed = false;
|
|
17
|
+
disposal;
|
|
18
|
+
constructor(connection, createSession) {
|
|
23
19
|
this.connection = connection;
|
|
24
|
-
this.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
20
|
+
this.createSession = createSession;
|
|
21
|
+
}
|
|
22
|
+
getSession(sessionId) {
|
|
23
|
+
const entry = this.sessions.get(sessionId);
|
|
24
|
+
if (!entry || this.disposed) throw RequestError.invalidParams({ sessionId }, "Unknown ACP session");
|
|
25
|
+
return entry;
|
|
26
|
+
}
|
|
27
|
+
enqueue(entry, operation) {
|
|
28
|
+
const result = entry.queue.then(operation);
|
|
29
|
+
entry.queue = result.then(() => {}, () => {});
|
|
30
|
+
return result;
|
|
30
31
|
}
|
|
31
32
|
dispose() {
|
|
32
|
-
this.
|
|
33
|
+
if (this.disposal) return this.disposal;
|
|
34
|
+
this.disposed = true;
|
|
35
|
+
const entries = [...this.sessions.values()];
|
|
36
|
+
this.sessions.clear();
|
|
37
|
+
const cleanup = Promise.allSettled([Promise.allSettled([...this.pendingCreations]), ...entries.map(async (entry) => {
|
|
38
|
+
for (const turn of entry.turns) turn.cancelled = true;
|
|
39
|
+
if (entry.state) {
|
|
40
|
+
entry.state.cancelled = true;
|
|
41
|
+
entry.session.abort();
|
|
42
|
+
entry.state?.resolve("aborted");
|
|
43
|
+
}
|
|
44
|
+
entry.unsubscribe();
|
|
45
|
+
await entry.cleanup?.();
|
|
46
|
+
})]).then((results) => {
|
|
47
|
+
const failures = results.filter((result) => result.status === "rejected").map((result) => result.reason);
|
|
48
|
+
failures.push(...this.startupCleanupFailures);
|
|
49
|
+
if (failures.length) throw new AggregateError(failures, "ACP session cleanup failed");
|
|
50
|
+
});
|
|
51
|
+
this.disposal = new Promise((resolve, reject) => {
|
|
52
|
+
const timeout = setTimeout(() => reject(/* @__PURE__ */ new Error("ACP shutdown timed out after 10 seconds")), 1e4);
|
|
53
|
+
cleanup.then(resolve, reject).finally(() => clearTimeout(timeout));
|
|
54
|
+
});
|
|
55
|
+
return this.disposal;
|
|
33
56
|
}
|
|
34
57
|
async initialize(_request) {
|
|
35
58
|
return {
|
|
@@ -37,121 +60,289 @@ var MastraCodeAcpAgent = class {
|
|
|
37
60
|
agentInfo: {
|
|
38
61
|
name: "mastracode",
|
|
39
62
|
title: "Mastra Code",
|
|
40
|
-
version:
|
|
63
|
+
version: getCurrentVersion()
|
|
41
64
|
},
|
|
42
|
-
agentCapabilities: {
|
|
65
|
+
agentCapabilities: {
|
|
66
|
+
loadSession: false,
|
|
67
|
+
mcpCapabilities: {
|
|
68
|
+
http: true,
|
|
69
|
+
sse: false
|
|
70
|
+
}
|
|
71
|
+
}
|
|
43
72
|
};
|
|
44
73
|
}
|
|
45
|
-
async authenticate() {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
74
|
+
async authenticate() {
|
|
75
|
+
throw RequestError.invalidParams(void 0, "Configure authentication through Mastra Code before starting ACP");
|
|
76
|
+
}
|
|
77
|
+
newSession(request) {
|
|
78
|
+
const creating = Promise.resolve().then(() => this.createNewSession(request));
|
|
79
|
+
this.pendingCreations.add(creating);
|
|
80
|
+
creating.then(() => this.pendingCreations.delete(creating), () => this.pendingCreations.delete(creating));
|
|
81
|
+
return creating;
|
|
82
|
+
}
|
|
83
|
+
async createNewSession(request) {
|
|
84
|
+
if (this.disposed) throw RequestError.internalError(void 0, "ACP connection is closed");
|
|
85
|
+
if (!isAbsolute(request.cwd)) throw RequestError.invalidParams(void 0, "cwd must be an absolute path");
|
|
86
|
+
const runtime = await this.createSession(request);
|
|
57
87
|
try {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
88
|
+
if (this.disposed) throw RequestError.internalError(void 0, "ACP connection is closed");
|
|
89
|
+
const thread = await runtime.session.thread.create();
|
|
90
|
+
await runtime.session.thread.switch({ threadId: thread.id });
|
|
91
|
+
let models;
|
|
92
|
+
try {
|
|
93
|
+
const available = await runtime.controller.listAvailableModels();
|
|
94
|
+
models = {
|
|
95
|
+
currentModelId: runtime.session.model.get() ?? "",
|
|
96
|
+
availableModels: includeCurrentModel([...new Map(available.filter((model) => model.hasApiKey || model.id === runtime.session.model.get()).map((model) => [model.id, {
|
|
97
|
+
modelId: model.id,
|
|
98
|
+
name: model.hasApiKey ? model.id : `${model.id} (provider not configured)`
|
|
99
|
+
}])).values()], runtime.session.model.get() ?? "")
|
|
100
|
+
};
|
|
101
|
+
} catch {}
|
|
102
|
+
if (this.disposed) throw RequestError.internalError(void 0, "ACP connection is closed");
|
|
103
|
+
const entry = {
|
|
104
|
+
...runtime,
|
|
105
|
+
models: models?.availableModels ?? [],
|
|
106
|
+
state: null,
|
|
107
|
+
queue: Promise.resolve(),
|
|
108
|
+
turns: /* @__PURE__ */ new Set(),
|
|
109
|
+
unsubscribe: () => {},
|
|
110
|
+
commands: []
|
|
65
111
|
};
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
112
|
+
if (this.disposed) throw RequestError.internalError(void 0, "ACP connection is closed");
|
|
113
|
+
entry.unsubscribe = runtime.session.subscribe((event) => {
|
|
114
|
+
handleAgentControllerEvent(event, entry.state, this.connection, entry.session);
|
|
115
|
+
if (event.type === "mode_changed") this.connection.sessionUpdate({
|
|
116
|
+
sessionId: thread.id,
|
|
117
|
+
update: {
|
|
118
|
+
sessionUpdate: "current_mode_update",
|
|
119
|
+
currentModeId: entry.session.mode.get()
|
|
120
|
+
}
|
|
121
|
+
}).catch((error) => process.stderr.write(`[acp] mode update failed: ${error}\n`));
|
|
122
|
+
if (event.type === "mode_changed" || event.type === "model_changed" || event.type === "state_changed" && event.changedKeys.includes("thinkingLevel")) this.connection.sessionUpdate({
|
|
123
|
+
sessionId: thread.id,
|
|
124
|
+
update: {
|
|
125
|
+
sessionUpdate: "config_option_update",
|
|
126
|
+
configOptions: this.configOptions(entry)
|
|
127
|
+
}
|
|
128
|
+
}).catch((error) => process.stderr.write(`[acp] configuration update failed: ${error}\n`));
|
|
129
|
+
});
|
|
130
|
+
const response = {
|
|
131
|
+
sessionId: thread.id,
|
|
132
|
+
modes: {
|
|
133
|
+
currentModeId: runtime.session.mode.get(),
|
|
134
|
+
availableModes: runtime.modes.map((mode) => ({
|
|
135
|
+
id: mode.id,
|
|
136
|
+
name: mode.name ?? mode.id
|
|
137
|
+
}))
|
|
138
|
+
},
|
|
139
|
+
models,
|
|
140
|
+
configOptions: this.configOptions(entry)
|
|
141
|
+
};
|
|
142
|
+
this.sessions.set(thread.id, entry);
|
|
143
|
+
setImmediate(() => {
|
|
144
|
+
this.enqueue(entry, async () => {
|
|
145
|
+
if (!this.disposed) await this.refreshCommands(thread.id, entry);
|
|
146
|
+
}).catch((error) => process.stderr.write(`[acp] command discovery failed: ${error}\n`));
|
|
147
|
+
});
|
|
148
|
+
return response;
|
|
149
|
+
} catch (error) {
|
|
150
|
+
try {
|
|
151
|
+
await runtime.cleanup?.();
|
|
152
|
+
} catch (cleanupError) {
|
|
153
|
+
if (this.disposed) this.startupCleanupFailures.push(cleanupError);
|
|
154
|
+
throw withCleanupFailure(error, cleanupError);
|
|
155
|
+
}
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
75
158
|
}
|
|
76
|
-
async
|
|
77
|
-
const
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
159
|
+
async refreshCommands(sessionId, entry) {
|
|
160
|
+
const skills = await entry.getSkills?.();
|
|
161
|
+
const commands = await listSkillCommands(skills);
|
|
162
|
+
if (JSON.stringify(commands) !== JSON.stringify(entry.commands)) {
|
|
163
|
+
await this.connection.sessionUpdate({
|
|
164
|
+
sessionId,
|
|
165
|
+
update: {
|
|
166
|
+
sessionUpdate: "available_commands_update",
|
|
167
|
+
availableCommands: commands
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
entry.commands = commands;
|
|
171
|
+
}
|
|
172
|
+
return skills;
|
|
173
|
+
}
|
|
174
|
+
configOptions(entry) {
|
|
175
|
+
const modelId = entry.session.model.get() ?? "";
|
|
176
|
+
const options = [];
|
|
177
|
+
const models = includeCurrentModel(entry.models, modelId);
|
|
178
|
+
if (models.length) options.push({
|
|
179
|
+
id: "model",
|
|
180
|
+
name: "Model",
|
|
181
|
+
category: "model",
|
|
182
|
+
type: "select",
|
|
183
|
+
currentValue: modelId,
|
|
184
|
+
options: models.map((model) => ({
|
|
185
|
+
value: model.modelId,
|
|
186
|
+
name: model.name
|
|
187
|
+
}))
|
|
188
|
+
});
|
|
189
|
+
options.push({
|
|
190
|
+
id: "mode",
|
|
191
|
+
name: "Mode",
|
|
192
|
+
category: "mode",
|
|
193
|
+
type: "select",
|
|
194
|
+
currentValue: entry.session.mode.get(),
|
|
195
|
+
options: entry.modes.map((mode) => ({
|
|
196
|
+
value: mode.id,
|
|
197
|
+
name: mode.name ?? mode.id
|
|
198
|
+
}))
|
|
84
199
|
});
|
|
85
|
-
|
|
200
|
+
if (entry.getThinkingLevel) options.push({
|
|
201
|
+
id: "thought_level",
|
|
202
|
+
name: "Reasoning effort",
|
|
203
|
+
category: "thought_level",
|
|
204
|
+
type: "select",
|
|
205
|
+
description: "Requested reasoning level. The provider may adjust it for the selected model.",
|
|
206
|
+
currentValue: this.thinkingLevel(entry),
|
|
207
|
+
options: getAvailableThinkingLevelsForModel(modelId).map((value) => ({
|
|
208
|
+
value,
|
|
209
|
+
name: value[0].toUpperCase() + value.slice(1)
|
|
210
|
+
}))
|
|
211
|
+
});
|
|
212
|
+
return options;
|
|
213
|
+
}
|
|
214
|
+
thinkingLevel(entry) {
|
|
215
|
+
const level = entry.getThinkingLevel?.() ?? "off";
|
|
216
|
+
return getAvailableThinkingLevelsForModel(entry.session.model.get() ?? "").includes(level) ? level : "xhigh";
|
|
217
|
+
}
|
|
218
|
+
async setSessionConfigOption(params) {
|
|
219
|
+
const entry = this.getSession(params.sessionId);
|
|
220
|
+
return this.enqueue(entry, async () => {
|
|
221
|
+
this.getSession(params.sessionId);
|
|
222
|
+
const option = this.configOptions(entry).find((option) => option.id === params.configId);
|
|
223
|
+
if (!option || option.type !== "select" || !option.options.some((item) => "value" in item && item.value === params.value)) throw RequestError.invalidParams(void 0, "Unknown session configuration selection");
|
|
224
|
+
if (params.configId === "model") await entry.session.model.switch({ modelId: String(params.value) });
|
|
225
|
+
else if (params.configId === "mode") await entry.session.mode.switch({ modeId: String(params.value) });
|
|
226
|
+
else if (isThinkingLevelSetting(params.value)) await entry.session.state.set({ thinkingLevel: params.value });
|
|
227
|
+
if (entry.getThinkingLevel && entry.getThinkingLevel() !== this.thinkingLevel(entry)) await entry.session.state.set({ thinkingLevel: this.thinkingLevel(entry) });
|
|
228
|
+
return { configOptions: this.configOptions(entry) };
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
async prompt(request) {
|
|
232
|
+
const entry = this.getSession(request.sessionId);
|
|
233
|
+
const content = extractTextFromContentBlocks(request.prompt);
|
|
234
|
+
const turn = { cancelled: false };
|
|
235
|
+
entry.turns.add(turn);
|
|
86
236
|
try {
|
|
87
|
-
await this.
|
|
88
|
-
|
|
237
|
+
return await this.enqueue(entry, async () => {
|
|
238
|
+
if (turn.cancelled || this.disposed) return { stopReason: "cancelled" };
|
|
89
239
|
const usage = {
|
|
90
240
|
promptTokens: 0,
|
|
91
241
|
completionTokens: 0,
|
|
92
242
|
totalTokens: 0
|
|
93
243
|
};
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
244
|
+
let complete;
|
|
245
|
+
const completion = new Promise((resolve) => {
|
|
246
|
+
complete = resolve;
|
|
247
|
+
});
|
|
248
|
+
const state = {
|
|
249
|
+
sessionId: request.sessionId,
|
|
97
250
|
usage,
|
|
98
251
|
resolve: (reason) => {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
usage
|
|
102
|
-
});
|
|
103
|
-
this.currentPromptState = null;
|
|
252
|
+
state.finished = true;
|
|
253
|
+
complete(reason);
|
|
104
254
|
}
|
|
105
255
|
};
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
256
|
+
entry.state = state;
|
|
257
|
+
try {
|
|
258
|
+
const skills = await this.refreshCommands(request.sessionId, entry);
|
|
259
|
+
const expanded = await expandSkillCommand(content, skills, entry.commands ?? []);
|
|
260
|
+
if (turn.cancelled || this.disposed) return { stopReason: "cancelled" };
|
|
261
|
+
await entry.session.sendMessage({ content: expanded });
|
|
262
|
+
const reason = await completion;
|
|
263
|
+
if (reason === "error" && !state.cancelled && !state.stopReason) throw RequestError.internalError(void 0, state.error?.message ?? "Mastra Code turn failed");
|
|
264
|
+
return {
|
|
265
|
+
stopReason: state.cancelled ? "cancelled" : state.stopReason ?? mapStopReason(reason),
|
|
266
|
+
usage: {
|
|
267
|
+
inputTokens: usage.promptTokens,
|
|
268
|
+
outputTokens: usage.completionTokens,
|
|
269
|
+
totalTokens: usage.totalTokens,
|
|
270
|
+
thoughtTokens: usage.reasoningTokens,
|
|
271
|
+
cachedReadTokens: usage.cachedInputTokens,
|
|
272
|
+
cachedWriteTokens: usage.cacheCreationInputTokens
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
} catch (error) {
|
|
276
|
+
if (state.cancelled) return { stopReason: "cancelled" };
|
|
277
|
+
if (error instanceof RequestError) throw error;
|
|
278
|
+
throw RequestError.internalError(void 0, error instanceof Error ? error.message : "Mastra Code turn failed");
|
|
279
|
+
} finally {
|
|
280
|
+
state.finished = true;
|
|
281
|
+
if (entry.state === state) entry.state = null;
|
|
123
282
|
}
|
|
124
|
-
};
|
|
283
|
+
});
|
|
125
284
|
} finally {
|
|
126
|
-
|
|
285
|
+
entry.turns.delete(turn);
|
|
127
286
|
}
|
|
128
287
|
}
|
|
129
|
-
async cancel(
|
|
130
|
-
this.
|
|
288
|
+
async cancel(notification) {
|
|
289
|
+
const entry = this.sessions.get(notification.sessionId);
|
|
290
|
+
if (!entry) return;
|
|
291
|
+
for (const turn of entry.turns) turn.cancelled = true;
|
|
292
|
+
if (entry.state && !entry.state.finished && !entry.state.cancelled) {
|
|
293
|
+
const state = entry.state;
|
|
294
|
+
state.cancelled = true;
|
|
295
|
+
for (const deny of state.cancelSuspensions?.values() ?? []) try {
|
|
296
|
+
await deny();
|
|
297
|
+
} catch {}
|
|
298
|
+
state.cancelSuspensions?.clear();
|
|
299
|
+
if (entry.state !== state) return;
|
|
300
|
+
entry.session.abort();
|
|
301
|
+
if (entry.state?.suspended) {
|
|
302
|
+
entry.session.stream.detach();
|
|
303
|
+
entry.state.resolve("aborted");
|
|
304
|
+
}
|
|
305
|
+
}
|
|
131
306
|
}
|
|
132
307
|
async setSessionMode(params) {
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
this.
|
|
308
|
+
const entry = this.getSession(params.sessionId);
|
|
309
|
+
if (!entry.modes.some((mode) => mode.id === params.modeId)) throw RequestError.invalidParams(void 0, "Unknown mode");
|
|
310
|
+
await this.enqueue(entry, async () => {
|
|
311
|
+
if (this.disposed) return;
|
|
312
|
+
await entry.session.mode.switch({ modeId: params.modeId });
|
|
313
|
+
});
|
|
136
314
|
}
|
|
137
315
|
async unstable_setSessionModel(params) {
|
|
138
|
-
const
|
|
139
|
-
await this.
|
|
140
|
-
|
|
316
|
+
const entry = this.getSession(params.sessionId);
|
|
317
|
+
await this.enqueue(entry, async () => {
|
|
318
|
+
if (this.disposed) return;
|
|
319
|
+
if (!includeCurrentModel(entry.models, entry.session.model.get() ?? "").some((model) => model.modelId === params.modelId)) throw RequestError.invalidParams(void 0, "Model is unavailable or its provider is not configured. Refresh the model list.");
|
|
320
|
+
await entry.session.model.switch({ modelId: params.modelId });
|
|
321
|
+
});
|
|
141
322
|
}
|
|
142
323
|
};
|
|
324
|
+
function includeCurrentModel(models, currentModelId) {
|
|
325
|
+
return currentModelId && !models.some((model) => model.modelId === currentModelId) ? [{
|
|
326
|
+
modelId: currentModelId,
|
|
327
|
+
name: currentModelId
|
|
328
|
+
}, ...models] : models;
|
|
329
|
+
}
|
|
143
330
|
function extractTextFromContentBlocks(blocks) {
|
|
144
331
|
const parts = [];
|
|
145
332
|
for (const block of blocks) if (block.type === "text") parts.push(block.text);
|
|
146
333
|
else if (block.type === "resource_link") parts.push(`[resource: ${block.uri}]`);
|
|
147
|
-
else if (block.type === "resource")
|
|
334
|
+
else if (block.type === "resource") {
|
|
335
|
+
parts.push(`[resource: ${block.resource.uri}]`);
|
|
336
|
+
if (!("text" in block.resource)) throw RequestError.invalidParams(void 0, "Binary prompt resources are not supported");
|
|
337
|
+
parts.push(block.resource.text);
|
|
338
|
+
} else throw RequestError.invalidParams(void 0, `Unsupported prompt content: ${block.type}`);
|
|
148
339
|
return parts.join("\n");
|
|
149
340
|
}
|
|
150
341
|
function mapStopReason(reason) {
|
|
151
342
|
switch (reason) {
|
|
152
343
|
case "complete": return "end_turn";
|
|
153
344
|
case "aborted": return "cancelled";
|
|
154
|
-
case "error":
|
|
345
|
+
case "error": throw RequestError.internalError(void 0, "Mastra Code turn failed");
|
|
155
346
|
case "suspended": return "end_turn";
|
|
156
347
|
}
|
|
157
348
|
}
|
package/dist/acp/agent.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.js","names":[],"sources":["../../src/acp/agent.ts"],"sourcesContent":["import type {\n Agent,\n AgentSideConnection,\n InitializeRequest,\n InitializeResponse,\n NewSessionRequest,\n NewSessionResponse,\n PromptRequest,\n PromptResponse,\n CancelNotification,\n ContentBlock,\n} from '@agentclientprotocol/sdk';\nimport { PROTOCOL_VERSION } from '@agentclientprotocol/sdk';\nimport type { AgentController, AgentControllerMode, Session } from '@mastra/core/agent-controller';\nimport { handleAgentControllerEvent } from './event-mapper.js';\nimport type { PromptState } from './event-mapper.js';\n\n/**\n * ACP Agent implementation that wraps a mastracode Controller.\n * Each instance represents one ACP connection from a client.\n */\nexport class MastraCodeAcpAgent implements Agent {\n private readonly connection: AgentSideConnection;\n private readonly controller: AgentController;\n private readonly session: Session;\n private readonly modes: AgentControllerMode[];\n private readonly unsubscribeSessionEvents: () => void;\n private readonly sessionMap = new Map<string, string>(); // sessionId -> threadId\n private currentPromptState: PromptState | null = null;\n private promptMutex: Promise<void> = Promise.resolve();\n\n private getThreadIdOrThrow(sessionId: string): string {\n const threadId = this.sessionMap.get(sessionId);\n if (!threadId) {\n throw new Error(`Unknown ACP sessionId: ${sessionId}`);\n }\n return threadId;\n }\n\n constructor(\n connection: AgentSideConnection,\n controller: AgentController,\n session: Session,\n modes: AgentControllerMode[],\n ) {\n this.connection = connection;\n this.controller = controller;\n this.session = session;\n this.modes = modes;\n\n // Register persistent event listener\n this.unsubscribeSessionEvents = this.session.subscribe(event => {\n handleAgentControllerEvent(event, this.currentPromptState, this.connection, this.session);\n });\n }\n\n dispose(): void {\n this.unsubscribeSessionEvents();\n }\n\n async initialize(_request: InitializeRequest): Promise<InitializeResponse> {\n return {\n protocolVersion: PROTOCOL_VERSION,\n agentInfo: {\n name: 'mastracode',\n title: 'Mastra Code',\n version: '0.1.0',\n },\n agentCapabilities: {\n loadSession: false,\n },\n };\n }\n\n async authenticate(): Promise<void> {\n // No-op: mastracode handles its own auth\n }\n\n async newSession(_request: NewSessionRequest): Promise<NewSessionResponse> {\n const thread = await this.session.thread.create();\n const sessionId = thread.id;\n this.sessionMap.set(sessionId, thread.id);\n\n // Switch to the new thread\n await this.session.thread.switch({ threadId: thread.id });\n\n // Build modes list from constructor param\n const availableModes = this.modes.map((m: AgentControllerMode) => ({\n id: m.id,\n name: m.name ?? m.id,\n }));\n\n const currentModeId = this.session.mode.get();\n\n // Build models list (best-effort)\n let models: NewSessionResponse['models'];\n try {\n const availableModels = await this.controller.listAvailableModels();\n const currentModelId = this.session.model.get();\n models = {\n currentModelId: currentModelId ?? '',\n availableModels: availableModels.map(m => ({\n modelId: m.id,\n name: m.modelName,\n })),\n };\n } catch {\n // Model listing may fail if no providers are configured\n }\n\n return {\n sessionId,\n modes: {\n currentModeId,\n availableModes,\n },\n models,\n };\n }\n\n async prompt(request: PromptRequest): Promise<PromptResponse> {\n const { sessionId, prompt: contentBlocks } = request;\n\n // Extract text from content blocks\n const text = extractTextFromContentBlocks(contentBlocks);\n\n const threadId = this.getThreadIdOrThrow(sessionId);\n\n // Serialize prompts via mutex\n const prevMutex = this.promptMutex;\n let resolveMutex: () => void;\n this.promptMutex = new Promise<void>(resolve => {\n resolveMutex = resolve;\n });\n\n await prevMutex;\n\n try {\n // Ensure we're on the right thread while prompts are serialized\n await this.session.thread.switch({ threadId });\n\n // Create prompt state that will be resolved when agent_end fires\n const result = new Promise<{\n reason: 'complete' | 'aborted' | 'error' | 'suspended';\n usage: PromptState['usage'];\n }>(resolve => {\n const usage: PromptState['usage'] = {\n promptTokens: 0,\n completionTokens: 0,\n totalTokens: 0,\n };\n\n this.currentPromptState = {\n sessionId,\n lastTextLength: 0,\n usage,\n resolve: reason => {\n resolve({ reason, usage });\n this.currentPromptState = null;\n },\n };\n });\n\n // Send the message to the session\n try {\n await this.session.sendMessage({ content: text });\n } catch (error) {\n this.currentPromptState = null;\n throw error;\n }\n\n // Wait for agent_end to resolve\n const { reason, usage } = await result;\n\n return {\n stopReason: mapStopReason(reason),\n usage: {\n inputTokens: usage.promptTokens,\n outputTokens: usage.completionTokens,\n totalTokens: usage.totalTokens,\n thoughtTokens: usage.reasoningTokens,\n cachedReadTokens: usage.cachedInputTokens,\n cachedWriteTokens: usage.cacheCreationInputTokens,\n },\n };\n } finally {\n resolveMutex!();\n }\n }\n\n async cancel(_notification: CancelNotification): Promise<void> {\n this.session.abort();\n }\n\n async setSessionMode(params: { sessionId: string; modeId: string }): Promise<void> {\n const threadId = this.getThreadIdOrThrow(params.sessionId);\n await this.session.thread.switch({ threadId });\n this.session.mode.set({ modeId: params.modeId });\n }\n\n async unstable_setSessionModel(params: { sessionId: string; modelId: string }): Promise<void> {\n const threadId = this.getThreadIdOrThrow(params.sessionId);\n await this.session.thread.switch({ threadId });\n this.session.model.set({ modelId: params.modelId });\n }\n}\n\nexport function extractTextFromContentBlocks(blocks: ContentBlock[]): string {\n const parts: string[] = [];\n for (const block of blocks) {\n if (block.type === 'text') {\n parts.push(block.text);\n } else if (block.type === 'resource_link') {\n parts.push(`[resource: ${block.uri}]`);\n } else if (block.type === 'resource') {\n parts.push(`[resource: ${block.resource.uri}]`);\n }\n }\n return parts.join('\\n');\n}\n\nexport function mapStopReason(\n reason: 'complete' | 'aborted' | 'error' | 'suspended',\n): 'end_turn' | 'cancelled' | 'max_tokens' | 'max_turn_requests' | 'refusal' {\n switch (reason) {\n case 'complete':\n return 'end_turn';\n case 'aborted':\n return 'cancelled';\n case 'error':\n return 'end_turn';\n case 'suspended':\n return 'end_turn';\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"agent.js","names":[],"sources":["../../src/acp/agent.ts"],"sourcesContent":["import { isAbsolute } from 'node:path';\nimport { PROTOCOL_VERSION, RequestError } from '@agentclientprotocol/sdk';\nimport type {\n Agent,\n AgentSideConnection,\n InitializeRequest,\n InitializeResponse,\n NewSessionRequest,\n NewSessionResponse,\n PromptRequest,\n PromptResponse,\n CancelNotification,\n ContentBlock,\n SessionConfigOption,\n SetSessionConfigOptionRequest,\n SetSessionConfigOptionResponse,\n AvailableCommand,\n} from '@agentclientprotocol/sdk';\nimport type { AgentController, AgentControllerMode, Session } from '@mastra/core/agent-controller';\nimport { getAvailableThinkingLevelsForModel, isThinkingLevelSetting } from '../thinking.js';\nimport type { ThinkingLevelSetting } from '../thinking.js';\nimport { getCurrentVersion } from '../utils/update-check.js';\nimport { withCleanupFailure } from './errors.js';\nimport { handleAgentControllerEvent } from './event-mapper.js';\nimport type { PromptState } from './event-mapper.js';\nimport { expandSkillCommand, listSkillCommands } from './skills.js';\nimport type { AcpSkills } from './skills.js';\n\nexport interface AcpSessionRuntime {\n controller: AgentController;\n session: Session;\n modes: AgentControllerMode[];\n getThinkingLevel?: () => ThinkingLevelSetting;\n getSkills?: () => Promise<AcpSkills | undefined>;\n cleanup?: () => Promise<void>;\n}\n\nexport type AcpSessionFactory = (request: NewSessionRequest) => Promise<AcpSessionRuntime>;\n\ninterface SessionEntry extends AcpSessionRuntime {\n models: { modelId: string; name: string }[];\n state: PromptState | null;\n queue: Promise<void>;\n turns: Set<{ cancelled: boolean }>;\n unsubscribe: () => void;\n commands?: AvailableCommand[];\n}\n\n/** One ACP connection, with an independent Mastra Code runtime for each conversation. */\nexport class MastraCodeAcpAgent implements Agent {\n private readonly sessions = new Map<string, SessionEntry>();\n private readonly pendingCreations = new Set<Promise<NewSessionResponse>>();\n private readonly startupCleanupFailures: unknown[] = [];\n private disposed = false;\n private disposal?: Promise<void>;\n\n constructor(\n private readonly connection: AgentSideConnection,\n private readonly createSession: AcpSessionFactory,\n ) {}\n\n private getSession(sessionId: string): SessionEntry {\n const entry = this.sessions.get(sessionId);\n if (!entry || this.disposed) throw RequestError.invalidParams({ sessionId }, 'Unknown ACP session');\n return entry;\n }\n\n private enqueue<T>(entry: SessionEntry, operation: () => Promise<T>): Promise<T> {\n const result = entry.queue.then(operation);\n entry.queue = result.then(\n () => {},\n () => {},\n );\n return result;\n }\n\n dispose(): Promise<void> {\n if (this.disposal) return this.disposal;\n this.disposed = true;\n const entries = [...this.sessions.values()];\n this.sessions.clear();\n const cleanup = Promise.allSettled([\n // A runtime under construction owns its cleanup until it joins sessions.\n Promise.allSettled([...this.pendingCreations]),\n ...entries.map(async entry => {\n for (const turn of entry.turns) turn.cancelled = true;\n if (entry.state) {\n entry.state.cancelled = true;\n entry.session.abort();\n entry.state?.resolve('aborted');\n }\n entry.unsubscribe();\n await entry.cleanup?.();\n }),\n ]).then(results => {\n const failures = results.filter(result => result.status === 'rejected').map(result => result.reason);\n failures.push(...this.startupCleanupFailures);\n if (failures.length) throw new AggregateError(failures, 'ACP session cleanup failed');\n });\n // A provider or MCP startup can stall. Keep its cleanup ownership, but let\n // the host terminate the connection if shutdown cannot finish in time.\n this.disposal = new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => reject(new Error('ACP shutdown timed out after 10 seconds')), 10_000);\n void cleanup.then(resolve, reject).finally(() => clearTimeout(timeout));\n });\n return this.disposal;\n }\n\n async initialize(_request: InitializeRequest): Promise<InitializeResponse> {\n return {\n protocolVersion: PROTOCOL_VERSION,\n agentInfo: { name: 'mastracode', title: 'Mastra Code', version: getCurrentVersion() },\n agentCapabilities: { loadSession: false, mcpCapabilities: { http: true, sse: false } },\n };\n }\n\n async authenticate(): Promise<void> {\n throw RequestError.invalidParams(undefined, 'Configure authentication through Mastra Code before starting ACP');\n }\n\n newSession(request: NewSessionRequest): Promise<NewSessionResponse> {\n const creating = Promise.resolve().then(() => this.createNewSession(request));\n this.pendingCreations.add(creating);\n void creating.then(\n () => this.pendingCreations.delete(creating),\n () => this.pendingCreations.delete(creating),\n );\n return creating;\n }\n\n private async createNewSession(request: NewSessionRequest): Promise<NewSessionResponse> {\n if (this.disposed) throw RequestError.internalError(undefined, 'ACP connection is closed');\n if (!isAbsolute(request.cwd)) throw RequestError.invalidParams(undefined, 'cwd must be an absolute path');\n const runtime = await this.createSession(request);\n try {\n if (this.disposed) throw RequestError.internalError(undefined, 'ACP connection is closed');\n const thread = await runtime.session.thread.create();\n await runtime.session.thread.switch({ threadId: thread.id });\n let models: NewSessionResponse['models'];\n try {\n const available = await runtime.controller.listAvailableModels();\n models = {\n currentModelId: runtime.session.model.get() ?? '',\n availableModels: includeCurrentModel(\n [\n ...new Map(\n available\n .filter(model => model.hasApiKey || model.id === runtime.session.model.get())\n .map(\n model =>\n [\n model.id,\n {\n modelId: model.id,\n name: model.hasApiKey ? model.id : `${model.id} (provider not configured)`,\n },\n ] as const,\n ),\n ).values(),\n ],\n runtime.session.model.get() ?? '',\n ),\n };\n } catch {\n // Discovery may be unavailable before provider authentication.\n }\n if (this.disposed) throw RequestError.internalError(undefined, 'ACP connection is closed');\n const entry: SessionEntry = {\n ...runtime,\n models: models?.availableModels ?? [],\n state: null,\n queue: Promise.resolve(),\n turns: new Set(),\n unsubscribe: () => {},\n commands: [],\n };\n if (this.disposed) throw RequestError.internalError(undefined, 'ACP connection is closed');\n entry.unsubscribe = runtime.session.subscribe(event => {\n handleAgentControllerEvent(event, entry.state, this.connection, entry.session);\n if (event.type === 'mode_changed') {\n void this.connection\n .sessionUpdate({\n sessionId: thread.id,\n update: { sessionUpdate: 'current_mode_update', currentModeId: entry.session.mode.get() },\n })\n .catch(error => process.stderr.write(`[acp] mode update failed: ${error}\\n`));\n }\n if (\n event.type === 'mode_changed' ||\n event.type === 'model_changed' ||\n (event.type === 'state_changed' && event.changedKeys.includes('thinkingLevel'))\n ) {\n void this.connection\n .sessionUpdate({\n sessionId: thread.id,\n update: { sessionUpdate: 'config_option_update', configOptions: this.configOptions(entry) },\n })\n .catch(error => process.stderr.write(`[acp] configuration update failed: ${error}\\n`));\n }\n });\n const response: NewSessionResponse = {\n sessionId: thread.id,\n modes: {\n currentModeId: runtime.session.mode.get(),\n availableModes: runtime.modes.map(mode => ({ id: mode.id, name: mode.name ?? mode.id })),\n },\n models,\n configOptions: this.configOptions(entry),\n };\n this.sessions.set(thread.id, entry);\n // Let the SDK send session/new before clients receive updates for this ID.\n setImmediate(() => {\n void this.enqueue(entry, async () => {\n if (!this.disposed) await this.refreshCommands(thread.id, entry);\n }).catch(error => process.stderr.write(`[acp] command discovery failed: ${error}\\n`));\n });\n return response;\n } catch (error) {\n try {\n await runtime.cleanup?.();\n } catch (cleanupError) {\n if (this.disposed) this.startupCleanupFailures.push(cleanupError);\n throw withCleanupFailure(error, cleanupError);\n }\n throw error;\n }\n }\n\n private async refreshCommands(sessionId: string, entry: SessionEntry): Promise<AcpSkills | undefined> {\n const skills = await entry.getSkills?.();\n const commands = await listSkillCommands(skills);\n if (JSON.stringify(commands) !== JSON.stringify(entry.commands)) {\n await this.connection.sessionUpdate({\n sessionId,\n update: { sessionUpdate: 'available_commands_update', availableCommands: commands },\n });\n entry.commands = commands;\n }\n return skills;\n }\n\n private configOptions(entry: SessionEntry): SessionConfigOption[] {\n const modelId = entry.session.model.get() ?? '';\n const options: SessionConfigOption[] = [];\n const models = includeCurrentModel(entry.models, modelId);\n if (models.length)\n options.push({\n id: 'model',\n name: 'Model',\n category: 'model',\n type: 'select',\n currentValue: modelId,\n options: models.map(model => ({ value: model.modelId, name: model.name })),\n });\n options.push({\n id: 'mode',\n name: 'Mode',\n category: 'mode',\n type: 'select',\n currentValue: entry.session.mode.get(),\n options: entry.modes.map(mode => ({ value: mode.id, name: mode.name ?? mode.id })),\n });\n if (entry.getThinkingLevel)\n options.push({\n id: 'thought_level',\n name: 'Reasoning effort',\n category: 'thought_level',\n type: 'select',\n description: 'Requested reasoning level. The provider may adjust it for the selected model.',\n currentValue: this.thinkingLevel(entry),\n options: getAvailableThinkingLevelsForModel(modelId).map(value => ({\n value,\n name: value[0]!.toUpperCase() + value.slice(1),\n })),\n });\n return options;\n }\n\n private thinkingLevel(entry: SessionEntry): ThinkingLevelSetting {\n const level = entry.getThinkingLevel?.() ?? 'off';\n const levels = getAvailableThinkingLevelsForModel(entry.session.model.get() ?? '');\n return levels.includes(level) ? level : 'xhigh';\n }\n\n async setSessionConfigOption(params: SetSessionConfigOptionRequest): Promise<SetSessionConfigOptionResponse> {\n const entry = this.getSession(params.sessionId);\n return this.enqueue(entry, async () => {\n this.getSession(params.sessionId);\n const option = this.configOptions(entry).find(option => option.id === params.configId);\n if (\n !option ||\n option.type !== 'select' ||\n !option.options.some(item => 'value' in item && item.value === params.value)\n ) {\n throw RequestError.invalidParams(undefined, 'Unknown session configuration selection');\n }\n if (params.configId === 'model') {\n await entry.session.model.switch({ modelId: String(params.value) });\n } else if (params.configId === 'mode') {\n await entry.session.mode.switch({ modeId: String(params.value) });\n } else if (isThinkingLevelSetting(params.value)) {\n await entry.session.state.set({ thinkingLevel: params.value });\n }\n if (entry.getThinkingLevel && entry.getThinkingLevel() !== this.thinkingLevel(entry)) {\n await entry.session.state.set({ thinkingLevel: this.thinkingLevel(entry) });\n }\n return { configOptions: this.configOptions(entry) };\n });\n }\n\n async prompt(request: PromptRequest): Promise<PromptResponse> {\n const entry = this.getSession(request.sessionId);\n const content = extractTextFromContentBlocks(request.prompt);\n const turn = { cancelled: false };\n entry.turns.add(turn);\n try {\n return await this.enqueue(entry, async () => {\n if (turn.cancelled || this.disposed) return { stopReason: 'cancelled' };\n const usage: PromptState['usage'] = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };\n let complete!: PromptState['resolve'];\n const completion = new Promise<Parameters<PromptState['resolve']>[0]>(resolve => {\n complete = resolve;\n });\n const state: PromptState = {\n sessionId: request.sessionId,\n usage,\n resolve: reason => {\n state.finished = true;\n complete(reason);\n },\n };\n entry.state = state;\n try {\n const skills = await this.refreshCommands(request.sessionId, entry);\n const expanded = await expandSkillCommand(content, skills, entry.commands ?? []);\n if (turn.cancelled || this.disposed) return { stopReason: 'cancelled' };\n await entry.session.sendMessage({ content: expanded });\n const reason = await completion;\n if (reason === 'error' && !state.cancelled && !state.stopReason) {\n throw RequestError.internalError(undefined, state.error?.message ?? 'Mastra Code turn failed');\n }\n return {\n stopReason: state.cancelled ? 'cancelled' : (state.stopReason ?? mapStopReason(reason)),\n usage: {\n inputTokens: usage.promptTokens,\n outputTokens: usage.completionTokens,\n totalTokens: usage.totalTokens,\n thoughtTokens: usage.reasoningTokens,\n cachedReadTokens: usage.cachedInputTokens,\n cachedWriteTokens: usage.cacheCreationInputTokens,\n },\n };\n } catch (error) {\n if (state.cancelled) return { stopReason: 'cancelled' };\n if (error instanceof RequestError) throw error;\n throw RequestError.internalError(\n undefined,\n error instanceof Error ? error.message : 'Mastra Code turn failed',\n );\n } finally {\n state.finished = true;\n if (entry.state === state) entry.state = null;\n }\n });\n } finally {\n entry.turns.delete(turn);\n }\n }\n\n async cancel(notification: CancelNotification): Promise<void> {\n const entry = this.sessions.get(notification.sessionId);\n if (!entry) return;\n for (const turn of entry.turns) turn.cancelled = true;\n if (entry.state && !entry.state.finished && !entry.state.cancelled) {\n const state = entry.state;\n state.cancelled = true;\n // Persist denial before aborting, otherwise a parked snapshot can replay on the next turn.\n for (const deny of state.cancelSuspensions?.values() ?? []) {\n try {\n await deny();\n } catch {\n /* Still abort if the suspended run is no longer available. */\n }\n }\n state.cancelSuspensions?.clear();\n if (entry.state !== state) return;\n entry.session.abort();\n // A suspended run has already ended and will not emit another agent_end.\n if (entry.state?.suspended) {\n entry.session.stream.detach();\n entry.state.resolve('aborted');\n }\n }\n }\n\n async setSessionMode(params: { sessionId: string; modeId: string }): Promise<void> {\n const entry = this.getSession(params.sessionId);\n if (!entry.modes.some(mode => mode.id === params.modeId))\n throw RequestError.invalidParams(undefined, 'Unknown mode');\n await this.enqueue(entry, async () => {\n if (this.disposed) return;\n await entry.session.mode.switch({ modeId: params.modeId });\n });\n }\n\n async unstable_setSessionModel(params: { sessionId: string; modelId: string }): Promise<void> {\n const entry = this.getSession(params.sessionId);\n await this.enqueue(entry, async () => {\n if (this.disposed) return;\n if (\n !includeCurrentModel(entry.models, entry.session.model.get() ?? '').some(\n model => model.modelId === params.modelId,\n )\n ) {\n throw RequestError.invalidParams(\n undefined,\n 'Model is unavailable or its provider is not configured. Refresh the model list.',\n );\n }\n await entry.session.model.switch({ modelId: params.modelId });\n });\n }\n}\n\nfunction includeCurrentModel(models: SessionEntry['models'], currentModelId: string): SessionEntry['models'] {\n // Saved/custom model IDs may work even when discovery only returns a gateway-qualified alias.\n return currentModelId && !models.some(model => model.modelId === currentModelId)\n ? [{ modelId: currentModelId, name: currentModelId }, ...models]\n : models;\n}\n\nexport function extractTextFromContentBlocks(blocks: ContentBlock[]): string {\n const parts: string[] = [];\n for (const block of blocks) {\n if (block.type === 'text') {\n parts.push(block.text);\n } else if (block.type === 'resource_link') {\n parts.push(`[resource: ${block.uri}]`);\n } else if (block.type === 'resource') {\n parts.push(`[resource: ${block.resource.uri}]`);\n if (!('text' in block.resource))\n throw RequestError.invalidParams(undefined, 'Binary prompt resources are not supported');\n parts.push(block.resource.text);\n } else {\n throw RequestError.invalidParams(undefined, `Unsupported prompt content: ${block.type}`);\n }\n }\n return parts.join('\\n');\n}\n\nexport function mapStopReason(\n reason: 'complete' | 'aborted' | 'error' | 'suspended',\n): 'end_turn' | 'cancelled' | 'max_tokens' | 'max_turn_requests' | 'refusal' {\n switch (reason) {\n case 'complete':\n return 'end_turn';\n case 'aborted':\n return 'cancelled';\n case 'error':\n throw RequestError.internalError(undefined, 'Mastra Code turn failed');\n case 'suspended':\n return 'end_turn';\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/acp/errors.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,GAAG,OAAO,CAajF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/acp/errors.ts
|
|
2
|
+
/** Keep the session failure primary, including its ACP code, when cleanup also fails. */
|
|
3
|
+
function withCleanupFailure(error, cleanupError) {
|
|
4
|
+
if (error instanceof Error) {
|
|
5
|
+
error.cause = new AggregateError(error.cause === void 0 ? [cleanupError] : [error.cause, cleanupError], "ACP session cleanup also failed");
|
|
6
|
+
return error;
|
|
7
|
+
}
|
|
8
|
+
const message = error !== null && typeof error === "object" && "message" in error && typeof error.message === "string" ? error.message : String(error);
|
|
9
|
+
return new AggregateError([error, cleanupError], message, { cause: error });
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { withCleanupFailure };
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","names":[],"sources":["../../src/acp/errors.ts"],"sourcesContent":["/** Keep the session failure primary, including its ACP code, when cleanup also fails. */\nexport function withCleanupFailure(error: unknown, cleanupError: unknown): unknown {\n if (error instanceof Error) {\n error.cause = new AggregateError(\n error.cause === undefined ? [cleanupError] : [error.cause, cleanupError],\n 'ACP session cleanup also failed',\n );\n return error;\n }\n const message =\n error !== null && typeof error === 'object' && 'message' in error && typeof error.message === 'string'\n ? error.message\n : String(error);\n return new AggregateError([error, cleanupError], message, { cause: error });\n}\n"],"mappings":";;AACA,SAAgB,mBAAmB,OAAgB,cAAgC;CACjF,IAAI,iBAAiB,OAAO;EAC1B,MAAM,QAAQ,IAAI,eAChB,MAAM,UAAU,KAAA,IAAY,CAAC,YAAY,IAAI,CAAC,MAAM,OAAO,YAAY,GACvE,iCACF;EACA,OAAO;CACT;CACA,MAAM,UACJ,UAAU,QAAQ,OAAO,UAAU,YAAY,aAAa,SAAS,OAAO,MAAM,YAAY,WAC1F,MAAM,UACN,OAAO,KAAK;CAClB,OAAO,IAAI,eAAe,CAAC,OAAO,YAAY,GAAG,SAAS,EAAE,OAAO,MAAM,CAAC;AAC5E"}
|
|
@@ -10,8 +10,13 @@ export declare function setAutoApprove(value: boolean): void;
|
|
|
10
10
|
export interface PromptState {
|
|
11
11
|
sessionId: string;
|
|
12
12
|
activeAssistantMessageId?: string;
|
|
13
|
-
lastTextLength: number;
|
|
14
13
|
usage: TokenUsage;
|
|
14
|
+
error?: Error;
|
|
15
|
+
stopReason?: 'max_tokens' | 'refusal';
|
|
16
|
+
finished?: boolean;
|
|
17
|
+
cancelled?: boolean;
|
|
18
|
+
suspended?: boolean;
|
|
19
|
+
cancelSuspensions?: Map<string, () => Promise<void>>;
|
|
15
20
|
resolve: (reason: 'complete' | 'aborted' | 'error' | 'suspended') => void;
|
|
16
21
|
}
|
|
17
22
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-mapper.d.ts","sourceRoot":"","sources":["../../src/acp/event-mapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiD,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACnH,OAAO,KAAK,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"event-mapper.d.ts","sourceRoot":"","sources":["../../src/acp/event-mapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiD,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACnH,OAAO,KAAK,EAAE,oBAAoB,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAI/F;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAEnD;AA4BD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,UAAU,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iBAAiB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACrD,OAAO,EAAE,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,KAAK,IAAI,CAAC;CAC3E;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,oBAAoB,EAC3B,KAAK,EAAE,WAAW,GAAG,IAAI,EACzB,UAAU,EAAE,mBAAmB,EAC/B,OAAO,EAAE,OAAO,GACf,IAAI,CA6FN"}
|