@andreprado/agentkit 0.1.0-alpha.16 → 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/README.md +8 -0
- package/docs/guides/add-channel.md +4 -2
- package/docs/guides/add-managed-composio.md +161 -0
- package/docs/guides/channel-security.md +36 -39
- package/docs/guides/connect-telegram.md +3 -1
- package/docs/guides/debug-channel.md +141 -0
- package/docs/guides/prepare-deploy.md +7 -10
- package/docs/llms-full.txt +19 -5
- package/docs/llms.txt +11 -2
- package/package.json +1 -3
- package/src/cli/cloud-client.ts +12 -0
- package/src/cli/commands/channels.ts +119 -7
- package/src/cli/commands/transcribe.ts +171 -0
- package/src/cli/deploy-chat-ui.ts +146 -3
- package/src/cli/deploy-readiness.ts +112 -3
- package/src/cli/help.ts +19 -4
- package/src/cli/index.ts +198 -3
- package/src/create-project.ts +4 -32
- package/src/index.ts +149 -0
- package/src/runtime/chat.ts +2 -1
- package/src/runtime/config.ts +133 -0
- package/src/runtime/core/manifest.ts +31 -2
- package/src/runtime/deploy-readiness.ts +31 -1
- package/src/runtime/inspect.ts +109 -4
- package/src/runtime/integrations/composio.ts +423 -0
- package/src/runtime/skills.ts +95 -0
- package/src/runtime/targets/cloudflare/build.ts +395 -10
- package/src/runtime/tool-runner.ts +2 -1
- package/src/templates/skills/agentkit-capsule/SKILL.md +1 -0
- package/src/templates/skills/agentkit-channels/SKILL.md +2 -0
- package/src/templates/skills/agentkit-channels/references/channel-debugging.md +3 -1
- package/src/templates/skills/agentkit-channels/references/telegram.md +3 -1
- package/src/templates/skills/agentkit-deploy/SKILL.md +1 -1
- package/src/templates/skills/agentkit-integrations/SKILL.md +75 -0
- package/src/templates/skills/agentkit-troubleshooting/SKILL.md +3 -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
package/src/index.ts
CHANGED
|
@@ -145,6 +145,32 @@ export type WhatsappChannelConfig = {
|
|
|
145
145
|
|
|
146
146
|
export type AgentChannel = WebsiteChannelConfig | TelegramChannelConfig | WhatsappChannelConfig;
|
|
147
147
|
|
|
148
|
+
export type IntegrationTagsConfig = {
|
|
149
|
+
enable?: string[];
|
|
150
|
+
disable?: string[];
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
export type ComposioManagedIntegrationInput = {
|
|
154
|
+
name?: string;
|
|
155
|
+
toolkits: string[];
|
|
156
|
+
tools?: Record<string, string[]>;
|
|
157
|
+
tags?: IntegrationTagsConfig;
|
|
158
|
+
confirmExternalWrites?: boolean;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
export type ComposioManagedIntegration = {
|
|
162
|
+
type: "composio";
|
|
163
|
+
provider: "composio";
|
|
164
|
+
mode: "managed";
|
|
165
|
+
name: string;
|
|
166
|
+
toolkits: string[];
|
|
167
|
+
tools?: Record<string, string[]>;
|
|
168
|
+
tags?: IntegrationTagsConfig;
|
|
169
|
+
confirmExternalWrites?: boolean;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
export type AgentIntegration = ComposioManagedIntegration;
|
|
173
|
+
|
|
148
174
|
export type AgentDatabaseConfig =
|
|
149
175
|
| {
|
|
150
176
|
driver: "none";
|
|
@@ -316,6 +342,7 @@ export type AgentConfig = {
|
|
|
316
342
|
instructions: string;
|
|
317
343
|
secrets: string[];
|
|
318
344
|
tools?: AgentTool[];
|
|
345
|
+
integrations?: AgentIntegration[];
|
|
319
346
|
channels?: AgentChannel[];
|
|
320
347
|
transcription?: AgentTranscriptionConfig;
|
|
321
348
|
knowledge?: AgentKnowledgeConfig;
|
|
@@ -338,6 +365,25 @@ export function defineTool<Input = unknown, Output = unknown>(tool: AgentTool<In
|
|
|
338
365
|
return tool;
|
|
339
366
|
}
|
|
340
367
|
|
|
368
|
+
export function composioManaged(input: ComposioManagedIntegrationInput): ComposioManagedIntegration {
|
|
369
|
+
const name = normalizeIntegrationName(input.name ?? "composio", "composio integration name");
|
|
370
|
+
const toolkits = normalizeToolkitList(input.toolkits, "composioManaged.toolkits");
|
|
371
|
+
const tools = input.tools ? normalizeComposioToolMap(input.tools, toolkits) : undefined;
|
|
372
|
+
const tags = input.tags ? normalizeIntegrationTags(input.tags) : undefined;
|
|
373
|
+
const confirmExternalWrites = input.confirmExternalWrites;
|
|
374
|
+
|
|
375
|
+
return {
|
|
376
|
+
type: "composio",
|
|
377
|
+
provider: "composio",
|
|
378
|
+
mode: "managed",
|
|
379
|
+
name,
|
|
380
|
+
toolkits,
|
|
381
|
+
...(tools ? { tools } : {}),
|
|
382
|
+
...(tags ? { tags } : {}),
|
|
383
|
+
...(confirmExternalWrites === undefined ? {} : { confirmExternalWrites }),
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
|
|
341
387
|
export function websiteChannel(input: WebsiteChannelInput): WebsiteChannelConfig {
|
|
342
388
|
return {
|
|
343
389
|
type: "website",
|
|
@@ -404,6 +450,109 @@ function normalizeChannelSecrets(secrets: string[], context: string): string[] {
|
|
|
404
450
|
return Array.from(uniqueSecrets).sort();
|
|
405
451
|
}
|
|
406
452
|
|
|
453
|
+
function normalizeIntegrationName(value: string, context: string): string {
|
|
454
|
+
const name = value.trim();
|
|
455
|
+
|
|
456
|
+
if (!/^[a-z][a-z0-9-]*$/.test(name)) {
|
|
457
|
+
throw new Error(`${context} must start with a lowercase letter and contain only lowercase letters, numbers, and hyphens.`);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
return name;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
function normalizeToolkitList(values: string[], context: string): string[] {
|
|
464
|
+
if (!Array.isArray(values) || values.length === 0) {
|
|
465
|
+
throw new Error(`${context} must include at least one toolkit slug.`);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
const toolkits = new Set<string>();
|
|
469
|
+
|
|
470
|
+
for (const value of values) {
|
|
471
|
+
if (typeof value !== "string") {
|
|
472
|
+
throw new Error(`${context} entries must be toolkit slug strings.`);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
const toolkit = value.trim().toLowerCase();
|
|
476
|
+
|
|
477
|
+
if (!/^[a-z][a-z0-9_-]*$/.test(toolkit)) {
|
|
478
|
+
throw new Error(`${context} entries must start with a letter and contain only letters, numbers, underscores, and hyphens.`);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
toolkits.add(toolkit);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
return Array.from(toolkits).sort();
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
function normalizeComposioToolMap(values: Record<string, string[]>, toolkits: string[]): Record<string, string[]> | undefined {
|
|
488
|
+
const toolkitSet = new Set(toolkits);
|
|
489
|
+
const normalized: Record<string, string[]> = {};
|
|
490
|
+
|
|
491
|
+
for (const [rawToolkit, rawTools] of Object.entries(values)) {
|
|
492
|
+
const toolkit = rawToolkit.trim().toLowerCase();
|
|
493
|
+
|
|
494
|
+
if (!toolkitSet.has(toolkit)) {
|
|
495
|
+
throw new Error(`composioManaged.tools.${rawToolkit} must reference a toolkit listed in composioManaged.toolkits.`);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
if (!Array.isArray(rawTools) || rawTools.length === 0) {
|
|
499
|
+
throw new Error(`composioManaged.tools.${rawToolkit} must include at least one Composio action slug.`);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
const tools = new Set<string>();
|
|
503
|
+
|
|
504
|
+
for (const rawTool of rawTools) {
|
|
505
|
+
if (typeof rawTool !== "string") {
|
|
506
|
+
throw new Error(`composioManaged.tools.${rawToolkit} entries must be Composio action slug strings.`);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
const tool = rawTool.trim().toUpperCase();
|
|
510
|
+
|
|
511
|
+
if (!/^[A-Z][A-Z0-9_]*$/.test(tool)) {
|
|
512
|
+
throw new Error(`composioManaged.tools.${rawToolkit} entries must be uppercase Composio action slugs.`);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
tools.add(tool);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
normalized[toolkit] = Array.from(tools).sort();
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
return Object.keys(normalized).length > 0 ? normalized : undefined;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
function normalizeIntegrationTags(tags: IntegrationTagsConfig): IntegrationTagsConfig {
|
|
525
|
+
const normalized: IntegrationTagsConfig = {};
|
|
526
|
+
|
|
527
|
+
if (tags.enable !== undefined) {
|
|
528
|
+
normalized.enable = normalizeTagList(tags.enable, "composioManaged.tags.enable");
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
if (tags.disable !== undefined) {
|
|
532
|
+
normalized.disable = normalizeTagList(tags.disable, "composioManaged.tags.disable");
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
return normalized;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
function normalizeTagList(values: string[], context: string): string[] {
|
|
539
|
+
if (!Array.isArray(values)) {
|
|
540
|
+
throw new Error(`${context} must be an array of tag strings.`);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
return Array.from(
|
|
544
|
+
new Set(
|
|
545
|
+
values.map((value) => {
|
|
546
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
547
|
+
throw new Error(`${context} entries must be non-empty strings.`);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
return value.trim();
|
|
551
|
+
}),
|
|
552
|
+
),
|
|
553
|
+
).sort();
|
|
554
|
+
}
|
|
555
|
+
|
|
407
556
|
function normalizeChannelBuffer(input: ChannelBufferInput, context: string): ChannelBufferConfig {
|
|
408
557
|
if (input.mode === "off") {
|
|
409
558
|
return { mode: "off" };
|
package/src/runtime/chat.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { loadAgentCapsule } from "./config";
|
|
|
7
7
|
import { openPreparedCapsuleStore } from "./database";
|
|
8
8
|
import { loadCapsuleEnv } from "./env";
|
|
9
9
|
import { AgentKitError, isAgentKitError } from "./errors";
|
|
10
|
+
import { createManagedComposioTools } from "./integrations/composio";
|
|
10
11
|
import { syncConfiguredKnowledgeSources } from "./knowledge/ingest";
|
|
11
12
|
import { appendKnowledgePromptPolicy } from "./knowledge/prompt-policy";
|
|
12
13
|
import { createKnowledgeSearchTool } from "./knowledge/tool";
|
|
@@ -145,7 +146,7 @@ export async function runAgentMessage(
|
|
|
145
146
|
}
|
|
146
147
|
|
|
147
148
|
function withKnowledgeTools(capsule: LoadedAgentCapsule): NonNullable<LoadedAgentCapsule["config"]["tools"]> {
|
|
148
|
-
const tools = [...(capsule.config.tools ?? [])];
|
|
149
|
+
const tools = [...createManagedComposioTools(capsule.config), ...(capsule.config.tools ?? [])];
|
|
149
150
|
const knowledgeTool = createKnowledgeSearchTool(capsule);
|
|
150
151
|
|
|
151
152
|
if (knowledgeTool) {
|
package/src/runtime/config.ts
CHANGED
|
@@ -16,9 +16,11 @@ import type {
|
|
|
16
16
|
TelegramAllowedUpdate,
|
|
17
17
|
AgentKnowledgeEmbeddingProvider,
|
|
18
18
|
ChannelBufferMode,
|
|
19
|
+
AgentIntegration,
|
|
19
20
|
ChannelAudioMode,
|
|
20
21
|
TranscriptionProviderName,
|
|
21
22
|
} from "../index";
|
|
23
|
+
import { MANAGED_COMPOSIO_TOOL_NAME } from "./integrations/composio";
|
|
22
24
|
import { AgentKitError } from "./errors";
|
|
23
25
|
import { isValidTimeZone } from "./prompt-context";
|
|
24
26
|
|
|
@@ -35,6 +37,9 @@ const TELEGRAM_ALLOWED_UPDATES = new Set<TelegramAllowedUpdate>(["message"]);
|
|
|
35
37
|
const KNOWLEDGE_EMBEDDING_PROVIDERS = new Set<AgentKnowledgeEmbeddingProvider>(["none", "test", "openai"]);
|
|
36
38
|
const TRANSCRIPTION_PROVIDERS = new Set<TranscriptionProviderName>(["test", "openai", "groq"]);
|
|
37
39
|
const CHANNEL_NAME_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
40
|
+
const INTEGRATION_NAME_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
41
|
+
const COMPOSIO_TOOLKIT_PATTERN = /^[a-z][a-z0-9_-]*$/;
|
|
42
|
+
const COMPOSIO_TOOL_SLUG_PATTERN = /^[A-Z][A-Z0-9_]*$/;
|
|
38
43
|
const SECRET_NAME_PATTERN = /^[A-Z_][A-Z0-9_]*$/;
|
|
39
44
|
const moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
40
45
|
let configImportNonce = 0;
|
|
@@ -234,6 +239,7 @@ function validateAgentConfig(value: unknown): asserts value is AgentConfig {
|
|
|
234
239
|
}
|
|
235
240
|
}
|
|
236
241
|
|
|
242
|
+
validateIntegrations(value.integrations, value.runtime as AgentRuntime, value.tools);
|
|
237
243
|
validateTranscriptionConfig(value.transcription);
|
|
238
244
|
validateChannels(value.channels, value.runtime as AgentRuntime, Boolean(value.transcription));
|
|
239
245
|
validateKnowledgeConfig(value.knowledge);
|
|
@@ -258,6 +264,133 @@ function validateAgentConfig(value: unknown): asserts value is AgentConfig {
|
|
|
258
264
|
validateFilesConfig(value.storage.files);
|
|
259
265
|
}
|
|
260
266
|
|
|
267
|
+
function validateIntegrations(
|
|
268
|
+
value: unknown,
|
|
269
|
+
runtime: AgentRuntime,
|
|
270
|
+
tools: AgentConfig["tools"] = [],
|
|
271
|
+
): void {
|
|
272
|
+
if (value === undefined) {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (!Array.isArray(value)) {
|
|
277
|
+
throw invalidConfig("integrations must be an array when provided.");
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (value.length > 0 && runtime !== "edge") {
|
|
281
|
+
throw invalidConfig('managed integrations require runtime: "edge". Use BYO defineTool wrappers for local-only integrations.');
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
let composioCount = 0;
|
|
285
|
+
|
|
286
|
+
for (const [index, integration] of value.entries()) {
|
|
287
|
+
if (!isRecord(integration)) {
|
|
288
|
+
throw invalidConfig(`integrations[${index}] must be an object.`);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
if (integration.provider !== "composio" || integration.type !== "composio" || integration.mode !== "managed") {
|
|
292
|
+
throw invalidConfig(`integrations[${index}] must be composioManaged({...}) or { type: "composio", provider: "composio", mode: "managed", ... }.`);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
composioCount += 1;
|
|
296
|
+
validateComposioManagedIntegration(integration as unknown as AgentIntegration, index);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
if (composioCount > 1) {
|
|
300
|
+
throw invalidConfig("Only one managed Composio integration is supported per agent.");
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const hasExplicitComposioTools = value.some(
|
|
304
|
+
(integration) => isRecord(integration) && integration.provider === "composio" && isRecord(integration.tools),
|
|
305
|
+
);
|
|
306
|
+
|
|
307
|
+
if (hasExplicitComposioTools && tools.some((tool) => isRecord(tool) && tool.name === MANAGED_COMPOSIO_TOOL_NAME)) {
|
|
308
|
+
throw invalidConfig(`tools must not declare reserved managed Composio tool name "${MANAGED_COMPOSIO_TOOL_NAME}".`);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function validateComposioManagedIntegration(value: AgentIntegration, index: number): void {
|
|
313
|
+
expectString(value.name, `integrations[${index}].name`);
|
|
314
|
+
|
|
315
|
+
if (!INTEGRATION_NAME_PATTERN.test(value.name)) {
|
|
316
|
+
throw invalidConfig(`integrations[${index}].name must start with a lowercase letter and contain only lowercase letters, numbers, and hyphens.`);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if (!Array.isArray(value.toolkits) || value.toolkits.length === 0) {
|
|
320
|
+
throw invalidConfig(`integrations[${index}].toolkits must include at least one Composio toolkit slug.`);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const toolkits = new Set<string>();
|
|
324
|
+
|
|
325
|
+
for (const [toolkitIndex, toolkit] of value.toolkits.entries()) {
|
|
326
|
+
expectString(toolkit, `integrations[${index}].toolkits[${toolkitIndex}]`);
|
|
327
|
+
|
|
328
|
+
if (!COMPOSIO_TOOLKIT_PATTERN.test(toolkit)) {
|
|
329
|
+
throw invalidConfig(`integrations[${index}].toolkits[${toolkitIndex}] must be a lowercase Composio toolkit slug.`);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if (toolkits.has(toolkit)) {
|
|
333
|
+
throw invalidConfig(`integrations[${index}].toolkits must not contain duplicates.`);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
toolkits.add(toolkit);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
if (value.tools !== undefined) {
|
|
340
|
+
if (!isRecord(value.tools)) {
|
|
341
|
+
throw invalidConfig(`integrations[${index}].tools must be an object when provided.`);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
for (const [toolkit, tools] of Object.entries(value.tools)) {
|
|
345
|
+
if (!toolkits.has(toolkit)) {
|
|
346
|
+
throw invalidConfig(`integrations[${index}].tools.${toolkit} must reference a toolkit listed in integrations[${index}].toolkits.`);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
if (!Array.isArray(tools) || tools.length === 0) {
|
|
350
|
+
throw invalidConfig(`integrations[${index}].tools.${toolkit} must include at least one Composio action slug.`);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
const seenTools = new Set<string>();
|
|
354
|
+
|
|
355
|
+
for (const [toolIndex, tool] of tools.entries()) {
|
|
356
|
+
expectString(tool, `integrations[${index}].tools.${toolkit}[${toolIndex}]`);
|
|
357
|
+
|
|
358
|
+
if (!COMPOSIO_TOOL_SLUG_PATTERN.test(tool)) {
|
|
359
|
+
throw invalidConfig(`integrations[${index}].tools.${toolkit}[${toolIndex}] must be an uppercase Composio action slug.`);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
if (seenTools.has(tool)) {
|
|
363
|
+
throw invalidConfig(`integrations[${index}].tools.${toolkit} must not contain duplicates.`);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
seenTools.add(tool);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
if (value.tags !== undefined) {
|
|
372
|
+
validateIntegrationTags(value.tags, `integrations[${index}].tags`);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (value.confirmExternalWrites !== undefined && typeof value.confirmExternalWrites !== "boolean") {
|
|
376
|
+
throw invalidConfig(`integrations[${index}].confirmExternalWrites must be a boolean when provided.`);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
function validateIntegrationTags(value: unknown, label: string): void {
|
|
381
|
+
if (!isRecord(value)) {
|
|
382
|
+
throw invalidConfig(`${label} must be an object when provided.`);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (value.enable !== undefined) {
|
|
386
|
+
expectStringArray(value.enable, `${label}.enable`);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
if (value.disable !== undefined) {
|
|
390
|
+
expectStringArray(value.disable, `${label}.disable`);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
261
394
|
function validateTranscriptionConfig(value: unknown): void {
|
|
262
395
|
if (value === undefined) {
|
|
263
396
|
return;
|
|
@@ -2,6 +2,11 @@ import { relative, resolve } from "node:path";
|
|
|
2
2
|
|
|
3
3
|
import type { AgentConfig, AgentTool } from "../../index";
|
|
4
4
|
import type { LoadedAgentCapsule } from "../config";
|
|
5
|
+
import {
|
|
6
|
+
createManagedComposioTools,
|
|
7
|
+
managedComposioRequiredSecrets,
|
|
8
|
+
resolveManagedComposioIntegrations,
|
|
9
|
+
} from "../integrations/composio";
|
|
5
10
|
import { resolveKnowledgeConfig } from "../knowledge/config";
|
|
6
11
|
import { KNOWLEDGE_SEARCH_TOOL_NAME } from "../knowledge/tool";
|
|
7
12
|
import { resolveTranscriptionConfig } from "../transcription";
|
|
@@ -28,6 +33,15 @@ export type SharedAgentManifest = {
|
|
|
28
33
|
permissions: string[];
|
|
29
34
|
timeoutMs: number | null;
|
|
30
35
|
}>;
|
|
36
|
+
integrations: Array<{
|
|
37
|
+
name: string;
|
|
38
|
+
provider: "composio";
|
|
39
|
+
mode: "managed";
|
|
40
|
+
toolkits: string[];
|
|
41
|
+
tools: string[];
|
|
42
|
+
userId: string;
|
|
43
|
+
confirmExternalWrites: boolean;
|
|
44
|
+
}>;
|
|
31
45
|
channels: NonNullable<AgentConfig["channels"]>;
|
|
32
46
|
transcription: {
|
|
33
47
|
enabled: boolean;
|
|
@@ -94,6 +108,8 @@ export function buildSharedAgentManifest(
|
|
|
94
108
|
const database = buildDatabaseManifest(capsule, options.databaseSchema ?? null);
|
|
95
109
|
const files = buildFilesManifest(capsule);
|
|
96
110
|
const knowledge = resolveKnowledgeConfig(capsule.config);
|
|
111
|
+
const integrationTools = createManagedComposioTools(capsule.config);
|
|
112
|
+
const tools = [...integrationTools, ...(capsule.config.tools ?? [])];
|
|
97
113
|
const transcription = resolveTranscriptionConfig(capsule.config.transcription);
|
|
98
114
|
|
|
99
115
|
requiredSecrets.add("AGENTKIT_PRIVATE_TOKEN");
|
|
@@ -119,7 +135,11 @@ export function buildSharedAgentManifest(
|
|
|
119
135
|
requiredSecrets.add(transcription.secret);
|
|
120
136
|
}
|
|
121
137
|
|
|
122
|
-
for (const
|
|
138
|
+
for (const secret of managedComposioRequiredSecrets(capsule.config)) {
|
|
139
|
+
requiredSecrets.add(secret);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
for (const tool of tools) {
|
|
123
143
|
for (const secret of tool.secrets ?? []) {
|
|
124
144
|
requiredSecrets.add(secret);
|
|
125
145
|
}
|
|
@@ -139,7 +159,7 @@ export function buildSharedAgentManifest(
|
|
|
139
159
|
timeZone: capsule.config.timeZone ?? null,
|
|
140
160
|
prompt: toCapsulePath(capsule, capsule.instructionsPath),
|
|
141
161
|
secrets: Array.from(requiredSecrets).sort(),
|
|
142
|
-
tools:
|
|
162
|
+
tools: tools.map((tool) => ({
|
|
143
163
|
name: tool.name,
|
|
144
164
|
description: tool.description,
|
|
145
165
|
inputSchema: tool.inputSchema,
|
|
@@ -148,6 +168,15 @@ export function buildSharedAgentManifest(
|
|
|
148
168
|
permissions: [...(tool.permissions ?? [])].sort(),
|
|
149
169
|
timeoutMs: tool.timeoutMs ?? null,
|
|
150
170
|
})),
|
|
171
|
+
integrations: resolveManagedComposioIntegrations(capsule.config).map((integration) => ({
|
|
172
|
+
name: integration.name,
|
|
173
|
+
provider: integration.provider,
|
|
174
|
+
mode: integration.mode,
|
|
175
|
+
toolkits: integration.toolkits,
|
|
176
|
+
tools: integration.allowedTools,
|
|
177
|
+
userId: integration.userId,
|
|
178
|
+
confirmExternalWrites: integration.confirmExternalWrites !== false,
|
|
179
|
+
})),
|
|
151
180
|
channels: capsule.config.channels ?? [],
|
|
152
181
|
transcription: {
|
|
153
182
|
enabled: transcription.enabled,
|
|
@@ -3,6 +3,10 @@ import { createHash } from "node:crypto";
|
|
|
3
3
|
import { loadAgentCapsule } from "./config";
|
|
4
4
|
import { buildSharedAgentManifest } from "./core/manifest";
|
|
5
5
|
import { listCapsuleEnv } from "./env";
|
|
6
|
+
import {
|
|
7
|
+
MANAGED_COMPOSIO_API_KEY_SECRET,
|
|
8
|
+
resolveManagedComposioIntegrations,
|
|
9
|
+
} from "./integrations/composio";
|
|
6
10
|
|
|
7
11
|
export type DeployReadinessSecretSource = {
|
|
8
12
|
dotenv: boolean;
|
|
@@ -30,6 +34,14 @@ export type DeployReadinessContext = {
|
|
|
30
34
|
embeddingProvider: string;
|
|
31
35
|
databaseDriver: "none" | "turso";
|
|
32
36
|
};
|
|
37
|
+
integrations: {
|
|
38
|
+
managedComposio: {
|
|
39
|
+
enabled: boolean;
|
|
40
|
+
toolkits: string[];
|
|
41
|
+
toolCount: number;
|
|
42
|
+
userId: string | null;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
33
45
|
};
|
|
34
46
|
|
|
35
47
|
export async function loadDeployReadinessContext(
|
|
@@ -38,6 +50,7 @@ export async function loadDeployReadinessContext(
|
|
|
38
50
|
): Promise<DeployReadinessContext> {
|
|
39
51
|
const capsule = await loadAgentCapsule(cwd);
|
|
40
52
|
const manifest = buildSharedAgentManifest(capsule);
|
|
53
|
+
const managedComposio = resolveManagedComposioIntegrations(capsule.config)[0];
|
|
41
54
|
const dotenvNames = new Set(await listCapsuleEnv(capsule.root));
|
|
42
55
|
const requiredSecrets = manifest.secrets;
|
|
43
56
|
const localSecrets: Record<string, DeployReadinessSecretSource> = {};
|
|
@@ -57,6 +70,7 @@ export async function loadDeployReadinessContext(
|
|
|
57
70
|
isAgentKitManagedDeploySecret(name, {
|
|
58
71
|
accessMode: capsule.config.access.mode,
|
|
59
72
|
databaseDriver: manifest.storage.database.driver,
|
|
73
|
+
managedComposioEnabled: Boolean(managedComposio),
|
|
60
74
|
}),
|
|
61
75
|
);
|
|
62
76
|
const managed = new Set(agentKitManagedSecrets);
|
|
@@ -82,6 +96,14 @@ export async function loadDeployReadinessContext(
|
|
|
82
96
|
embeddingProvider: manifest.knowledge.embedding.provider,
|
|
83
97
|
databaseDriver: manifest.storage.database.driver,
|
|
84
98
|
},
|
|
99
|
+
integrations: {
|
|
100
|
+
managedComposio: {
|
|
101
|
+
enabled: Boolean(managedComposio),
|
|
102
|
+
toolkits: managedComposio?.toolkits ?? [],
|
|
103
|
+
toolCount: managedComposio?.allowedTools.length ?? 0,
|
|
104
|
+
userId: managedComposio?.userId ?? null,
|
|
105
|
+
},
|
|
106
|
+
},
|
|
85
107
|
};
|
|
86
108
|
}
|
|
87
109
|
|
|
@@ -91,7 +113,11 @@ export function stableCloudProjectId(name: string, accountId?: string | null): s
|
|
|
91
113
|
|
|
92
114
|
function isAgentKitManagedDeploySecret(
|
|
93
115
|
name: string,
|
|
94
|
-
context: {
|
|
116
|
+
context: {
|
|
117
|
+
accessMode: DeployReadinessContext["accessMode"];
|
|
118
|
+
databaseDriver: "none" | "turso";
|
|
119
|
+
managedComposioEnabled: boolean;
|
|
120
|
+
},
|
|
95
121
|
): boolean {
|
|
96
122
|
if (context.databaseDriver === "turso" && (name === "TURSO_DATABASE_URL" || name === "TURSO_AUTH_TOKEN")) {
|
|
97
123
|
return true;
|
|
@@ -101,5 +127,9 @@ function isAgentKitManagedDeploySecret(
|
|
|
101
127
|
return true;
|
|
102
128
|
}
|
|
103
129
|
|
|
130
|
+
if (context.managedComposioEnabled && name === MANAGED_COMPOSIO_API_KEY_SECRET) {
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
|
|
104
134
|
return false;
|
|
105
135
|
}
|