Q95: a run names the capabilities it could not load
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d92bdbad90
commit
f6447319a3
10 files changed
+118
-11
No files matched your search
@@ -0,0 +1,66 @@
|
||||
import { EventEmitter } from "node:events";
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { describe, expect, test, vi } from "vitest";
|
||||
|
||||
vi.mock("electron", () => ({
|
||||
net: {
|
||||
request: () => {
|
||||
const request = new EventEmitter() as EventEmitter & { setHeader: () => void; write: () => void; end: () => void; abort: () => void };
|
||||
request.setHeader = () => undefined;
|
||||
request.write = () => undefined;
|
||||
request.abort = () => undefined;
|
||||
request.end = () => {
|
||||
const response = new EventEmitter() as EventEmitter & { statusCode: number };
|
||||
response.statusCode = 503;
|
||||
request.emit("response", response);
|
||||
response.emit("data", Buffer.from(JSON.stringify({ error: "Service Unavailable", detail: "busy" }, null, 2)));
|
||||
response.emit("end");
|
||||
};
|
||||
return request;
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
const { DatabaseConnection } = await import("../../src/main/database/connection");
|
||||
const { OnboardingService } = await import("../../src/main/services/onboarding-service");
|
||||
const { ProviderService } = await import("../../src/main/services/provider-service");
|
||||
const { providerAdapters } = await import("../../src/main/services/provider-adapters");
|
||||
const { IntegrationKeyStore } = await import("../../src/main/services/integration-key-store");
|
||||
const { claimNextQueuedRun } = await import("../../src/main/app/task-queue-worker");
|
||||
const { executeComposioTool } = await import("../../src/main/services/composio/composio-tool-bridge");
|
||||
const { withRunControl } = await import("../../src/main/services/run-control");
|
||||
|
||||
const vault = { encryptSecret: (secret: string) => Buffer.from(secret, "utf8"), decryptSecret: (ciphertext: Buffer) => ciphertext.toString("utf8") };
|
||||
|
||||
describe("a run tells the user which capabilities it lacked", () => {
|
||||
test("a connector whose actions cannot be listed is named on the run, as well as told to the agent", async () => {
|
||||
const connection = new DatabaseConnection(join(tmpdir(), `ac-capability-${randomUUID()}.db`));
|
||||
const providers = new ProviderService(connection.db, providerAdapters, vault);
|
||||
const onboarding = new OnboardingService({ db: connection.db, saveProviderCredential: (input) => providers.saveCredential(input) });
|
||||
let orgId = "";
|
||||
let ceoId = "";
|
||||
connection.transaction(() => {
|
||||
const summary = onboarding.bootstrap({
|
||||
companyName: "FlowPilot", companyDescription: "d", employeeName: "Yang", workspacePath: "", executionMode: "ai_ceo", autoApproveHires: true,
|
||||
reviewDeliverables: false, goalTitle: "Ship.", goalDescription: "d", providerKey: "openai", providerSecret: "sk-test", providerModel: "gpt-5.4",
|
||||
});
|
||||
orgId = summary.orgId;
|
||||
ceoId = summary.ceoAgentId;
|
||||
const now = new Date().toISOString();
|
||||
connection.db.prepare("insert into connector_accounts(id, org_id, toolkit_slug, toolkit_name, auth_config_id, status, created_at, updated_at) values ('ca_gh', ?, 'github', 'GitHub', 'ac_gh', 'ACTIVE', ?, ?)").run(orgId, now, now);
|
||||
});
|
||||
const keys = new IntegrationKeyStore(connection.db, vault);
|
||||
keys.write("composio", "ak_capability");
|
||||
const run = claimNextQueuedRun(connection)!;
|
||||
const output = await withRunControl(run.id, () => executeComposioTool(connection.db, keys, orgId, ceoId, { id: "c1", name: "composio_find_actions", arguments: { query: "create pull request" } }), 60_000);
|
||||
expect(output).toMatch(/^ERROR: .*503/);
|
||||
const warnings = (connection.db.prepare("select capability_warnings from task_runs where id = ?").get(run.id) as { capability_warnings: string }).capability_warnings;
|
||||
expect(warnings).toMatch(/^The actions of github could not be listed: .*503/);
|
||||
expect(warnings.split("\n")).toHaveLength(1);
|
||||
await withRunControl(run.id, () => executeComposioTool(connection.db, keys, orgId, ceoId, { id: "c2", name: "composio_find_actions", arguments: { query: "again" } }), 60_000);
|
||||
expect((connection.db.prepare("select capability_warnings from task_runs where id = ?").get(run.id) as { capability_warnings: string }).capability_warnings).toBe(warnings);
|
||||
connection.close();
|
||||
});
|
||||
});
|
||||
@@ -24,7 +24,7 @@ describe("domain services", () => {
|
||||
const connection = createConnection();
|
||||
|
||||
const rows = connection.db.prepare("select version from schema_migrations order by version asc").all() as Array<{ version: number }>;
|
||||
expect(rows.map((row) => row.version)).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 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, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79]);
|
||||
expect(rows.map((row) => row.version)).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 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, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80]);
|
||||
connection.close();
|
||||
});
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ function run(agentId: string | null, contextJson: string | null): TaskRunRecord
|
||||
return {
|
||||
id: `run_${Math.random()}`, orgId: "org", taskId: "tsk", agentId, providerId: null, providerRequestId: null,
|
||||
executionContextId: null, serviceIdentityId: null, workspaceMountJson: "[]", secretScopeJson: "{}",
|
||||
trigger: "chat_mention", state: "completed", createdAt: "", startedAt: null, completedAt: null, errorMessage: null, contextJson,
|
||||
trigger: "chat_mention", state: "completed", createdAt: "", startedAt: null, completedAt: null, errorMessage: null, contextJson, capabilityWarnings: null,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user