@mastra/acp 0.4.0 → 0.4.1-alpha.0
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/LICENSE.md +6 -4
- package/dist/agent.d.ts.map +1 -1
- package/dist/connection.d.ts.map +1 -1
- package/dist/docs/SKILL.md +5 -4
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/{docs-agents-acp.md → docs-connections-acp.md} +25 -11
- package/dist/docs/references/docs-connections-overview.md +96 -0
- package/dist/docs/references/reference-acp-acp-agent.md +9 -7
- package/dist/docs/references/reference-acp-create-acp-tool.md +6 -4
- package/dist/index.cjs +674 -726
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +650 -720
- package/dist/index.js.map +1 -1
- package/dist/session.d.ts.map +1 -1
- package/package.json +11 -11
- package/CHANGELOG.md +0 -275
package/dist/index.js
CHANGED
|
@@ -1,750 +1,680 @@
|
|
|
1
|
-
import { randomUUID } from
|
|
2
|
-
import { ReadableStream } from
|
|
3
|
-
import { MessageList, coreContentToString } from
|
|
4
|
-
import { spawn } from
|
|
5
|
-
import process from
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { createTool } from
|
|
10
|
-
|
|
11
|
-
// src/agent.ts
|
|
1
|
+
import { randomUUID } from "crypto";
|
|
2
|
+
import { ReadableStream } from "stream/web";
|
|
3
|
+
import { MessageList, coreContentToString } from "@mastra/core/agent/message-list";
|
|
4
|
+
import { spawn } from "child_process";
|
|
5
|
+
import process from "process";
|
|
6
|
+
import { Readable, Writable } from "stream";
|
|
7
|
+
import { ClientSideConnection, PROTOCOL_VERSION, ndJsonStream } from "@agentclientprotocol/sdk";
|
|
8
|
+
import { LocalFilesystem, Workspace } from "@mastra/core/workspace";
|
|
9
|
+
import { createTool } from "@mastra/core/tools";
|
|
10
|
+
//#region src/connection.ts
|
|
12
11
|
var ACPClient = class {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
return { content };
|
|
58
|
-
}
|
|
59
|
-
async writeTextFile(params) {
|
|
60
|
-
await this.workspace.filesystem?.writeFile(params.path, params.content);
|
|
61
|
-
return {};
|
|
62
|
-
}
|
|
12
|
+
getPromptState;
|
|
13
|
+
workspace;
|
|
14
|
+
onPermissionRequest;
|
|
15
|
+
constructor(getPromptState, workspace, onPermissionRequest) {
|
|
16
|
+
this.getPromptState = getPromptState;
|
|
17
|
+
this.workspace = workspace;
|
|
18
|
+
this.onPermissionRequest = onPermissionRequest;
|
|
19
|
+
}
|
|
20
|
+
async sessionUpdate(notification) {
|
|
21
|
+
const state = this.getPromptState();
|
|
22
|
+
if (!state || notification.sessionId !== state.sessionId) return;
|
|
23
|
+
const update = notification.update;
|
|
24
|
+
if (update.sessionUpdate === "agent_message_chunk") {
|
|
25
|
+
if (update.content.type === "text") state.onEvent?.({
|
|
26
|
+
type: "text",
|
|
27
|
+
text: update.content.text
|
|
28
|
+
});
|
|
29
|
+
} else state.onEvent?.({
|
|
30
|
+
type: "session-update",
|
|
31
|
+
update
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
async requestPermission(request) {
|
|
35
|
+
if (this.onPermissionRequest) return this.onPermissionRequest(request);
|
|
36
|
+
const option = request.options[0];
|
|
37
|
+
if (!option) return { outcome: { outcome: "cancelled" } };
|
|
38
|
+
return { outcome: selectedPermissionOutcome(option) };
|
|
39
|
+
}
|
|
40
|
+
async readTextFile(params) {
|
|
41
|
+
let content = await this.workspace.filesystem?.readFile(params.path);
|
|
42
|
+
if (!(typeof content === "string")) content = new TextDecoder("utf-8").decode(content);
|
|
43
|
+
if (params.line != null || params.limit != null) {
|
|
44
|
+
const lines = content.split("\n");
|
|
45
|
+
const start = (params.line ?? 1) - 1;
|
|
46
|
+
const end = params.limit != null ? start + params.limit : lines.length;
|
|
47
|
+
return { content: lines.slice(start, end).join("\n") };
|
|
48
|
+
}
|
|
49
|
+
return { content };
|
|
50
|
+
}
|
|
51
|
+
async writeTextFile(params) {
|
|
52
|
+
await this.workspace.filesystem?.writeFile(params.path, params.content);
|
|
53
|
+
return {};
|
|
54
|
+
}
|
|
63
55
|
};
|
|
64
56
|
var ACPConnection = class {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
cwd: this.options.cwd ?? process.cwd(),
|
|
249
|
-
mcpServers: [],
|
|
250
|
-
...this.options.session
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
throwIfPromptDidNotComplete(response) {
|
|
254
|
-
if (response.stopReason === "end_turn") {
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
throw new Error(`ACP prompt stopped before completing: ${response.stopReason}`);
|
|
258
|
-
}
|
|
259
|
-
withStderr(error) {
|
|
260
|
-
const stderr = this.stderr.trim();
|
|
261
|
-
if (error instanceof Error) {
|
|
262
|
-
if (stderr && !error.message.includes(stderr)) {
|
|
263
|
-
error.message = `${error.message}
|
|
264
|
-
|
|
265
|
-
ACP agent stderr:
|
|
266
|
-
${stderr}`;
|
|
267
|
-
}
|
|
268
|
-
return error;
|
|
269
|
-
}
|
|
270
|
-
return new Error(stderr ? `${String(error)}
|
|
271
|
-
|
|
272
|
-
ACP agent stderr:
|
|
273
|
-
${stderr}` : String(error));
|
|
274
|
-
}
|
|
57
|
+
options;
|
|
58
|
+
agentProcess;
|
|
59
|
+
connection;
|
|
60
|
+
session;
|
|
61
|
+
initializePromise;
|
|
62
|
+
currentPrompt;
|
|
63
|
+
stderr = "";
|
|
64
|
+
constructor(options) {
|
|
65
|
+
this.options = options;
|
|
66
|
+
}
|
|
67
|
+
get sessionId() {
|
|
68
|
+
return this.session?.sessionId;
|
|
69
|
+
}
|
|
70
|
+
async getAvailableModels() {
|
|
71
|
+
await this.ensureConnected();
|
|
72
|
+
return this.session?.models?.availableModels ?? [];
|
|
73
|
+
}
|
|
74
|
+
async setModel(modelId) {
|
|
75
|
+
await this.ensureConnected();
|
|
76
|
+
const available = this.session?.models?.availableModels;
|
|
77
|
+
if (available && !available.some((m) => m.modelId === modelId)) {
|
|
78
|
+
const ids = available.map((m) => m.modelId).join(", ") || "(none)";
|
|
79
|
+
throw new Error(`Model "${modelId}" is not available. Available models: ${ids}`);
|
|
80
|
+
}
|
|
81
|
+
await this.connection.unstable_setSessionModel({
|
|
82
|
+
sessionId: this.session.sessionId,
|
|
83
|
+
modelId
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
async prompt(task, signal) {
|
|
87
|
+
const parts = [];
|
|
88
|
+
for await (const event of this.promptStream(task, signal)) if (event.type === "text") parts.push(event.text);
|
|
89
|
+
return parts.join("");
|
|
90
|
+
}
|
|
91
|
+
async *promptStream(task, signal) {
|
|
92
|
+
await this.ensureConnected();
|
|
93
|
+
const sessionId = this.session?.sessionId;
|
|
94
|
+
if (!this.connection || !sessionId) throw new Error("ACP connection is not initialized");
|
|
95
|
+
if (signal?.aborted) {
|
|
96
|
+
await this.cancel();
|
|
97
|
+
throw signal.reason ?? /* @__PURE__ */ new Error("ACP prompt aborted");
|
|
98
|
+
}
|
|
99
|
+
const queue = createAsyncQueue();
|
|
100
|
+
const state = {
|
|
101
|
+
sessionId,
|
|
102
|
+
onEvent: (event) => queue.push(event)
|
|
103
|
+
};
|
|
104
|
+
this.currentPrompt = state;
|
|
105
|
+
const abortHandler = () => {
|
|
106
|
+
this.cancel();
|
|
107
|
+
queue.throw(signal?.reason ?? /* @__PURE__ */ new Error("ACP prompt aborted"));
|
|
108
|
+
};
|
|
109
|
+
signal?.addEventListener("abort", abortHandler, { once: true });
|
|
110
|
+
const responsePromise = this.connection.prompt({
|
|
111
|
+
sessionId,
|
|
112
|
+
prompt: [{
|
|
113
|
+
type: "text",
|
|
114
|
+
text: task
|
|
115
|
+
}]
|
|
116
|
+
}).then((response) => {
|
|
117
|
+
this.throwIfPromptDidNotComplete(response);
|
|
118
|
+
queue.close();
|
|
119
|
+
}, (error) => {
|
|
120
|
+
queue.throw(this.withStderr(error));
|
|
121
|
+
});
|
|
122
|
+
try {
|
|
123
|
+
for await (const chunk of queue) yield chunk;
|
|
124
|
+
await responsePromise;
|
|
125
|
+
} catch (error) {
|
|
126
|
+
await responsePromise.catch(() => void 0);
|
|
127
|
+
throw error;
|
|
128
|
+
} finally {
|
|
129
|
+
signal?.removeEventListener("abort", abortHandler);
|
|
130
|
+
if (this.currentPrompt === state) this.currentPrompt = void 0;
|
|
131
|
+
if (this.options.persistSession === false) this.disconnect();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async cancel() {
|
|
135
|
+
const sessionId = this.session?.sessionId;
|
|
136
|
+
if (!this.connection || !sessionId) return;
|
|
137
|
+
await this.connection.cancel({ sessionId });
|
|
138
|
+
}
|
|
139
|
+
disconnect() {
|
|
140
|
+
this.connection = void 0;
|
|
141
|
+
this.session = void 0;
|
|
142
|
+
this.initializePromise = void 0;
|
|
143
|
+
this.currentPrompt = void 0;
|
|
144
|
+
if (this.agentProcess && !this.agentProcess.killed) this.agentProcess.kill();
|
|
145
|
+
this.agentProcess = void 0;
|
|
146
|
+
}
|
|
147
|
+
async ensureConnected() {
|
|
148
|
+
if (this.connection && this.session) return;
|
|
149
|
+
this.initializePromise ??= this.initialize();
|
|
150
|
+
await this.initializePromise;
|
|
151
|
+
}
|
|
152
|
+
async initialize() {
|
|
153
|
+
this.stderr = "";
|
|
154
|
+
this.agentProcess = spawn(this.options.command, this.options.args ?? [], {
|
|
155
|
+
cwd: this.options.cwd,
|
|
156
|
+
env: {
|
|
157
|
+
...process.env,
|
|
158
|
+
...this.options.env
|
|
159
|
+
},
|
|
160
|
+
stdio: [
|
|
161
|
+
"pipe",
|
|
162
|
+
"pipe",
|
|
163
|
+
"pipe"
|
|
164
|
+
]
|
|
165
|
+
});
|
|
166
|
+
const processFailure = new Promise((_, reject) => {
|
|
167
|
+
this.agentProcess.on("error", (error) => {
|
|
168
|
+
reject(error instanceof Error ? error : new Error(String(error)));
|
|
169
|
+
});
|
|
170
|
+
this.agentProcess.on("exit", (code, signal) => {
|
|
171
|
+
reject(/* @__PURE__ */ new Error(`ACP agent process exited during initialization (code: ${code}, signal: ${signal})`));
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
processFailure.catch(() => void 0);
|
|
175
|
+
this.agentProcess.stderr.on("data", (chunk) => {
|
|
176
|
+
this.stderr += String(chunk);
|
|
177
|
+
});
|
|
178
|
+
const stream = ndJsonStream(Writable.toWeb(this.agentProcess.stdin), Readable.toWeb(this.agentProcess.stdout));
|
|
179
|
+
const workspace = this.options.workspace ?? new Workspace({ filesystem: new LocalFilesystem({ basePath: this.options.cwd ?? process.cwd() }) });
|
|
180
|
+
try {
|
|
181
|
+
this.connection = new ClientSideConnection(() => {
|
|
182
|
+
const defaultClient = new ACPClient(() => this.currentPrompt, workspace, this.options.onPermissionRequest);
|
|
183
|
+
return this.options.createClient?.(defaultClient) ?? defaultClient;
|
|
184
|
+
}, stream);
|
|
185
|
+
await Promise.race([processFailure, this.initializeSession()]);
|
|
186
|
+
} catch (error) {
|
|
187
|
+
this.disconnect();
|
|
188
|
+
throw this.withStderr(error);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
async initializeSession() {
|
|
192
|
+
await this.connection.initialize(this.getInitializeRequest());
|
|
193
|
+
if (this.options.authMethodId) await this.connection.authenticate({ methodId: this.options.authMethodId });
|
|
194
|
+
this.session = await this.connection.newSession(this.getNewSessionRequest());
|
|
195
|
+
if (this.options.model) {
|
|
196
|
+
const available = this.session.models?.availableModels;
|
|
197
|
+
if (available && !available.some((m) => m.modelId === this.options.model)) {
|
|
198
|
+
const ids = available.map((m) => m.modelId).join(", ") || "(none)";
|
|
199
|
+
throw new Error(`Model "${this.options.model}" is not available. Available models: ${ids}`);
|
|
200
|
+
}
|
|
201
|
+
await this.connection.unstable_setSessionModel({
|
|
202
|
+
sessionId: this.session.sessionId,
|
|
203
|
+
modelId: this.options.model
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
getInitializeRequest() {
|
|
208
|
+
return {
|
|
209
|
+
protocolVersion: PROTOCOL_VERSION,
|
|
210
|
+
clientCapabilities: { fs: {
|
|
211
|
+
readTextFile: true,
|
|
212
|
+
writeTextFile: true
|
|
213
|
+
} },
|
|
214
|
+
clientInfo: {
|
|
215
|
+
name: "@mastra/acp",
|
|
216
|
+
version: "0.1.0"
|
|
217
|
+
},
|
|
218
|
+
...this.options.initialize
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
getNewSessionRequest() {
|
|
222
|
+
return {
|
|
223
|
+
cwd: this.options.cwd ?? process.cwd(),
|
|
224
|
+
mcpServers: [],
|
|
225
|
+
...this.options.session
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
throwIfPromptDidNotComplete(response) {
|
|
229
|
+
if (response.stopReason === "end_turn") return;
|
|
230
|
+
throw new Error(`ACP prompt stopped before completing: ${response.stopReason}`);
|
|
231
|
+
}
|
|
232
|
+
withStderr(error) {
|
|
233
|
+
const stderr = this.stderr.trim();
|
|
234
|
+
if (error instanceof Error) {
|
|
235
|
+
if (stderr && !error.message.includes(stderr)) error.message = `${error.message}\n\nACP agent stderr:\n${stderr}`;
|
|
236
|
+
return error;
|
|
237
|
+
}
|
|
238
|
+
return new Error(stderr ? `${String(error)}\n\nACP agent stderr:\n${stderr}` : String(error));
|
|
239
|
+
}
|
|
275
240
|
};
|
|
276
241
|
function createAsyncQueue() {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
242
|
+
const values = [];
|
|
243
|
+
const waiters = [];
|
|
244
|
+
let closed = false;
|
|
245
|
+
let error;
|
|
246
|
+
const next = () => {
|
|
247
|
+
if (values.length > 0) return Promise.resolve({
|
|
248
|
+
value: values.shift(),
|
|
249
|
+
done: false
|
|
250
|
+
});
|
|
251
|
+
if (error) return Promise.reject(error);
|
|
252
|
+
if (closed) return Promise.resolve({
|
|
253
|
+
value: void 0,
|
|
254
|
+
done: true
|
|
255
|
+
});
|
|
256
|
+
return new Promise((resolve, reject) => {
|
|
257
|
+
waiters.push({
|
|
258
|
+
resolve,
|
|
259
|
+
reject
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
};
|
|
263
|
+
return {
|
|
264
|
+
push(value) {
|
|
265
|
+
const waiter = waiters.shift();
|
|
266
|
+
if (waiter) {
|
|
267
|
+
waiter.resolve({
|
|
268
|
+
value,
|
|
269
|
+
done: false
|
|
270
|
+
});
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
values.push(value);
|
|
274
|
+
},
|
|
275
|
+
close() {
|
|
276
|
+
closed = true;
|
|
277
|
+
for (const waiter of waiters.splice(0)) waiter.resolve({
|
|
278
|
+
value: void 0,
|
|
279
|
+
done: true
|
|
280
|
+
});
|
|
281
|
+
},
|
|
282
|
+
throw(queueError) {
|
|
283
|
+
error = queueError;
|
|
284
|
+
for (const waiter of waiters.splice(0)) waiter.reject(queueError);
|
|
285
|
+
},
|
|
286
|
+
[Symbol.asyncIterator]() {
|
|
287
|
+
return { next };
|
|
288
|
+
}
|
|
289
|
+
};
|
|
320
290
|
}
|
|
321
291
|
function selectedPermissionOutcome(option) {
|
|
322
|
-
|
|
292
|
+
return {
|
|
293
|
+
outcome: "selected",
|
|
294
|
+
optionId: option.optionId
|
|
295
|
+
};
|
|
323
296
|
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}),
|
|
339
|
-
doStream: async () => ({
|
|
340
|
-
stream: new ReadableStream({
|
|
341
|
-
start: async (controller) => {
|
|
342
|
-
controller.close();
|
|
343
|
-
}
|
|
344
|
-
})
|
|
345
|
-
})
|
|
297
|
+
//#endregion
|
|
298
|
+
//#region src/agent.ts
|
|
299
|
+
const CHUNK_FROM_AGENT = "AGENT";
|
|
300
|
+
const model = {
|
|
301
|
+
modelId: "acp-agent",
|
|
302
|
+
provider: "@mastra/acp",
|
|
303
|
+
specificationVersion: "v3",
|
|
304
|
+
supportedUrls: {},
|
|
305
|
+
doGenerate: async () => ({ stream: new ReadableStream({ start: async (controller) => {
|
|
306
|
+
controller.close();
|
|
307
|
+
} }) }),
|
|
308
|
+
doStream: async () => ({ stream: new ReadableStream({ start: async (controller) => {
|
|
309
|
+
controller.close();
|
|
310
|
+
} }) })
|
|
346
311
|
};
|
|
347
312
|
var AcpAgent = class {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
313
|
+
id;
|
|
314
|
+
name;
|
|
315
|
+
connection;
|
|
316
|
+
description;
|
|
317
|
+
constructor(options) {
|
|
318
|
+
this.id = options.id;
|
|
319
|
+
this.name = options.name ?? options.id;
|
|
320
|
+
this.description = options.description;
|
|
321
|
+
this.connection = new ACPConnection(options);
|
|
322
|
+
}
|
|
323
|
+
__registerMastra(_mastra) {}
|
|
324
|
+
getDescription() {
|
|
325
|
+
return this.description;
|
|
326
|
+
}
|
|
327
|
+
getModel() {
|
|
328
|
+
return model;
|
|
329
|
+
}
|
|
330
|
+
hasOwnMemory() {
|
|
331
|
+
return false;
|
|
332
|
+
}
|
|
333
|
+
__setMemory(_memory) {}
|
|
334
|
+
getMemory() {}
|
|
335
|
+
getInstructions() {
|
|
336
|
+
return "";
|
|
337
|
+
}
|
|
338
|
+
async getAvailableModels() {
|
|
339
|
+
return this.connection.getAvailableModels();
|
|
340
|
+
}
|
|
341
|
+
async setModel(modelId) {
|
|
342
|
+
return this.connection.setModel(modelId);
|
|
343
|
+
}
|
|
344
|
+
async generate(messages, options) {
|
|
345
|
+
const prompt = this.getPrompt(messages, options?.instructions);
|
|
346
|
+
const text = await this.connection.prompt(prompt, options?.abortSignal);
|
|
347
|
+
return {
|
|
348
|
+
text,
|
|
349
|
+
response: { dbMessages: this.createMessageList(messages, text).get.response.db() },
|
|
350
|
+
toolResults: [],
|
|
351
|
+
finishReason: "stop",
|
|
352
|
+
runId: options?.runId ?? randomUUID()
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
async resumeGenerate() {
|
|
356
|
+
throw new Error("AcpAgent does not support resuming suspended generate calls");
|
|
357
|
+
}
|
|
358
|
+
async resumeStream() {
|
|
359
|
+
throw new Error("AcpAgent does not support resuming suspended stream calls");
|
|
360
|
+
}
|
|
361
|
+
async stream(messages, options) {
|
|
362
|
+
const runId = options?.runId ?? randomUUID();
|
|
363
|
+
const prompt = this.getPrompt(messages, options?.instructions);
|
|
364
|
+
const signal = options?.abortSignal;
|
|
365
|
+
const messageList = new MessageList();
|
|
366
|
+
messageList.add(messages, "input");
|
|
367
|
+
let resolveText;
|
|
368
|
+
let rejectText;
|
|
369
|
+
const textPromise = new Promise((resolve, reject) => {
|
|
370
|
+
resolveText = resolve;
|
|
371
|
+
rejectText = reject;
|
|
372
|
+
});
|
|
373
|
+
return {
|
|
374
|
+
fullStream: new ReadableStream({ start: async (controller) => {
|
|
375
|
+
const textId = randomUUID();
|
|
376
|
+
const chunks = [];
|
|
377
|
+
const toolNames = /* @__PURE__ */ new Map();
|
|
378
|
+
const toolResults = [];
|
|
379
|
+
try {
|
|
380
|
+
controller.enqueue({
|
|
381
|
+
type: "text-start",
|
|
382
|
+
runId,
|
|
383
|
+
from: CHUNK_FROM_AGENT,
|
|
384
|
+
payload: { id: textId }
|
|
385
|
+
});
|
|
386
|
+
for await (const event of this.connection.promptStream(prompt, signal)) if (event.type === "text") {
|
|
387
|
+
chunks.push(event.text);
|
|
388
|
+
controller.enqueue({
|
|
389
|
+
type: "text-delta",
|
|
390
|
+
runId,
|
|
391
|
+
from: CHUNK_FROM_AGENT,
|
|
392
|
+
payload: {
|
|
393
|
+
id: textId,
|
|
394
|
+
text: event.text
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
} else if (event.type === "session-update") for (const chunk of getMastraChunksFromACPUpdate(event.update, runId, toolNames)) {
|
|
398
|
+
if (chunk.type === "tool-result") toolResults.push({ payload: chunk.payload });
|
|
399
|
+
controller.enqueue(chunk);
|
|
400
|
+
}
|
|
401
|
+
const text = chunks.join("");
|
|
402
|
+
messageList.add([{
|
|
403
|
+
role: "assistant",
|
|
404
|
+
content: text
|
|
405
|
+
}], "response");
|
|
406
|
+
controller.enqueue({
|
|
407
|
+
type: "text-end",
|
|
408
|
+
runId,
|
|
409
|
+
from: CHUNK_FROM_AGENT,
|
|
410
|
+
payload: { id: textId }
|
|
411
|
+
});
|
|
412
|
+
controller.enqueue(createFinishChunk("step-finish", runId));
|
|
413
|
+
controller.enqueue(createFinishChunk("finish", runId));
|
|
414
|
+
await options?.onFinish?.(createOnFinishResult({
|
|
415
|
+
text,
|
|
416
|
+
runId,
|
|
417
|
+
messageList,
|
|
418
|
+
toolResults
|
|
419
|
+
}));
|
|
420
|
+
resolveText(text);
|
|
421
|
+
controller.close();
|
|
422
|
+
} catch (error) {
|
|
423
|
+
const text = chunks.join("");
|
|
424
|
+
await options?.onFinish?.(createOnFinishResult({
|
|
425
|
+
text,
|
|
426
|
+
runId,
|
|
427
|
+
messageList,
|
|
428
|
+
toolResults,
|
|
429
|
+
error
|
|
430
|
+
}));
|
|
431
|
+
rejectText(error);
|
|
432
|
+
controller.error(error);
|
|
433
|
+
}
|
|
434
|
+
} }),
|
|
435
|
+
text: textPromise,
|
|
436
|
+
messageList,
|
|
437
|
+
toolResults: [],
|
|
438
|
+
runId
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
getPrompt(messages, instructions) {
|
|
442
|
+
const prompt = extractText(messages);
|
|
443
|
+
const instructionText = instructions ? extractInstructions(instructions) : "";
|
|
444
|
+
if (!instructionText) return prompt;
|
|
445
|
+
return `${instructionText}\n\n${prompt}`;
|
|
446
|
+
}
|
|
447
|
+
createMessageList(messages, text) {
|
|
448
|
+
const messageList = new MessageList();
|
|
449
|
+
messageList.add(messages, "input");
|
|
450
|
+
messageList.add([{
|
|
451
|
+
role: "assistant",
|
|
452
|
+
content: text
|
|
453
|
+
}], "response");
|
|
454
|
+
return messageList;
|
|
455
|
+
}
|
|
484
456
|
};
|
|
485
457
|
function extractText(messages) {
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
}
|
|
492
|
-
const messageList = new MessageList();
|
|
493
|
-
messageList.add(messages, "input");
|
|
494
|
-
return messageList.get.all.core().map((message) => coreContentToString(message.content)).filter(Boolean).join("\n");
|
|
458
|
+
if (typeof messages === "string") return messages;
|
|
459
|
+
if (Array.isArray(messages) && messages.every((message) => typeof message === "string")) return messages.join("\n");
|
|
460
|
+
const messageList = new MessageList();
|
|
461
|
+
messageList.add(messages, "input");
|
|
462
|
+
return messageList.get.all.core().map((message) => coreContentToString(message.content)).filter(Boolean).join("\n");
|
|
495
463
|
}
|
|
496
464
|
function extractInstructions(instructions) {
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
if (Array.isArray(instructions)) {
|
|
501
|
-
return instructions.map((instruction) => extractInstructions(instruction)).join("\n");
|
|
502
|
-
}
|
|
503
|
-
return coreContentToString(instructions.content);
|
|
465
|
+
if (typeof instructions === "string") return instructions;
|
|
466
|
+
if (Array.isArray(instructions)) return instructions.map((instruction) => extractInstructions(instruction)).join("\n");
|
|
467
|
+
return coreContentToString(instructions.content);
|
|
504
468
|
}
|
|
505
469
|
function getMastraChunksFromACPUpdate(update, runId, toolNames) {
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
}
|
|
551
|
-
];
|
|
552
|
-
}
|
|
553
|
-
default:
|
|
554
|
-
return [];
|
|
555
|
-
}
|
|
470
|
+
switch (update.sessionUpdate) {
|
|
471
|
+
case "tool_call": {
|
|
472
|
+
const toolName = getToolName(update, toolNames);
|
|
473
|
+
toolNames.set(update.toolCallId, toolName);
|
|
474
|
+
return [{
|
|
475
|
+
type: "tool-call",
|
|
476
|
+
runId,
|
|
477
|
+
from: CHUNK_FROM_AGENT,
|
|
478
|
+
payload: {
|
|
479
|
+
toolCallId: update.toolCallId,
|
|
480
|
+
toolName,
|
|
481
|
+
args: toRecord(update.rawInput)
|
|
482
|
+
}
|
|
483
|
+
}];
|
|
484
|
+
}
|
|
485
|
+
case "tool_call_update": {
|
|
486
|
+
const toolName = getToolName(update, toolNames);
|
|
487
|
+
if (update.status === "completed" || update.status === "failed") return [{
|
|
488
|
+
type: "tool-result",
|
|
489
|
+
runId,
|
|
490
|
+
from: CHUNK_FROM_AGENT,
|
|
491
|
+
payload: {
|
|
492
|
+
toolCallId: update.toolCallId,
|
|
493
|
+
toolName,
|
|
494
|
+
result: update.rawOutput ?? update.content ?? {
|
|
495
|
+
status: update.status,
|
|
496
|
+
title: update.title
|
|
497
|
+
},
|
|
498
|
+
isError: update.status === "failed"
|
|
499
|
+
}
|
|
500
|
+
}];
|
|
501
|
+
return [{
|
|
502
|
+
type: "tool-call-delta",
|
|
503
|
+
runId,
|
|
504
|
+
from: CHUNK_FROM_AGENT,
|
|
505
|
+
payload: {
|
|
506
|
+
toolCallId: update.toolCallId,
|
|
507
|
+
toolName,
|
|
508
|
+
argsTextDelta: update.title ?? update.status ?? ""
|
|
509
|
+
}
|
|
510
|
+
}];
|
|
511
|
+
}
|
|
512
|
+
default: return [];
|
|
513
|
+
}
|
|
556
514
|
}
|
|
557
515
|
function getToolName(update, toolNames) {
|
|
558
|
-
|
|
516
|
+
return update.title ?? toolNames.get(update.toolCallId) ?? update.kind ?? "acp_tool";
|
|
559
517
|
}
|
|
560
518
|
function toRecord(value) {
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
if (value === void 0) {
|
|
565
|
-
return {};
|
|
566
|
-
}
|
|
567
|
-
return { input: value };
|
|
519
|
+
if (value && typeof value === "object" && !Array.isArray(value)) return value;
|
|
520
|
+
if (value === void 0) return {};
|
|
521
|
+
return { input: value };
|
|
568
522
|
}
|
|
569
|
-
function createOnFinishResult({
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
toolResults,
|
|
588
|
-
runId,
|
|
589
|
-
...error === void 0 ? {} : { error }
|
|
590
|
-
};
|
|
523
|
+
function createOnFinishResult({ text, runId, messageList, toolResults, error }) {
|
|
524
|
+
const usage = {
|
|
525
|
+
inputTokens: 0,
|
|
526
|
+
outputTokens: 0,
|
|
527
|
+
totalTokens: 0
|
|
528
|
+
};
|
|
529
|
+
return {
|
|
530
|
+
text,
|
|
531
|
+
finishReason: "stop",
|
|
532
|
+
usage,
|
|
533
|
+
totalUsage: usage,
|
|
534
|
+
warnings: [],
|
|
535
|
+
response: { messages: messageList.get.response.aiV5.model() },
|
|
536
|
+
steps: [],
|
|
537
|
+
toolResults,
|
|
538
|
+
runId,
|
|
539
|
+
...error === void 0 ? {} : { error }
|
|
540
|
+
};
|
|
591
541
|
}
|
|
592
542
|
function createFinishChunk(type, runId) {
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
543
|
+
return {
|
|
544
|
+
type,
|
|
545
|
+
runId,
|
|
546
|
+
from: CHUNK_FROM_AGENT,
|
|
547
|
+
payload: {
|
|
548
|
+
id: randomUUID(),
|
|
549
|
+
output: {
|
|
550
|
+
steps: [],
|
|
551
|
+
usage: {
|
|
552
|
+
inputTokens: 0,
|
|
553
|
+
outputTokens: 0,
|
|
554
|
+
totalTokens: 0
|
|
555
|
+
}
|
|
556
|
+
},
|
|
557
|
+
stepResult: {
|
|
558
|
+
reason: "stop",
|
|
559
|
+
warnings: [],
|
|
560
|
+
isContinued: false
|
|
561
|
+
},
|
|
562
|
+
metadata: {},
|
|
563
|
+
messages: {
|
|
564
|
+
nonUser: [],
|
|
565
|
+
all: []
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
};
|
|
612
569
|
}
|
|
613
|
-
|
|
614
|
-
|
|
570
|
+
//#endregion
|
|
571
|
+
//#region src/session.ts
|
|
615
572
|
var ACPToolSession = class {
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
});
|
|
633
|
-
}
|
|
573
|
+
options;
|
|
574
|
+
connection;
|
|
575
|
+
constructor(options) {
|
|
576
|
+
this.options = options;
|
|
577
|
+
}
|
|
578
|
+
getConnection(workspace) {
|
|
579
|
+
if (this.options.persistSession === false) return this.createConnection(workspace);
|
|
580
|
+
this.connection ??= this.createConnection(workspace);
|
|
581
|
+
return this.connection;
|
|
582
|
+
}
|
|
583
|
+
createConnection(workspace) {
|
|
584
|
+
return new ACPConnection({
|
|
585
|
+
...this.options,
|
|
586
|
+
workspace: workspace ?? this.options.workspace
|
|
587
|
+
});
|
|
588
|
+
}
|
|
634
589
|
};
|
|
635
|
-
|
|
636
|
-
|
|
590
|
+
//#endregion
|
|
591
|
+
//#region src/tool.ts
|
|
637
592
|
function createACPTool(options) {
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
"description": "The outcome of the permission request",
|
|
722
|
-
"type": "string",
|
|
723
|
-
"const": "selected"
|
|
724
|
-
}
|
|
725
|
-
}
|
|
726
|
-
},
|
|
727
|
-
{
|
|
728
|
-
"type": "object",
|
|
729
|
-
"properties": {
|
|
730
|
-
"outcome": {
|
|
731
|
-
"description": "The outcome of the permission request",
|
|
732
|
-
"type": "string",
|
|
733
|
-
"const": "cancelled"
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
}
|
|
737
|
-
]
|
|
738
|
-
},
|
|
739
|
-
execute: async ({ task }, context) => {
|
|
740
|
-
const workspace = await context?.mastra?.getWorkspace();
|
|
741
|
-
const connection = session.getConnection(workspace);
|
|
742
|
-
const output = await connection.prompt(task, context?.abortSignal);
|
|
743
|
-
return { output };
|
|
744
|
-
}
|
|
745
|
-
});
|
|
593
|
+
const session = new ACPToolSession(options);
|
|
594
|
+
return createTool({
|
|
595
|
+
id: options.id,
|
|
596
|
+
description: options.description,
|
|
597
|
+
inputSchema: {
|
|
598
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
599
|
+
"type": "object",
|
|
600
|
+
"properties": { "task": {
|
|
601
|
+
"type": "string",
|
|
602
|
+
"description": "The task to send to the ACP agent"
|
|
603
|
+
} },
|
|
604
|
+
"required": ["task"]
|
|
605
|
+
},
|
|
606
|
+
outputSchema: {
|
|
607
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
608
|
+
"type": "object",
|
|
609
|
+
"properties": { "output": {
|
|
610
|
+
"type": "string",
|
|
611
|
+
"description": "The output of the ACP agent"
|
|
612
|
+
} },
|
|
613
|
+
"required": ["output"]
|
|
614
|
+
},
|
|
615
|
+
suspendSchema: {
|
|
616
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
617
|
+
"type": "object",
|
|
618
|
+
"properties": { "permissionRequest": {
|
|
619
|
+
"type": "object",
|
|
620
|
+
"properties": {
|
|
621
|
+
"title": {
|
|
622
|
+
"type": "string",
|
|
623
|
+
"description": "The title of the permission request"
|
|
624
|
+
},
|
|
625
|
+
"options": {
|
|
626
|
+
"type": "array",
|
|
627
|
+
"items": {
|
|
628
|
+
"type": "object",
|
|
629
|
+
"properties": {
|
|
630
|
+
"optionId": {
|
|
631
|
+
"type": "string",
|
|
632
|
+
"description": "The option id to select"
|
|
633
|
+
},
|
|
634
|
+
"name": {
|
|
635
|
+
"type": "string",
|
|
636
|
+
"description": "The title of the permission request"
|
|
637
|
+
}
|
|
638
|
+
},
|
|
639
|
+
"required": ["optionId", "name"]
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
},
|
|
643
|
+
"required": ["title", "options"]
|
|
644
|
+
} },
|
|
645
|
+
"required": ["permissionRequest"]
|
|
646
|
+
},
|
|
647
|
+
resumeSchema: {
|
|
648
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
649
|
+
"anyOf": [{
|
|
650
|
+
"type": "object",
|
|
651
|
+
"properties": {
|
|
652
|
+
"optionId": {
|
|
653
|
+
"description": "The option id to select",
|
|
654
|
+
"type": "string"
|
|
655
|
+
},
|
|
656
|
+
"outcome": {
|
|
657
|
+
"description": "The outcome of the permission request",
|
|
658
|
+
"type": "string",
|
|
659
|
+
"const": "selected"
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}, {
|
|
663
|
+
"type": "object",
|
|
664
|
+
"properties": { "outcome": {
|
|
665
|
+
"description": "The outcome of the permission request",
|
|
666
|
+
"type": "string",
|
|
667
|
+
"const": "cancelled"
|
|
668
|
+
} }
|
|
669
|
+
}]
|
|
670
|
+
},
|
|
671
|
+
execute: async ({ task }, context) => {
|
|
672
|
+
const workspace = await context?.mastra?.getWorkspace();
|
|
673
|
+
return { output: await session.getConnection(workspace).prompt(task, context?.abortSignal) };
|
|
674
|
+
}
|
|
675
|
+
});
|
|
746
676
|
}
|
|
747
|
-
|
|
677
|
+
//#endregion
|
|
748
678
|
export { AcpAgent, createACPTool };
|
|
749
|
-
|
|
679
|
+
|
|
750
680
|
//# sourceMappingURL=index.js.map
|