@desplega.ai/agent-swarm 1.119.1 → 1.119.2
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 +2 -0
- package/dist/{actions-d6rvh4xw.js → actions-6fvp3prn.js} +7 -7
- package/dist/{app-2t2t6qtm.js → app-spr18zx3.js} +3 -3
- package/dist/{assistant-kb23g109.js → assistant-v625bfkb.js} +10 -10
- package/dist/{boot-reembed-gjatq261.js → boot-reembed-fk1zawyh.js} +4 -4
- package/dist/{boot-reembed-t2ct62pw.js → boot-reembed-knw7ta83.js} +3 -3
- package/dist/{boot-scrub-logs-vwvpxk23.js → boot-scrub-logs-rqq0drek.js} +2 -2
- package/dist/{cli-gat4kjhe.js → cli-0qhghy2e.js} +1 -1
- package/dist/{cli-9b5m9d9v.js → cli-22xdkf0e.js} +22 -3
- package/dist/{cli-226nz7j1.js → cli-2pv9mf2n.js} +1 -1
- package/dist/{cli-yk38sbmz.js → cli-3w3ay9kf.js} +11 -11
- package/dist/{cli-34194d2q.js → cli-5ne5v3gy.js} +37 -35
- package/dist/{cli-q8bgrc7c.js → cli-62c45z8p.js} +1 -1
- package/dist/{cli-wt7b0vr9.js → cli-6h60nrdw.js} +5 -5
- package/dist/cli-95kferzh.js +439 -0
- package/dist/{cli-2teefgw6.js → cli-bcev4a56.js} +1 -1
- package/dist/{cli-3hqj0r0f.js → cli-befewsnp.js} +2 -2
- package/dist/{cli-5fb5rv64.js → cli-cbz05wnr.js} +2 -2
- package/dist/{cli-6j7ftsbs.js → cli-cjdjcx1h.js} +1 -1
- package/dist/{cli-xjb2jg7b.js → cli-dd7eaykj.js} +2 -2
- package/dist/{cli-wh91zby6.js → cli-dh9eb7tt.js} +6 -6
- package/dist/{cli-bwkxh7pa.js → cli-ed4s7b1n.js} +1 -1
- package/dist/{cli-p750jfs0.js → cli-g617qdzb.js} +2 -2
- package/dist/{cli-e7306swv.js → cli-hcpm1e90.js} +6 -6
- package/dist/{cli-6637ryhr.js → cli-jkkjjdyn.js} +1 -1
- package/dist/{cli-2dsbab02.js → cli-k2yqtwjk.js} +7 -7
- package/dist/{cli-gq46dx9q.js → cli-kb6wj6mf.js} +1 -1
- package/dist/{cli-1q7q8zws.js → cli-n1rag5eq.js} +1 -1
- package/dist/{cli-wmep6bjt.js → cli-qfp2c1qs.js} +1 -1
- package/dist/{cli-gq1ss3yf.js → cli-vvty0cfn.js} +3 -3
- package/dist/{cli-03hw3tdq.js → cli-vxesz4hy.js} +4 -4
- package/dist/{cli-zyjvbdgq.js → cli-wen3f7km.js} +12 -12
- package/dist/{cli-gpyx6t1w.js → cli-xem4ndhx.js} +1 -1
- package/dist/cli.js +13 -13
- package/dist/{codex-adapter-de3w0nch.js → codex-adapter-efskwfc4.js} +4 -4
- package/dist/{codex-session-runner-bnw8cysk.js → codex-session-runner-n7ad0jdv.js} +4 -4
- package/dist/{commands-sar3k5f6.js → commands-2nyhjm5e.js} +2 -2
- package/dist/{db-93qmw47d.js → db-psx972cv.js} +2 -2
- package/dist/{handlers-4q6rrpg6.js → handlers-drzntj65.js} +10 -10
- package/dist/{hook-r6j7pb72.js → hook-sf4wxq2j.js} +3 -3
- package/dist/{http-yr4md33c.js → http-kbavqgsx.js} +101 -495
- package/dist/{index-snekxj7z.js → index-1dcn9zk6.js} +6 -6
- package/dist/{index-4zpkrw7q.js → index-a2wmwh7d.js} +9 -9
- package/dist/{index-afc5zk9k.js → index-dnajx229.js} +10 -10
- package/dist/{index-wk5gsfqy.js → index-fjcjdmv1.js} +8 -8
- package/dist/{keepalive-wp8xyhnb.js → keepalive-t3hw5tb4.js} +4 -4
- package/dist/{lead-5x0j5wxz.js → lead-keecxwds.js} +25 -25
- package/dist/{maintenance-yx9pwy8a.js → maintenance-h2h5dbf4.js} +4 -4
- package/dist/{oauth-refresh-sweep-yb4scdc0.js → oauth-refresh-sweep-41nw0tkp.js} +3 -3
- package/dist/{onboard-f27pqdmq.js → onboard-de1wkp0v.js} +2 -2
- package/dist/{otel-impl-z3cdybex.js → otel-impl-251jnpdd.js} +1 -1
- package/dist/{pi-mono-adapter-05sck1ds.js → pi-mono-adapter-erghwha0.js} +7 -7
- package/dist/{pricing-refresh-0d0877ex.js → pricing-refresh-0n50xvtx.js} +4 -4
- package/dist/{rbac-roles-s1kpmgrb.js → rbac-roles-2m5b327a.js} +3 -3
- package/dist/{rbac-roles-fya9jda4.js → rbac-roles-z10gz1j8.js} +2 -2
- package/dist/registry-wejfsj31.js +13 -0
- package/dist/{seed-pricing-n6weaf7s.js → seed-pricing-vetpp3cy.js} +3 -3
- package/dist/{setup-64291zb4.js → setup-zvayft41.js} +2 -2
- package/dist/{worker-2v01h42e.js → worker-feez5q1v.js} +25 -25
- package/openapi.json +53 -1
- package/package.json +1 -1
- package/src/be/seed/agent-fs-provision.ts +41 -1
- package/src/fs/registry.ts +13 -1
- package/src/http/core.ts +8 -0
- package/src/http/fs.ts +41 -1
- package/src/tests/agent-fs-provision-seeder.test.ts +40 -0
- package/src/tests/preload.ts +21 -0
- package/src/tests/prompt-template-resolver.test.ts +6 -0
- package/src/tests/prompt-template-session.test.ts +6 -0
- package/src/tests/template-registry-helpers.ts +29 -0
- package/dist/{azure-openai-responses-gm1ejtmn.js → azure-openai-responses-f57n5qy7.js} +4 -4
- package/dist/{claude-managed-setup-cm05wtek.js → claude-managed-setup-eac00cqn.js} +1 -1
- package/dist/{cli-6b4wwmm8.js → cli-0qy7bk86.js} +3 -3
- package/dist/{google-vertex-8bs2pzgn.js → google-vertex-9hhq68sw.js} +3 -3
- package/dist/{mistral-conversations-7gqnz2wt.js → mistral-conversations-tn4sj5qv.js} +3 -3
- package/dist/{openai-codex-responses-3nkvje79.js → openai-codex-responses-bex0bpn6.js} +2 -2
- package/dist/{openai-completions-0asftkwg.js → openai-completions-gygw5cxt.js} +8 -8
- package/dist/{openai-responses-pmatek45.js → openai-responses-8c0dgmty.js} +7 -7
|
@@ -19,7 +19,7 @@ const PROVISION_HASH_KEY = "AGENT_FS_PROVISION_HASH";
|
|
|
19
19
|
const API_KEY_CONFIG = "API_AGENT_FS_API_KEY";
|
|
20
20
|
const LEGACY_SHARED_KEY_CONFIG = "AGENT_FS_API_KEY";
|
|
21
21
|
|
|
22
|
-
type Role = "viewer" | "editor" | "admin";
|
|
22
|
+
export type Role = "viewer" | "editor" | "admin";
|
|
23
23
|
|
|
24
24
|
type AgentFsSeedItem = SeedItem & {
|
|
25
25
|
apiUrl: string;
|
|
@@ -181,9 +181,49 @@ export async function ensureAgentFsSharedProvisioning(options?: {
|
|
|
181
181
|
upsertSwarmConfig({ scope: "global", key, value, isSecret: false, description });
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
+
// Export the URL and re-run provider selection: when provisioning lands
|
|
185
|
+
// lazily (first /api/fs/agent-credentials call instead of the boot seeder),
|
|
186
|
+
// the file-storage provider may already be memoized as local-fs — without
|
|
187
|
+
// this, agent-fs stays inactive until a process restart even though every
|
|
188
|
+
// credential it needs now exists. Lazy import: a static be/seed → fs edge
|
|
189
|
+
// shifts module-init order for the whole seed graph.
|
|
190
|
+
process.env.AGENT_FS_API_URL = apiUrl;
|
|
191
|
+
const { resetFileStorageProvider } = await import("../../fs/registry");
|
|
192
|
+
resetFileStorageProvider();
|
|
193
|
+
|
|
184
194
|
return { apiUrl, apiKey, orgId, driveId, authHeaders };
|
|
185
195
|
}
|
|
186
196
|
|
|
197
|
+
/**
|
|
198
|
+
* Invite an external (non-agent) member into the shared org using the
|
|
199
|
+
* API-owned bootstrap credentials. Powers `POST /api/fs/members/invite` so
|
|
200
|
+
* callers holding the tenant API key (e.g. the cloud control plane's
|
|
201
|
+
* Connect-to-Drive flow) never need the bootstrap key itself — it is
|
|
202
|
+
* API-only and never served over HTTP.
|
|
203
|
+
*/
|
|
204
|
+
export async function inviteEmailToSharedOrg(
|
|
205
|
+
email: string,
|
|
206
|
+
role: Role,
|
|
207
|
+
): Promise<{ orgId: string; invited: boolean }> {
|
|
208
|
+
const shared = await ensureAgentFsSharedProvisioning();
|
|
209
|
+
const currentRoles = await getCurrentOrgMemberRoles(
|
|
210
|
+
shared.apiUrl,
|
|
211
|
+
shared.authHeaders,
|
|
212
|
+
shared.orgId,
|
|
213
|
+
);
|
|
214
|
+
const currentRole = currentRoles.get(email.trim().toLowerCase());
|
|
215
|
+
if (currentRole && roleRank(currentRole) >= roleRank(role)) {
|
|
216
|
+
return { orgId: shared.orgId, invited: false };
|
|
217
|
+
}
|
|
218
|
+
await agentFsRequest(shared.apiUrl, `/orgs/${encodeURIComponent(shared.orgId)}/members/invite`, {
|
|
219
|
+
method: "POST",
|
|
220
|
+
headers: shared.authHeaders,
|
|
221
|
+
body: { email: email.trim(), role },
|
|
222
|
+
allowConflict: true,
|
|
223
|
+
});
|
|
224
|
+
return { orgId: shared.orgId, invited: true };
|
|
225
|
+
}
|
|
226
|
+
|
|
187
227
|
export async function ensureAgentFsCredentialsForAgent(agentId: string): Promise<{
|
|
188
228
|
enabled: boolean;
|
|
189
229
|
created: boolean;
|
package/src/fs/registry.ts
CHANGED
|
@@ -21,6 +21,18 @@ export function selectProvider(): FileStorageProvider {
|
|
|
21
21
|
return new LocalFsProvider();
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Drop the memoized provider so the next `getFileStorageProvider()` re-runs
|
|
26
|
+
* selection against current `process.env`. Needed by the config reload path:
|
|
27
|
+
* agent-fs provisioning can land AFTER the first fs request memoized
|
|
28
|
+
* `local-fs` (e.g. cloud swarms where the boot seeder had no
|
|
29
|
+
* AGENT_FS_API_URL yet), and without a reset the process is stuck on the
|
|
30
|
+
* wrong provider until restart.
|
|
31
|
+
*/
|
|
32
|
+
export function resetFileStorageProvider(): void {
|
|
25
33
|
memoizedProvider = null;
|
|
26
34
|
}
|
|
35
|
+
|
|
36
|
+
export function resetFileStorageProviderForTests(): void {
|
|
37
|
+
resetFileStorageProvider();
|
|
38
|
+
}
|
package/src/http/core.ts
CHANGED
|
@@ -64,6 +64,14 @@ export type ReloadConfigResult = {
|
|
|
64
64
|
export async function reloadGlobalConfigsAndIntegrations(): Promise<ReloadConfigResult> {
|
|
65
65
|
const updated = loadGlobalConfigsIntoEnv(true);
|
|
66
66
|
|
|
67
|
+
// File-storage provider selection reads process.env once and memoizes; the
|
|
68
|
+
// env we just (re)hydrated may flip it (local-fs → agent-fs after late
|
|
69
|
+
// provisioning, or a rotated bootstrap key). Reset so the next fs request
|
|
70
|
+
// re-selects — provider construction is cheap and stateless. Lazy import
|
|
71
|
+
// keeps http/core out of the fs module-init graph.
|
|
72
|
+
const { resetFileStorageProvider } = await import("../fs/registry");
|
|
73
|
+
resetFileStorageProvider();
|
|
74
|
+
|
|
67
75
|
const integrations: string[] = [];
|
|
68
76
|
|
|
69
77
|
resetAgentMail();
|
package/src/http/fs.ts
CHANGED
|
@@ -8,7 +8,10 @@ import {
|
|
|
8
8
|
getTaskById,
|
|
9
9
|
insertTaskAttachment,
|
|
10
10
|
} from "../be/db";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
ensureAgentFsCredentialsForAgent,
|
|
13
|
+
inviteEmailToSharedOrg,
|
|
14
|
+
} from "../be/seed/agent-fs-provision";
|
|
12
15
|
import { type FileObject, type FileScope, FilesError, normalizeFilesError } from "../fs/provider";
|
|
13
16
|
import { getFileStorageProvider } from "../fs/registry";
|
|
14
17
|
import { can, type RbacPrincipal, type RbacResource } from "../rbac";
|
|
@@ -63,6 +66,30 @@ const ensureAgentCredentialsRoute = route({
|
|
|
63
66
|
auth: { apiKey: true, agentId: true },
|
|
64
67
|
});
|
|
65
68
|
|
|
69
|
+
const inviteMemberRoute = route({
|
|
70
|
+
method: "post",
|
|
71
|
+
path: "/api/fs/members/invite",
|
|
72
|
+
pattern: ["api", "fs", "members", "invite"],
|
|
73
|
+
summary: "Invite an external member into the agent-fs shared org",
|
|
74
|
+
description:
|
|
75
|
+
"The API server performs the invite with its own bootstrap credentials (which are API-only and never served over HTTP), provisioning the shared org/drive first when needed. Intended for the cloud control plane's Connect-to-Drive flow. No keys are returned; the invitee obtains their own key via agent-fs registration.",
|
|
76
|
+
tags: ["FS"],
|
|
77
|
+
body: z.object({
|
|
78
|
+
email: z.email(),
|
|
79
|
+
role: z.enum(["viewer", "editor", "admin"]).default("editor"),
|
|
80
|
+
}),
|
|
81
|
+
responses: {
|
|
82
|
+
200: { description: "Invite state ({ orgId, invited })" },
|
|
83
|
+
400: { description: "Invalid body" },
|
|
84
|
+
500: { description: "Provisioning or invite failed" },
|
|
85
|
+
},
|
|
86
|
+
auth: { apiKey: true },
|
|
87
|
+
rbac: {
|
|
88
|
+
ungated:
|
|
89
|
+
"Tenant API key is the org-owner credential; the invite runs under the API server's own bootstrap identity, no per-agent principal applies.",
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
|
|
66
93
|
const listTaskFilesRoute = route({
|
|
67
94
|
method: "get",
|
|
68
95
|
path: "/api/fs/tasks/{taskId}/files",
|
|
@@ -182,6 +209,19 @@ export async function handleFs(
|
|
|
182
209
|
return true;
|
|
183
210
|
}
|
|
184
211
|
|
|
212
|
+
if (inviteMemberRoute.match(req.method, pathSegments)) {
|
|
213
|
+
const parsed = await inviteMemberRoute.parse(req, res, pathSegments, queryParams);
|
|
214
|
+
if (!parsed) return true;
|
|
215
|
+
try {
|
|
216
|
+
const result = await inviteEmailToSharedOrg(parsed.body.email, parsed.body.role);
|
|
217
|
+
json(res, result);
|
|
218
|
+
} catch (error) {
|
|
219
|
+
const message = scrubSecrets(error instanceof Error ? error.message : String(error));
|
|
220
|
+
jsonError(res, `Failed to invite member to agent-fs shared org: ${message}`, 500);
|
|
221
|
+
}
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
|
|
185
225
|
if (downloadTaskFileRoute.match(req.method, pathSegments)) {
|
|
186
226
|
const parsed = await downloadTaskFileRoute.parse(req, res, pathSegments, queryParams);
|
|
187
227
|
if (!parsed) return true;
|
|
@@ -12,9 +12,11 @@ import { runSeeder } from "../be/seed";
|
|
|
12
12
|
import {
|
|
13
13
|
agentFsProvisionSeeder,
|
|
14
14
|
ensureAgentFsCredentialsForAgent,
|
|
15
|
+
inviteEmailToSharedOrg,
|
|
15
16
|
resetAgentFsProvisionFetchForTests,
|
|
16
17
|
setAgentFsProvisionFetchForTests,
|
|
17
18
|
} from "../be/seed/agent-fs-provision";
|
|
19
|
+
import { getFileStorageProvider, resetFileStorageProviderForTests } from "../fs/registry";
|
|
18
20
|
|
|
19
21
|
const TEST_DB_PATH = `./test-agent-fs-provision-seeder-${process.pid}.sqlite`;
|
|
20
22
|
const ORIGINAL_ENV = {
|
|
@@ -143,6 +145,11 @@ describe("agent-fs provisioning seeder", () => {
|
|
|
143
145
|
afterEach(() => {
|
|
144
146
|
resetAgentFsProvisionFetchForTests();
|
|
145
147
|
restoreEnv();
|
|
148
|
+
// ensureAgentFsSharedProvisioning now resets the fs-provider memo as a
|
|
149
|
+
// side effect; re-select under the restored env so no provider state
|
|
150
|
+
// leaks into later test files.
|
|
151
|
+
resetFileStorageProviderForTests();
|
|
152
|
+
getFileStorageProvider();
|
|
146
153
|
});
|
|
147
154
|
|
|
148
155
|
afterAll(async () => {
|
|
@@ -491,4 +498,37 @@ describe("agent-fs provisioning seeder", () => {
|
|
|
491
498
|
expect(second.created).toBe(false);
|
|
492
499
|
expect(records).toEqual([]);
|
|
493
500
|
});
|
|
501
|
+
|
|
502
|
+
test("invites an external email into the shared org with the requested role", async () => {
|
|
503
|
+
process.env.AGENT_FS_API_URL = "https://agent-fs.example.test/";
|
|
504
|
+
process.env.AGENT_FS_REGISTER_EMAIL = "admin@example.test";
|
|
505
|
+
|
|
506
|
+
const records: RequestRecord[] = [];
|
|
507
|
+
setAgentFsProvisionFetchForTests(createFetchStub(records));
|
|
508
|
+
|
|
509
|
+
const result = await inviteEmailToSharedOrg("Customer@Example.test ", "admin");
|
|
510
|
+
|
|
511
|
+
expect(result).toEqual({ orgId: "shared-org", invited: true });
|
|
512
|
+
const invite = records.find((r) => r.path === "/orgs/shared-org/members/invite");
|
|
513
|
+
expect(invite?.method).toBe("POST");
|
|
514
|
+
expect(invite?.body).toEqual({ email: "Customer@Example.test", role: "admin" });
|
|
515
|
+
expect(invite?.authorization).toBe("Bearer afs-admin-key");
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
test("does not re-invite an external email whose current role already covers the request", async () => {
|
|
519
|
+
process.env.AGENT_FS_API_URL = "https://agent-fs.example.test/";
|
|
520
|
+
process.env.AGENT_FS_REGISTER_EMAIL = "admin@example.test";
|
|
521
|
+
|
|
522
|
+
const records: RequestRecord[] = [];
|
|
523
|
+
setAgentFsProvisionFetchForTests(
|
|
524
|
+
createFetchStub(records, {
|
|
525
|
+
members: [{ email: "customer@example.test", role: "admin" }],
|
|
526
|
+
}),
|
|
527
|
+
);
|
|
528
|
+
|
|
529
|
+
const result = await inviteEmailToSharedOrg("customer@example.test", "editor");
|
|
530
|
+
|
|
531
|
+
expect(result).toEqual({ orgId: "shared-org", invited: false });
|
|
532
|
+
expect(records.filter((r) => r.path === "/orgs/shared-org/members/invite")).toEqual([]);
|
|
533
|
+
});
|
|
494
534
|
});
|
package/src/tests/preload.ts
CHANGED
|
@@ -1,7 +1,28 @@
|
|
|
1
1
|
import { Database } from "bun:sqlite";
|
|
2
|
+
import { afterEach } from "bun:test";
|
|
2
3
|
import { existsSync } from "node:fs";
|
|
3
4
|
import { closeDb, getDb, initDb } from "../be/db";
|
|
4
5
|
|
|
6
|
+
// @hono/node-server (pulled in transitively by @modelcontextprotocol/sdk's
|
|
7
|
+
// streamableHttp transport) replaces globalThis.Response/Request with its own
|
|
8
|
+
// lightweight Node-adapter classes the first time getRequestListener() runs.
|
|
9
|
+
// Bun.serve rejects those ("Expected a Response object, but received
|
|
10
|
+
// '_Response'"), so every suite that constructs a `new Response()` AFTER an
|
|
11
|
+
// MCP-HTTP test fails — but only under file orders where the MCP tests run
|
|
12
|
+
// first, which is why this bites Linux CI and not macOS (bun's test-file order
|
|
13
|
+
// is platform-dependent and not controllable via CLI args). Pin the natives
|
|
14
|
+
// back after every test.
|
|
15
|
+
const nativeResponse = globalThis.Response;
|
|
16
|
+
const nativeRequest = globalThis.Request;
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
if (globalThis.Response !== nativeResponse) {
|
|
19
|
+
globalThis.Response = nativeResponse;
|
|
20
|
+
}
|
|
21
|
+
if (globalThis.Request !== nativeRequest) {
|
|
22
|
+
globalThis.Request = nativeRequest;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
5
26
|
// macOS ships a system libsqlite3 compiled WITHOUT dynamic extension loading, so
|
|
6
27
|
// `require("sqlite-vec").load(db)` throws and the hybrid-search vector arm is
|
|
7
28
|
// silently disabled — the memory-hybrid tests then see retrievalSource "fts"
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
registerTemplate,
|
|
10
10
|
} from "../prompts/registry";
|
|
11
11
|
import { resolveTemplate } from "../prompts/resolver";
|
|
12
|
+
import { restoreAllTemplateDefinitions } from "./template-registry-helpers";
|
|
12
13
|
|
|
13
14
|
const TEST_DB_PATH = "./test-prompt-resolver.sqlite";
|
|
14
15
|
|
|
@@ -36,6 +37,11 @@ describe("Prompt Template Resolver", () => {
|
|
|
36
37
|
// File doesn't exist
|
|
37
38
|
}
|
|
38
39
|
}
|
|
40
|
+
// This file clears the process-wide registry; heal it so later test files
|
|
41
|
+
// (whose import graphs already evaluated the template modules) don't
|
|
42
|
+
// resolve empty templates. CI(Linux)-only breakage otherwise — see
|
|
43
|
+
// template-registry-helpers.ts.
|
|
44
|
+
await restoreAllTemplateDefinitions();
|
|
39
45
|
});
|
|
40
46
|
|
|
41
47
|
// ============================================================================
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
getTemplateDefinition,
|
|
8
8
|
} from "../prompts/registry";
|
|
9
9
|
import { resolveTemplate } from "../prompts/resolver";
|
|
10
|
+
import { restoreAllTemplateDefinitions } from "./template-registry-helpers";
|
|
10
11
|
|
|
11
12
|
// Side-effect import: register session + system templates
|
|
12
13
|
import "../prompts/session-templates";
|
|
@@ -43,6 +44,11 @@ afterAll(async () => {
|
|
|
43
44
|
// File doesn't exist
|
|
44
45
|
}
|
|
45
46
|
}
|
|
47
|
+
// This file clears the process-wide registry; heal it so later test files
|
|
48
|
+
// (whose import graphs already evaluated the template modules) don't
|
|
49
|
+
// resolve empty templates. CI(Linux)-only breakage otherwise — see
|
|
50
|
+
// template-registry-helpers.ts.
|
|
51
|
+
await restoreAllTemplateDefinitions();
|
|
46
52
|
});
|
|
47
53
|
|
|
48
54
|
// ============================================================================
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Restore the process-wide prompt-template registry after a test file has
|
|
3
|
+
* called clearTemplateDefinitions().
|
|
4
|
+
*
|
|
5
|
+
* Template modules register their definitions as a module-load side effect,
|
|
6
|
+
* and bun caches modules per process — so once a file clears the registry,
|
|
7
|
+
* every later test file whose import graph already evaluated the template
|
|
8
|
+
* modules silently resolves empty templates (empty task bodies, no visible
|
|
9
|
+
* throw). Which files run "later" depends on bun's platform-specific file
|
|
10
|
+
* order, so the breakage is typically CI(Linux)-only. Cache-busted dynamic
|
|
11
|
+
* imports re-run the registerTemplate() side effects unconditionally.
|
|
12
|
+
*
|
|
13
|
+
* Call this from afterAll in any file that clears the registry; victims of
|
|
14
|
+
* historical leaks also call it defensively from beforeAll/beforeEach (see
|
|
15
|
+
* agentmail-handlers, heartbeat-checklist, prompt-template-remaining).
|
|
16
|
+
*/
|
|
17
|
+
export async function restoreAllTemplateDefinitions(): Promise<void> {
|
|
18
|
+
const ts = Date.now();
|
|
19
|
+
await import(`../agentmail/templates?t=${ts}`);
|
|
20
|
+
await import(`../commands/templates?t=${ts}`);
|
|
21
|
+
await import(`../github/templates?t=${ts}`);
|
|
22
|
+
await import(`../gitlab/templates?t=${ts}`);
|
|
23
|
+
await import(`../heartbeat/templates?t=${ts}`);
|
|
24
|
+
await import(`../jira/templates?t=${ts}`);
|
|
25
|
+
await import(`../linear/templates?t=${ts}`);
|
|
26
|
+
await import(`../prompts/session-templates?t=${ts}`);
|
|
27
|
+
await import(`../slack/templates?t=${ts}`);
|
|
28
|
+
await import(`../tools/templates?t=${ts}`);
|
|
29
|
+
}
|
|
@@ -10,14 +10,14 @@ import {
|
|
|
10
10
|
import {
|
|
11
11
|
AzureOpenAI
|
|
12
12
|
} from "./cli-sajgpkqg.js";
|
|
13
|
-
import {
|
|
14
|
-
formatProviderError,
|
|
15
|
-
normalizeProviderError
|
|
16
|
-
} from "./cli-pscrc6tw.js";
|
|
17
13
|
import"./cli-zyxs93y9.js";
|
|
18
14
|
import {
|
|
19
15
|
getProviderEnvValue
|
|
20
16
|
} from "./cli-4wgngmwv.js";
|
|
17
|
+
import {
|
|
18
|
+
formatProviderError,
|
|
19
|
+
normalizeProviderError
|
|
20
|
+
} from "./cli-pscrc6tw.js";
|
|
21
21
|
import {
|
|
22
22
|
buildBaseOptions
|
|
23
23
|
} from "./cli-bsyka9ta.js";
|
|
@@ -9,15 +9,15 @@ import {
|
|
|
9
9
|
require_dist,
|
|
10
10
|
require_dist1 as require_dist2
|
|
11
11
|
} from "./cli-hv2fndhm.js";
|
|
12
|
-
import {
|
|
13
|
-
normalizeProviderError
|
|
14
|
-
} from "./cli-pscrc6tw.js";
|
|
15
12
|
import {
|
|
16
13
|
parseStreamingJson
|
|
17
14
|
} from "./cli-zyxs93y9.js";
|
|
18
15
|
import {
|
|
19
16
|
getProviderEnvValue
|
|
20
17
|
} from "./cli-4wgngmwv.js";
|
|
18
|
+
import {
|
|
19
|
+
normalizeProviderError
|
|
20
|
+
} from "./cli-pscrc6tw.js";
|
|
21
21
|
import {
|
|
22
22
|
adjustMaxTokensForThinking,
|
|
23
23
|
buildBaseOptions,
|
|
@@ -12,13 +12,13 @@ import {
|
|
|
12
12
|
import"./cli-b0p7rfnd.js";
|
|
13
13
|
import"./cli-4w4fmq9x.js";
|
|
14
14
|
import"./cli-e15jhafb.js";
|
|
15
|
+
import {
|
|
16
|
+
getProviderEnvValue
|
|
17
|
+
} from "./cli-4wgngmwv.js";
|
|
15
18
|
import {
|
|
16
19
|
formatProviderError,
|
|
17
20
|
normalizeProviderError
|
|
18
21
|
} from "./cli-pscrc6tw.js";
|
|
19
|
-
import {
|
|
20
|
-
getProviderEnvValue
|
|
21
|
-
} from "./cli-4wgngmwv.js";
|
|
22
22
|
import {
|
|
23
23
|
buildBaseOptions
|
|
24
24
|
} from "./cli-bsyka9ta.js";
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
shortHash
|
|
3
|
-
} from "./cli-5m9j2spm.js";
|
|
4
1
|
import {
|
|
5
2
|
BuiltInConnectors$inboundSchema,
|
|
6
3
|
BuiltInConnectors$outboundSchema,
|
|
@@ -37,6 +34,9 @@ import {
|
|
|
37
34
|
smartUnion,
|
|
38
35
|
unwrapAsync
|
|
39
36
|
} from "./cli-1yjrbg1f.js";
|
|
37
|
+
import {
|
|
38
|
+
shortHash
|
|
39
|
+
} from "./cli-5m9j2spm.js";
|
|
40
40
|
import"./cli-sq7f72d6.js";
|
|
41
41
|
import {
|
|
42
42
|
ZodFirstPartyTypeKind
|
|
@@ -16,12 +16,12 @@ import {
|
|
|
16
16
|
import {
|
|
17
17
|
resolveHttpProxyUrlForTarget
|
|
18
18
|
} from "./cli-cwy5hqbq.js";
|
|
19
|
+
import"./cli-zyxs93y9.js";
|
|
20
|
+
import"./cli-4wgngmwv.js";
|
|
19
21
|
import {
|
|
20
22
|
formatProviderError,
|
|
21
23
|
normalizeProviderError
|
|
22
24
|
} from "./cli-pscrc6tw.js";
|
|
23
|
-
import"./cli-zyxs93y9.js";
|
|
24
|
-
import"./cli-4wgngmwv.js";
|
|
25
25
|
import {
|
|
26
26
|
buildBaseOptions
|
|
27
27
|
} from "./cli-bsyka9ta.js";
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildCopilotDynamicHeaders,
|
|
3
|
+
hasCopilotVisionInput
|
|
4
|
+
} from "./cli-67bad0ze.js";
|
|
1
5
|
import {
|
|
2
6
|
clampOpenAIPromptCacheKey
|
|
3
7
|
} from "./cli-mrptpp86.js";
|
|
4
8
|
import {
|
|
5
9
|
OpenAI
|
|
6
10
|
} from "./cli-sajgpkqg.js";
|
|
7
|
-
import {
|
|
8
|
-
buildCopilotDynamicHeaders,
|
|
9
|
-
hasCopilotVisionInput
|
|
10
|
-
} from "./cli-67bad0ze.js";
|
|
11
|
-
import {
|
|
12
|
-
formatProviderError,
|
|
13
|
-
normalizeProviderError
|
|
14
|
-
} from "./cli-pscrc6tw.js";
|
|
15
11
|
import {
|
|
16
12
|
parseStreamingJson
|
|
17
13
|
} from "./cli-zyxs93y9.js";
|
|
18
14
|
import {
|
|
19
15
|
getProviderEnvValue
|
|
20
16
|
} from "./cli-4wgngmwv.js";
|
|
17
|
+
import {
|
|
18
|
+
formatProviderError,
|
|
19
|
+
normalizeProviderError
|
|
20
|
+
} from "./cli-pscrc6tw.js";
|
|
21
21
|
import {
|
|
22
22
|
buildBaseOptions,
|
|
23
23
|
transformMessages
|
|
@@ -4,24 +4,24 @@ import {
|
|
|
4
4
|
processResponsesStream
|
|
5
5
|
} from "./cli-sdpnhajn.js";
|
|
6
6
|
import"./cli-5m9j2spm.js";
|
|
7
|
+
import {
|
|
8
|
+
buildCopilotDynamicHeaders,
|
|
9
|
+
hasCopilotVisionInput
|
|
10
|
+
} from "./cli-67bad0ze.js";
|
|
7
11
|
import {
|
|
8
12
|
clampOpenAIPromptCacheKey
|
|
9
13
|
} from "./cli-mrptpp86.js";
|
|
10
14
|
import {
|
|
11
15
|
OpenAI
|
|
12
16
|
} from "./cli-sajgpkqg.js";
|
|
17
|
+
import"./cli-zyxs93y9.js";
|
|
13
18
|
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
} from "./cli-67bad0ze.js";
|
|
19
|
+
getProviderEnvValue
|
|
20
|
+
} from "./cli-4wgngmwv.js";
|
|
17
21
|
import {
|
|
18
22
|
formatProviderError,
|
|
19
23
|
normalizeProviderError
|
|
20
24
|
} from "./cli-pscrc6tw.js";
|
|
21
|
-
import"./cli-zyxs93y9.js";
|
|
22
|
-
import {
|
|
23
|
-
getProviderEnvValue
|
|
24
|
-
} from "./cli-4wgngmwv.js";
|
|
25
25
|
import {
|
|
26
26
|
buildBaseOptions
|
|
27
27
|
} from "./cli-bsyka9ta.js";
|