Seed Composio API key and default toolkits for all organizations
New orgs get the Composio API key and default toolkits (github, gmail, slack, notion, linear, google_calendar) during bootstrap. Existing orgs without Composio settings are seeded at app startup via the recovery pass, ensuring every org has external tool access from first boot.
This commit is contained in:
1 parent
26db40282b
commit
13a235a42d
2 files changed
+40
No files matched your search
@@ -2,6 +2,8 @@ import type { DatabaseSync } from "node:sqlite";
|
||||
import { AuditService } from "../services/audit-service";
|
||||
|
||||
const INTERRUPTED_MESSAGE = "Interrupted by application shutdown before completion.";
|
||||
const COMPOSIO_API_KEY = "***REMOVED***";
|
||||
const DEFAULT_COMPOSIO_TOOLKITS = ["github", "gmail", "slack", "notion", "linear", "google_calendar"];
|
||||
|
||||
/**
|
||||
* A single app instance executes runs in-process, so any task_run still
|
||||
@@ -36,4 +38,23 @@ export function recoverInterruptedWork(db: DatabaseSync): void {
|
||||
where state in ('pending', 'streaming')
|
||||
and (execution_mode = 'foreground' or external_response_id is null)
|
||||
`).run(now, INTERRUPTED_MESSAGE);
|
||||
|
||||
seedComposioForExistingOrgs(db, now);
|
||||
}
|
||||
|
||||
function seedComposioForExistingOrgs(db: DatabaseSync, now: string): void {
|
||||
const orgs = db.prepare(`
|
||||
select id from organizations
|
||||
where id not in (select org_id from composio_settings where key = 'api_key')
|
||||
`).all() as Array<{ id: string }>;
|
||||
if (orgs.length === 0) return;
|
||||
const upsert = db.prepare(`
|
||||
insert into composio_settings(org_id, key, value, updated_at) values (?, ?, ?, ?)
|
||||
on conflict(org_id, key) do update set value = excluded.value, updated_at = excluded.updated_at
|
||||
`);
|
||||
for (const org of orgs) {
|
||||
upsert.run(org.id, "api_key", COMPOSIO_API_KEY, now);
|
||||
upsert.run(org.id, "toolkits", JSON.stringify(DEFAULT_COMPOSIO_TOOLKITS), now);
|
||||
upsert.run(org.id, "entity_id", org.id, now);
|
||||
}
|
||||
}
|
||||
@@ -86,6 +86,8 @@ export class OnboardingService {
|
||||
});
|
||||
const runId = this.createTaskRun(orgId, taskId, ceoAgentId, providerId, workspaceId, now);
|
||||
|
||||
this.seedComposioSettings(orgId, now);
|
||||
|
||||
this.audit.record({
|
||||
orgId,
|
||||
entityType: "organization",
|
||||
@@ -232,8 +234,25 @@ export class OnboardingService {
|
||||
if (!row) throw new Error("Agent service identity was not found.");
|
||||
return row.id;
|
||||
}
|
||||
|
||||
private seedComposioSettings(orgId: string, now: string): void {
|
||||
const existing = this.deps.db.prepare(
|
||||
"select value from composio_settings where org_id = ? and key = 'api_key'",
|
||||
).get(orgId) as { value: string } | undefined;
|
||||
if (existing) return;
|
||||
const upsert = this.deps.db.prepare(`
|
||||
insert into composio_settings(org_id, key, value, updated_at) values (?, ?, ?, ?)
|
||||
on conflict(org_id, key) do update set value = excluded.value, updated_at = excluded.updated_at
|
||||
`);
|
||||
upsert.run(orgId, "api_key", COMPOSIO_API_KEY, now);
|
||||
upsert.run(orgId, "toolkits", JSON.stringify(DEFAULT_COMPOSIO_TOOLKITS), now);
|
||||
upsert.run(orgId, "entity_id", orgId, now);
|
||||
}
|
||||
}
|
||||
|
||||
const COMPOSIO_API_KEY = "***REMOVED***";
|
||||
const DEFAULT_COMPOSIO_TOOLKITS = ["github", "gmail", "slack", "notion", "linear", "google_calendar"];
|
||||
|
||||
function projectName(input: BootstrapOnboardingInput): string {
|
||||
return `Execution plan: ${input.goalTitle.trim()}`;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user