@andreprado/agentkit 0.1.0-alpha.17 → 0.1.0-alpha.18
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/docs/guides/add-channel.md +2 -2
- package/docs/guides/add-managed-composio.md +40 -16
- package/docs/guides/channel-security.md +36 -39
- package/docs/guides/debug-channel.md +141 -0
- package/docs/guides/prepare-deploy.md +5 -10
- package/docs/llms-full.txt +8 -6
- package/docs/llms.txt +5 -3
- package/package.json +1 -3
- package/src/cli/cloud-client.ts +12 -0
- package/src/cli/deploy-chat-ui.ts +146 -3
- package/src/cli/deploy-readiness.ts +54 -1
- package/src/cli/help.ts +6 -6
- package/src/cli/index.ts +69 -4
- package/src/index.ts +4 -0
- package/src/runtime/config.ts +4 -0
- package/src/runtime/core/manifest.ts +2 -0
- package/src/runtime/inspect.ts +1 -0
- package/src/runtime/integrations/composio.ts +168 -2
- package/src/runtime/targets/cloudflare/build.ts +235 -5
- package/src/templates/skills/agentkit-integrations/SKILL.md +11 -2
- package/docs/guides/agentkit-skills-architecture.md +0 -472
- package/docs/guides/channels-implementation-map.md +0 -243
- package/docs/guides/channels-production-handoff.md +0 -118
- package/docs/portable-deploy-release-checklist.md +0 -41
|
@@ -70,6 +70,27 @@ export async function startDeployChatUiServer(
|
|
|
70
70
|
return;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
if (
|
|
74
|
+
request.method === "GET" &&
|
|
75
|
+
(requestUrl.pathname === "/v1/conversations" ||
|
|
76
|
+
/^\/v1\/conversations\/[^/]+(?:\/trace)?$/.test(requestUrl.pathname))
|
|
77
|
+
) {
|
|
78
|
+
const token = await readDeployAccessTokenForUi(tokenPath);
|
|
79
|
+
const upstream = await fetch(new URL(requestUrl.pathname, deployUrl).href, {
|
|
80
|
+
method: "GET",
|
|
81
|
+
headers: {
|
|
82
|
+
Authorization: `Bearer ${token}`,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
const text = await upstream.text();
|
|
86
|
+
|
|
87
|
+
response.writeHead(upstream.status, {
|
|
88
|
+
"content-type": upstream.headers.get("content-type") ?? "application/json",
|
|
89
|
+
});
|
|
90
|
+
response.end(text);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
73
94
|
sendJson(response, 404, { error: { code: "not_found", message: "Route not found." } });
|
|
74
95
|
} catch (error) {
|
|
75
96
|
sendJson(response, 500, {
|
|
@@ -196,6 +217,8 @@ function renderDeployChatUi(input: { deployUrl: string }): string {
|
|
|
196
217
|
header {
|
|
197
218
|
border-bottom: 1px solid var(--line);
|
|
198
219
|
padding: 18px 22px;
|
|
220
|
+
display: grid;
|
|
221
|
+
gap: 10px;
|
|
199
222
|
}
|
|
200
223
|
|
|
201
224
|
h1 {
|
|
@@ -204,12 +227,27 @@ function renderDeployChatUi(input: { deployUrl: string }): string {
|
|
|
204
227
|
line-height: 1.2;
|
|
205
228
|
}
|
|
206
229
|
|
|
230
|
+
.topline {
|
|
231
|
+
display: flex;
|
|
232
|
+
align-items: start;
|
|
233
|
+
justify-content: space-between;
|
|
234
|
+
gap: 12px;
|
|
235
|
+
}
|
|
236
|
+
|
|
207
237
|
code {
|
|
208
238
|
color: var(--muted);
|
|
209
239
|
font-size: 12px;
|
|
210
240
|
overflow-wrap: anywhere;
|
|
211
241
|
}
|
|
212
242
|
|
|
243
|
+
.meta {
|
|
244
|
+
display: flex;
|
|
245
|
+
flex-wrap: wrap;
|
|
246
|
+
gap: 8px 14px;
|
|
247
|
+
color: var(--muted);
|
|
248
|
+
font-size: 12px;
|
|
249
|
+
}
|
|
250
|
+
|
|
213
251
|
#messages {
|
|
214
252
|
padding: 22px;
|
|
215
253
|
overflow: auto;
|
|
@@ -255,6 +293,39 @@ function renderDeployChatUi(input: { deployUrl: string }): string {
|
|
|
255
293
|
background: #fff6f6;
|
|
256
294
|
}
|
|
257
295
|
|
|
296
|
+
#trace {
|
|
297
|
+
border-top: 1px solid var(--line);
|
|
298
|
+
padding: 12px 22px;
|
|
299
|
+
display: grid;
|
|
300
|
+
gap: 8px;
|
|
301
|
+
background: #fbfbfa;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.tool-call {
|
|
305
|
+
border: 1px solid var(--line);
|
|
306
|
+
border-radius: 8px;
|
|
307
|
+
padding: 10px 12px;
|
|
308
|
+
display: grid;
|
|
309
|
+
gap: 6px;
|
|
310
|
+
font-size: 12px;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.tool-head {
|
|
314
|
+
display: flex;
|
|
315
|
+
flex-wrap: wrap;
|
|
316
|
+
gap: 8px;
|
|
317
|
+
align-items: center;
|
|
318
|
+
color: var(--muted);
|
|
319
|
+
font-weight: 700;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.tool-call pre {
|
|
323
|
+
margin: 0;
|
|
324
|
+
max-height: 180px;
|
|
325
|
+
overflow: auto;
|
|
326
|
+
white-space: pre-wrap;
|
|
327
|
+
}
|
|
328
|
+
|
|
258
329
|
form {
|
|
259
330
|
border-top: 1px solid var(--line);
|
|
260
331
|
padding: 14px;
|
|
@@ -286,6 +357,13 @@ function renderDeployChatUi(input: { deployUrl: string }): string {
|
|
|
286
357
|
cursor: pointer;
|
|
287
358
|
}
|
|
288
359
|
|
|
360
|
+
button.secondary {
|
|
361
|
+
min-height: 34px;
|
|
362
|
+
color: var(--ink);
|
|
363
|
+
background: #eef1ee;
|
|
364
|
+
border: 1px solid var(--line);
|
|
365
|
+
}
|
|
366
|
+
|
|
289
367
|
button:disabled {
|
|
290
368
|
cursor: wait;
|
|
291
369
|
opacity: 0.65;
|
|
@@ -305,10 +383,20 @@ function renderDeployChatUi(input: { deployUrl: string }): string {
|
|
|
305
383
|
<body>
|
|
306
384
|
<main>
|
|
307
385
|
<header>
|
|
308
|
-
<
|
|
309
|
-
|
|
386
|
+
<div class="topline">
|
|
387
|
+
<div>
|
|
388
|
+
<h1>AgentKit Hosted Chat</h1>
|
|
389
|
+
<code>${deployUrl}</code>
|
|
390
|
+
</div>
|
|
391
|
+
<button class="secondary" id="new-conversation" type="button">New conversation</button>
|
|
392
|
+
</div>
|
|
393
|
+
<div class="meta">
|
|
394
|
+
<span>Conversation: <code id="conversation-id">none</code></span>
|
|
395
|
+
<span>Tool calls: <code id="tool-count">0</code></span>
|
|
396
|
+
</div>
|
|
310
397
|
</header>
|
|
311
398
|
<section id="messages" aria-live="polite"></section>
|
|
399
|
+
<section id="trace" aria-live="polite"></section>
|
|
312
400
|
<form id="form">
|
|
313
401
|
<textarea id="message" name="message" placeholder="Type a message" required autofocus></textarea>
|
|
314
402
|
<button id="send" type="submit">Send</button>
|
|
@@ -319,6 +407,10 @@ function renderDeployChatUi(input: { deployUrl: string }): string {
|
|
|
319
407
|
const textarea = document.querySelector("#message");
|
|
320
408
|
const send = document.querySelector("#send");
|
|
321
409
|
const messages = document.querySelector("#messages");
|
|
410
|
+
const trace = document.querySelector("#trace");
|
|
411
|
+
const conversationLabel = document.querySelector("#conversation-id");
|
|
412
|
+
const toolCount = document.querySelector("#tool-count");
|
|
413
|
+
const newConversation = document.querySelector("#new-conversation");
|
|
322
414
|
let conversationId = null;
|
|
323
415
|
|
|
324
416
|
function addMessage(role, content, className = "") {
|
|
@@ -335,6 +427,55 @@ function renderDeployChatUi(input: { deployUrl: string }): string {
|
|
|
335
427
|
messages.scrollTop = messages.scrollHeight;
|
|
336
428
|
}
|
|
337
429
|
|
|
430
|
+
function setConversationId(value) {
|
|
431
|
+
conversationId = value || null;
|
|
432
|
+
conversationLabel.textContent = conversationId || "none";
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
function renderTrace(payload) {
|
|
436
|
+
const calls = [];
|
|
437
|
+
for (const run of payload.runs || []) {
|
|
438
|
+
for (const call of run.toolCalls || []) {
|
|
439
|
+
calls.push(call);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
toolCount.textContent = String(calls.length);
|
|
444
|
+
trace.innerHTML = "";
|
|
445
|
+
|
|
446
|
+
for (const call of calls.slice(-8)) {
|
|
447
|
+
const item = document.createElement("article");
|
|
448
|
+
item.className = "tool-call";
|
|
449
|
+
const head = document.createElement("div");
|
|
450
|
+
head.className = "tool-head";
|
|
451
|
+
head.textContent = [call.name, call.status, call.errorMessage].filter(Boolean).join(" · ");
|
|
452
|
+
const input = document.createElement("pre");
|
|
453
|
+
input.textContent = JSON.stringify(call.input || {}, null, 2);
|
|
454
|
+
item.append(head, input);
|
|
455
|
+
trace.append(item);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
async function refreshTrace() {
|
|
460
|
+
if (!conversationId) {
|
|
461
|
+
toolCount.textContent = "0";
|
|
462
|
+
trace.innerHTML = "";
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
const response = await fetch("/v1/conversations/" + encodeURIComponent(conversationId) + "/trace");
|
|
467
|
+
const payload = await response.json();
|
|
468
|
+
if (response.ok) renderTrace(payload);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
newConversation.addEventListener("click", () => {
|
|
472
|
+
setConversationId(null);
|
|
473
|
+
messages.innerHTML = "";
|
|
474
|
+
trace.innerHTML = "";
|
|
475
|
+
toolCount.textContent = "0";
|
|
476
|
+
textarea.focus();
|
|
477
|
+
});
|
|
478
|
+
|
|
338
479
|
textarea.addEventListener("keydown", (event) => {
|
|
339
480
|
if (event.key !== "Enter" || event.shiftKey || event.isComposing) return;
|
|
340
481
|
event.preventDefault();
|
|
@@ -363,10 +504,12 @@ function renderDeployChatUi(input: { deployUrl: string }): string {
|
|
|
363
504
|
throw new Error(payload.error?.message || "Request failed");
|
|
364
505
|
}
|
|
365
506
|
|
|
366
|
-
|
|
507
|
+
setConversationId(payload.conversationId || conversationId);
|
|
367
508
|
addMessage("assistant", payload.message?.content || "");
|
|
509
|
+
await refreshTrace();
|
|
368
510
|
} catch (error) {
|
|
369
511
|
addMessage("error", error instanceof Error ? error.message : String(error), "error");
|
|
512
|
+
await refreshTrace().catch(() => {});
|
|
370
513
|
} finally {
|
|
371
514
|
send.disabled = false;
|
|
372
515
|
textarea.focus();
|
|
@@ -2,13 +2,14 @@ import { findAgentCapsuleRoot, loadAgentCapsule } from "../runtime/config";
|
|
|
2
2
|
import { loadDeployReadinessContext, type DeployReadinessContext } from "../runtime/deploy-readiness";
|
|
3
3
|
import { loadCapsuleEnv } from "../runtime/env";
|
|
4
4
|
import { isAgentKitError } from "../runtime/errors";
|
|
5
|
-
import { MANAGED_COMPOSIO_ENTITLEMENT } from "../runtime/integrations/composio";
|
|
5
|
+
import { MANAGED_COMPOSIO_API_KEY_SECRET, MANAGED_COMPOSIO_ENTITLEMENT } from "../runtime/integrations/composio";
|
|
6
6
|
import {
|
|
7
7
|
cloudApiRequest,
|
|
8
8
|
formatCloudAuthSource,
|
|
9
9
|
readCloudAuthForApiUrl,
|
|
10
10
|
type CloudCapabilitiesResponse,
|
|
11
11
|
type CloudLimitsResponse,
|
|
12
|
+
type CloudManagedComposioResponse,
|
|
12
13
|
type CloudMeResponse,
|
|
13
14
|
type CloudProjectResolveResponse,
|
|
14
15
|
type CloudSecretsResponse,
|
|
@@ -203,6 +204,58 @@ export async function checkDeployReadiness(options: {
|
|
|
203
204
|
message: `Could not verify online deploy capacity. ${formatReadinessError(error)}`,
|
|
204
205
|
});
|
|
205
206
|
}
|
|
207
|
+
|
|
208
|
+
if (context.integrations.managedComposio.enabled) {
|
|
209
|
+
try {
|
|
210
|
+
const payload = (await cloudApiRequest(
|
|
211
|
+
options.apiUrl,
|
|
212
|
+
`/v1/me/managed-composio?toolkits=${encodeURIComponent(context.integrations.managedComposio.toolkits.join(","))}`,
|
|
213
|
+
{
|
|
214
|
+
method: "GET",
|
|
215
|
+
},
|
|
216
|
+
)) as CloudManagedComposioResponse;
|
|
217
|
+
const managed = payload.managed_composio;
|
|
218
|
+
const missingToolkits = (managed?.toolkits ?? []).filter((toolkit) => toolkit.auth_config !== "set");
|
|
219
|
+
|
|
220
|
+
if (managed?.api_key !== "set") {
|
|
221
|
+
checks.push({
|
|
222
|
+
status: "fail",
|
|
223
|
+
title: "Managed Composio API key",
|
|
224
|
+
message: `AgentKit Cloud is missing AGENTKIT_SECRET_${MANAGED_COMPOSIO_API_KEY_SECRET}.`,
|
|
225
|
+
action: "ask the AgentKit Cloud operator to configure managed Composio",
|
|
226
|
+
});
|
|
227
|
+
} else {
|
|
228
|
+
checks.push({
|
|
229
|
+
status: "pass",
|
|
230
|
+
title: "Managed Composio API key",
|
|
231
|
+
message: "AgentKit Cloud has the managed COMPOSIO_API_KEY.",
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (missingToolkits.length > 0) {
|
|
236
|
+
checks.push({
|
|
237
|
+
status: "fail",
|
|
238
|
+
title: "Managed Composio auth configs",
|
|
239
|
+
message: `Missing ${missingToolkits
|
|
240
|
+
.map((toolkit) => `${toolkit.auth_config_env ?? "auth config"} for ${toolkit.toolkit ?? "unknown"}`)
|
|
241
|
+
.join(", ")}.`,
|
|
242
|
+
action: "ask the AgentKit Cloud operator to configure the missing toolkit auth config",
|
|
243
|
+
});
|
|
244
|
+
} else {
|
|
245
|
+
checks.push({
|
|
246
|
+
status: "pass",
|
|
247
|
+
title: "Managed Composio auth configs",
|
|
248
|
+
message: `Auth configs are available for ${context.integrations.managedComposio.toolkits.join(", ")}.`,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
} catch (error) {
|
|
252
|
+
checks.push({
|
|
253
|
+
status: "warn",
|
|
254
|
+
title: "Managed Composio auth configs",
|
|
255
|
+
message: `Could not verify managed Composio auth configs. ${formatReadinessError(error)}`,
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
}
|
|
206
259
|
}
|
|
207
260
|
|
|
208
261
|
if (context.agentKitManagedSecrets.length > 0) {
|
package/src/cli/help.ts
CHANGED
|
@@ -73,9 +73,9 @@ Usage:
|
|
|
73
73
|
agentkit db seed [--file <path>]
|
|
74
74
|
agentkit eval run
|
|
75
75
|
agentkit eval from-conversation <conversation-id> [--out <path>] [--force]
|
|
76
|
-
agentkit conversations list
|
|
77
|
-
agentkit conversations show <conversation-id>
|
|
78
|
-
agentkit conversations trace <conversation-id>
|
|
76
|
+
agentkit conversations list [--deploy]
|
|
77
|
+
agentkit conversations show <conversation-id> [--deploy]
|
|
78
|
+
agentkit conversations trace <conversation-id> [--deploy]
|
|
79
79
|
agentkit channels list
|
|
80
80
|
agentkit channels add <website|telegram|whatsapp> <name> [--provider zapster|meta] [--api <url>]
|
|
81
81
|
agentkit channels connect <website|telegram|whatsapp> <name> [--provider zapster|meta] [--api <url>]
|
|
@@ -91,7 +91,7 @@ Usage:
|
|
|
91
91
|
agentkit channels buffers flush [<name>] <conversation-id> [--api <url>]
|
|
92
92
|
agentkit channels buffers clear [<name>] <conversation-id> [--api <url>]
|
|
93
93
|
agentkit channels buffers retry [<name>] <conversation-id> [--api <url>]
|
|
94
|
-
agentkit integrations status [--api <url>]
|
|
94
|
+
agentkit integrations status [--toolkit <slug>] [--api <url>]
|
|
95
95
|
agentkit integrations connect composio [--toolkit <slug>] [--callback-url <url>] [--api <url>]
|
|
96
96
|
agentkit skills status
|
|
97
97
|
agentkit skills sync
|
|
@@ -182,7 +182,7 @@ export function renderCommandHelp(command: string): string {
|
|
|
182
182
|
sync: "agentkit sync init [--force] | agentkit sync run [--file <path>]",
|
|
183
183
|
eval: "agentkit eval run | agentkit eval from-conversation <conversation-id> [--out <path>] [--force]",
|
|
184
184
|
conversations:
|
|
185
|
-
"agentkit conversations list | agentkit conversations show <conversation-id> | agentkit conversations trace <conversation-id>",
|
|
185
|
+
"agentkit conversations list [--deploy] | agentkit conversations show <conversation-id> [--deploy] | agentkit conversations trace <conversation-id> [--deploy]",
|
|
186
186
|
channels:
|
|
187
187
|
"agentkit channels list | add | connect | setup | status | doctor | test | test-audio | deliveries | buffers",
|
|
188
188
|
skills: "agentkit skills status | agentkit skills sync",
|
|
@@ -192,7 +192,7 @@ export function renderCommandHelp(command: string): string {
|
|
|
192
192
|
secret:
|
|
193
193
|
"agentkit secret set <NAME> --stdin | --from-env [ENV_NAME] | --from-local-env | agentkit secret sync --from-local | list | unset <NAME>",
|
|
194
194
|
access: "agentkit access token create <name> [--out <path>] | list | revoke <token-id>",
|
|
195
|
-
integrations: "agentkit integrations status | agentkit integrations connect composio [--toolkit <slug>]",
|
|
195
|
+
integrations: "agentkit integrations status [--toolkit <slug>] | agentkit integrations connect composio [--toolkit <slug>]",
|
|
196
196
|
env: "agentkit env set <NAME> --stdin | --from-env [ENV_NAME] | list | unset <NAME>",
|
|
197
197
|
docs: "agentkit docs path | llms | full",
|
|
198
198
|
handoff: "agentkit handoff codex [goal] | agentkit handoff claude [goal]",
|
package/src/cli/index.ts
CHANGED
|
@@ -338,8 +338,15 @@ async function main() {
|
|
|
338
338
|
|
|
339
339
|
if (args.command === "conversations") {
|
|
340
340
|
const [subcommand, conversationId] = args.positional;
|
|
341
|
+
const fromDeploy = args.flags.deploy === true;
|
|
341
342
|
|
|
342
343
|
if (subcommand === "list") {
|
|
344
|
+
if (fromDeploy) {
|
|
345
|
+
const payload = await fetchDeployConversationJson(process.cwd(), "/v1/conversations");
|
|
346
|
+
printJson(payload);
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
|
|
343
350
|
const conversations = await listConversationsFromCwd(process.cwd());
|
|
344
351
|
|
|
345
352
|
if (conversations.length === 0) {
|
|
@@ -365,7 +372,16 @@ async function main() {
|
|
|
365
372
|
|
|
366
373
|
if (subcommand === "show") {
|
|
367
374
|
if (!conversationId) {
|
|
368
|
-
throw new Error("Missing conversation id. Usage: agentkit conversations show <conversation-id>");
|
|
375
|
+
throw new Error("Missing conversation id. Usage: agentkit conversations show <conversation-id> [--deploy]");
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (fromDeploy) {
|
|
379
|
+
const payload = await fetchDeployConversationJson(
|
|
380
|
+
process.cwd(),
|
|
381
|
+
`/v1/conversations/${encodeURIComponent(conversationId)}`,
|
|
382
|
+
);
|
|
383
|
+
printJson(payload);
|
|
384
|
+
return;
|
|
369
385
|
}
|
|
370
386
|
|
|
371
387
|
const conversation = await getConversationFromCwd(process.cwd(), conversationId);
|
|
@@ -384,7 +400,16 @@ async function main() {
|
|
|
384
400
|
|
|
385
401
|
if (subcommand === "trace") {
|
|
386
402
|
if (!conversationId) {
|
|
387
|
-
throw new Error("Missing conversation id. Usage: agentkit conversations trace <conversation-id>");
|
|
403
|
+
throw new Error("Missing conversation id. Usage: agentkit conversations trace <conversation-id> [--deploy]");
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
if (fromDeploy) {
|
|
407
|
+
const trace = await fetchDeployConversationJson(
|
|
408
|
+
process.cwd(),
|
|
409
|
+
`/v1/conversations/${encodeURIComponent(conversationId)}/trace`,
|
|
410
|
+
);
|
|
411
|
+
printJson(trace);
|
|
412
|
+
return;
|
|
388
413
|
}
|
|
389
414
|
|
|
390
415
|
const trace = await getConversationTraceFromCwd(process.cwd(), conversationId);
|
|
@@ -392,7 +417,7 @@ async function main() {
|
|
|
392
417
|
return;
|
|
393
418
|
}
|
|
394
419
|
|
|
395
|
-
throw new Error("Usage: agentkit conversations list | agentkit conversations show <conversation-id> | agentkit conversations trace <conversation-id>");
|
|
420
|
+
throw new Error("Usage: agentkit conversations list [--deploy] | agentkit conversations show <conversation-id> [--deploy] | agentkit conversations trace <conversation-id> [--deploy]");
|
|
396
421
|
}
|
|
397
422
|
|
|
398
423
|
if (args.command === "knowledge") {
|
|
@@ -805,9 +830,16 @@ async function main() {
|
|
|
805
830
|
const apiUrl = await resolveCloudApiUrl(args.flags.api);
|
|
806
831
|
|
|
807
832
|
if (subcommand === "status") {
|
|
833
|
+
const toolkit = parseOptionalStringFlag(
|
|
834
|
+
args.flags.toolkit,
|
|
835
|
+
"toolkit",
|
|
836
|
+
"agentkit integrations status --toolkit <slug>",
|
|
837
|
+
);
|
|
808
838
|
const payload = await cloudApiRequest(
|
|
809
839
|
apiUrl,
|
|
810
|
-
`/v1/deploys/${encodeURIComponent(state.deploy_id)}/integrations/composio/status
|
|
840
|
+
`/v1/deploys/${encodeURIComponent(state.deploy_id)}/integrations/composio/status${
|
|
841
|
+
toolkit ? `?toolkit=${encodeURIComponent(toolkit)}` : ""
|
|
842
|
+
}`,
|
|
811
843
|
{ method: "GET" },
|
|
812
844
|
);
|
|
813
845
|
printJson(payload);
|
|
@@ -1180,6 +1212,39 @@ async function runDeploySmoke(input: { deployUrl: string; message: string; token
|
|
|
1180
1212
|
}
|
|
1181
1213
|
}
|
|
1182
1214
|
|
|
1215
|
+
async function fetchDeployConversationJson(cwd: string, path: string): Promise<unknown> {
|
|
1216
|
+
const state = await requireLocalDeployState();
|
|
1217
|
+
const deployUrl = requireDeployUrl(state);
|
|
1218
|
+
const token = await readDeployAccessTokenForSmoke(cwd, state);
|
|
1219
|
+
const headers = new Headers();
|
|
1220
|
+
|
|
1221
|
+
if (token) {
|
|
1222
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
let response: Response;
|
|
1226
|
+
|
|
1227
|
+
try {
|
|
1228
|
+
response = await fetch(new URL(path, deployUrl).href, {
|
|
1229
|
+
method: "GET",
|
|
1230
|
+
headers,
|
|
1231
|
+
});
|
|
1232
|
+
} catch (error) {
|
|
1233
|
+
throw new AgentKitError(
|
|
1234
|
+
"deploy_conversation_request_failed",
|
|
1235
|
+
`Could not read hosted conversation data: ${error instanceof Error ? error.message : String(error)}`,
|
|
1236
|
+
);
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
const payload = await response.json().catch(() => null);
|
|
1240
|
+
|
|
1241
|
+
if (!response.ok) {
|
|
1242
|
+
throw new AgentKitError("deploy_conversation_request_failed", readCloudError(payload, response.status));
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
return payload;
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1183
1248
|
function printJson(value: unknown): void {
|
|
1184
1249
|
console.log(JSON.stringify(value, null, 2));
|
|
1185
1250
|
}
|
package/src/index.ts
CHANGED
|
@@ -155,6 +155,7 @@ export type ComposioManagedIntegrationInput = {
|
|
|
155
155
|
toolkits: string[];
|
|
156
156
|
tools?: Record<string, string[]>;
|
|
157
157
|
tags?: IntegrationTagsConfig;
|
|
158
|
+
confirmExternalWrites?: boolean;
|
|
158
159
|
};
|
|
159
160
|
|
|
160
161
|
export type ComposioManagedIntegration = {
|
|
@@ -165,6 +166,7 @@ export type ComposioManagedIntegration = {
|
|
|
165
166
|
toolkits: string[];
|
|
166
167
|
tools?: Record<string, string[]>;
|
|
167
168
|
tags?: IntegrationTagsConfig;
|
|
169
|
+
confirmExternalWrites?: boolean;
|
|
168
170
|
};
|
|
169
171
|
|
|
170
172
|
export type AgentIntegration = ComposioManagedIntegration;
|
|
@@ -368,6 +370,7 @@ export function composioManaged(input: ComposioManagedIntegrationInput): Composi
|
|
|
368
370
|
const toolkits = normalizeToolkitList(input.toolkits, "composioManaged.toolkits");
|
|
369
371
|
const tools = input.tools ? normalizeComposioToolMap(input.tools, toolkits) : undefined;
|
|
370
372
|
const tags = input.tags ? normalizeIntegrationTags(input.tags) : undefined;
|
|
373
|
+
const confirmExternalWrites = input.confirmExternalWrites;
|
|
371
374
|
|
|
372
375
|
return {
|
|
373
376
|
type: "composio",
|
|
@@ -377,6 +380,7 @@ export function composioManaged(input: ComposioManagedIntegrationInput): Composi
|
|
|
377
380
|
toolkits,
|
|
378
381
|
...(tools ? { tools } : {}),
|
|
379
382
|
...(tags ? { tags } : {}),
|
|
383
|
+
...(confirmExternalWrites === undefined ? {} : { confirmExternalWrites }),
|
|
380
384
|
};
|
|
381
385
|
}
|
|
382
386
|
|
package/src/runtime/config.ts
CHANGED
|
@@ -371,6 +371,10 @@ function validateComposioManagedIntegration(value: AgentIntegration, index: numb
|
|
|
371
371
|
if (value.tags !== undefined) {
|
|
372
372
|
validateIntegrationTags(value.tags, `integrations[${index}].tags`);
|
|
373
373
|
}
|
|
374
|
+
|
|
375
|
+
if (value.confirmExternalWrites !== undefined && typeof value.confirmExternalWrites !== "boolean") {
|
|
376
|
+
throw invalidConfig(`integrations[${index}].confirmExternalWrites must be a boolean when provided.`);
|
|
377
|
+
}
|
|
374
378
|
}
|
|
375
379
|
|
|
376
380
|
function validateIntegrationTags(value: unknown, label: string): void {
|
|
@@ -40,6 +40,7 @@ export type SharedAgentManifest = {
|
|
|
40
40
|
toolkits: string[];
|
|
41
41
|
tools: string[];
|
|
42
42
|
userId: string;
|
|
43
|
+
confirmExternalWrites: boolean;
|
|
43
44
|
}>;
|
|
44
45
|
channels: NonNullable<AgentConfig["channels"]>;
|
|
45
46
|
transcription: {
|
|
@@ -174,6 +175,7 @@ export function buildSharedAgentManifest(
|
|
|
174
175
|
toolkits: integration.toolkits,
|
|
175
176
|
tools: integration.allowedTools,
|
|
176
177
|
userId: integration.userId,
|
|
178
|
+
confirmExternalWrites: integration.confirmExternalWrites !== false,
|
|
177
179
|
})),
|
|
178
180
|
channels: capsule.config.channels ?? [],
|
|
179
181
|
transcription: {
|
package/src/runtime/inspect.ts
CHANGED
|
@@ -203,6 +203,7 @@ export function buildInspectState(
|
|
|
203
203
|
toolkits: integration.toolkits,
|
|
204
204
|
tools: integration.allowedTools,
|
|
205
205
|
userId: integration.userId,
|
|
206
|
+
confirmExternalWrites: integration.confirmExternalWrites !== false,
|
|
206
207
|
})),
|
|
207
208
|
channels: (capsule.config.channels ?? []).map((channel) => ({
|
|
208
209
|
name: channel.name,
|