@cargo-ai/cdk 1.0.5 → 1.0.7
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 +59 -9
- package/build/src/cli/commands/from.d.ts +65 -0
- package/build/src/cli/commands/from.d.ts.map +1 -0
- package/build/src/cli/commands/from.js +275 -0
- package/build/src/cli/commands/init.d.ts +1 -1
- package/build/src/cli/commands/init.d.ts.map +1 -1
- package/build/src/cli/commands/init.js +32 -13
- package/build/src/cli/commands/types.d.ts.map +1 -1
- package/build/src/cli/commands/types.js +75 -37
- package/build/src/core.d.ts +1 -1
- package/build/src/core.d.ts.map +1 -1
- package/build/src/deploy/apply.d.ts +6 -0
- package/build/src/deploy/apply.d.ts.map +1 -1
- package/build/src/deploy/apply.js +4 -0
- package/build/src/deploy/destroy.d.ts.map +1 -1
- package/build/src/deploy/destroy.js +33 -0
- package/build/src/deploy/executors.live.d.ts.map +1 -1
- package/build/src/deploy/executors.live.js +157 -1
- package/build/src/deploy/readers.live.d.ts.map +1 -1
- package/build/src/deploy/readers.live.js +34 -1
- package/build/src/index.d.ts +11 -7
- package/build/src/index.d.ts.map +1 -1
- package/build/src/index.js +6 -4
- package/build/src/refs.d.ts +22 -0
- package/build/src/refs.d.ts.map +1 -1
- package/build/src/refs.js +11 -2
- package/build/src/resources/actions.d.ts +39 -19
- package/build/src/resources/actions.d.ts.map +1 -1
- package/build/src/resources/actions.js +60 -33
- package/build/src/resources/agent.d.ts +33 -23
- package/build/src/resources/agent.d.ts.map +1 -1
- package/build/src/resources/agent.js +24 -24
- package/build/src/resources/app.d.ts +3 -1
- package/build/src/resources/app.d.ts.map +1 -1
- package/build/src/resources/app.js +2 -1
- package/build/src/resources/capacity.d.ts +11 -0
- package/build/src/resources/capacity.d.ts.map +1 -1
- package/build/src/resources/capacity.js +81 -0
- package/build/src/resources/connector.d.ts +10 -0
- package/build/src/resources/connector.d.ts.map +1 -1
- package/build/src/resources/connector.js +18 -1
- package/build/src/resources/customIntegration.d.ts +12 -0
- package/build/src/resources/customIntegration.d.ts.map +1 -0
- package/build/src/resources/customIntegration.js +18 -0
- package/build/src/resources/mcpServer.d.ts +8 -10
- package/build/src/resources/mcpServer.d.ts.map +1 -1
- package/build/src/resources/mcpServer.js +4 -7
- package/build/src/resources/model.d.ts +47 -4
- package/build/src/resources/model.d.ts.map +1 -1
- package/build/src/resources/model.js +38 -1
- package/build/src/resources/relationship.d.ts +21 -0
- package/build/src/resources/relationship.d.ts.map +1 -0
- package/build/src/resources/relationship.js +39 -0
- package/build/src/resources/worker.d.ts +13 -1
- package/build/src/resources/worker.d.ts.map +1 -1
- package/build/src/resources/worker.js +3 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/templates/blank/cargo.ts +17 -22
- package/templates/full/README.md +7 -4
- package/templates/full/agents/sdr.ts +12 -8
- package/templates/full/connectors/hunter.ts +10 -0
- package/templates/full/mcp/crm.ts +9 -6
- package/templates/full/tools/enrich.ts +28 -9
|
@@ -69,7 +69,7 @@ export function registerTypesCommand(parent, getApi) {
|
|
|
69
69
|
].join("\n"));
|
|
70
70
|
info(``);
|
|
71
71
|
const extractorCount = payload.extractorConfigs.reduce((n, e) => n + e.extractors.length, 0);
|
|
72
|
-
info(`Typed ${String(payload.connectorConfigs.length)} connector config(s), ${String(extractorCount)} extractor config(s), ${String(payload.integrations.length)} integration(s), ${String(payload.native.length)} native action(s).`);
|
|
72
|
+
info(`Typed ${String(payload.connectorConfigs.length)} connector config(s), ${String(extractorCount)} extractor config(s), ${String(payload.agentTriggerConfigs.length)} agent trigger config(s), ${String(payload.integrations.length)} integration(s), ${String(payload.native.length)} native action(s).`);
|
|
73
73
|
});
|
|
74
74
|
}
|
|
75
75
|
async function fetchWorkspaceSurface(api) {
|
|
@@ -80,7 +80,16 @@ async function fetchWorkspaceSurface(api) {
|
|
|
80
80
|
const native = collectNative(nativeIntegrationResult.nativeIntegration.actions);
|
|
81
81
|
const connectorConfigs = collectConnectorConfigs(rawIntegrations);
|
|
82
82
|
const extractorConfigs = collectExtractorConfigs(rawIntegrations);
|
|
83
|
-
|
|
83
|
+
const extractorSlugs = collectExtractorSlugs(rawIntegrations);
|
|
84
|
+
const agentTriggerConfigs = collectAgentTriggerConfigs(rawIntegrations);
|
|
85
|
+
return {
|
|
86
|
+
integrations,
|
|
87
|
+
native,
|
|
88
|
+
connectorConfigs,
|
|
89
|
+
extractorConfigs,
|
|
90
|
+
extractorSlugs,
|
|
91
|
+
agentTriggerConfigs,
|
|
92
|
+
};
|
|
84
93
|
}
|
|
85
94
|
// integrationSlug → connector config type. Skips integrations whose schema
|
|
86
95
|
// prints as a bare record (no typing gained — the builder already falls back to
|
|
@@ -103,6 +112,27 @@ function collectConnectorConfigs(integrations) {
|
|
|
103
112
|
out.sort((a, b) => a.slug.localeCompare(b.slug));
|
|
104
113
|
return out;
|
|
105
114
|
}
|
|
115
|
+
// integrationSlug → its agent connector-trigger config type. Only a few
|
|
116
|
+
// integrations expose an agent trigger (e.g. slack, http); the rest are skipped,
|
|
117
|
+
// as are those whose schema prints as a bare record.
|
|
118
|
+
function collectAgentTriggerConfigs(integrations) {
|
|
119
|
+
const out = [];
|
|
120
|
+
for (const integration of integrations) {
|
|
121
|
+
const schema = integration.agent?.trigger?.config?.schema;
|
|
122
|
+
if (schema === undefined)
|
|
123
|
+
continue;
|
|
124
|
+
const typeSrc = printJsonSchemaType(schema);
|
|
125
|
+
if (typeSrc === "Record<string, unknown>")
|
|
126
|
+
continue;
|
|
127
|
+
out.push({
|
|
128
|
+
slug: integration.slug,
|
|
129
|
+
name: trimOrUndefined(integration.name),
|
|
130
|
+
typeSrc,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
out.sort((a, b) => a.slug.localeCompare(b.slug));
|
|
134
|
+
return out;
|
|
135
|
+
}
|
|
106
136
|
// integrationSlug → its extractors' config types. Skips extractors whose schema
|
|
107
137
|
// prints as a bare record, and integrations left with none.
|
|
108
138
|
function collectExtractorConfigs(integrations) {
|
|
@@ -125,6 +155,20 @@ function collectExtractorConfigs(integrations) {
|
|
|
125
155
|
out.sort((a, b) => a.integrationSlug.localeCompare(b.integrationSlug));
|
|
126
156
|
return out;
|
|
127
157
|
}
|
|
158
|
+
// integrationSlug → every extractor slug it exposes (the keys of `extractors`),
|
|
159
|
+
// so `defineModel`'s `extractSlug` autocompletes the full set, not just the ones
|
|
160
|
+
// that happen to add a typed config.
|
|
161
|
+
function collectExtractorSlugs(integrations) {
|
|
162
|
+
const out = [];
|
|
163
|
+
for (const integration of integrations) {
|
|
164
|
+
const slugs = Object.keys(integration.extractors ?? {}).sort((a, b) => a.localeCompare(b));
|
|
165
|
+
if (slugs.length === 0)
|
|
166
|
+
continue;
|
|
167
|
+
out.push({ integrationSlug: integration.slug, slugs });
|
|
168
|
+
}
|
|
169
|
+
out.sort((a, b) => a.integrationSlug.localeCompare(b.integrationSlug));
|
|
170
|
+
return out;
|
|
171
|
+
}
|
|
128
172
|
function collectIntegrations(integrations) {
|
|
129
173
|
const out = [];
|
|
130
174
|
for (const integration of integrations) {
|
|
@@ -205,6 +249,24 @@ function renderTypes(payload) {
|
|
|
205
249
|
}
|
|
206
250
|
cdkLines.push(` }`);
|
|
207
251
|
}
|
|
252
|
+
if (payload.extractorSlugs.length > 0) {
|
|
253
|
+
cdkLines.push(` interface ExtractorSlugs {`);
|
|
254
|
+
for (const e of payload.extractorSlugs) {
|
|
255
|
+
const union = e.slugs.map((s) => JSON.stringify(s)).join(" | ");
|
|
256
|
+
cdkLines.push(` ${jsonKey(e.integrationSlug)}: ${union};`);
|
|
257
|
+
}
|
|
258
|
+
cdkLines.push(` }`);
|
|
259
|
+
}
|
|
260
|
+
if (payload.agentTriggerConfigs.length > 0) {
|
|
261
|
+
cdkLines.push(` interface AgentTriggerConfigs {`);
|
|
262
|
+
for (const t of payload.agentTriggerConfigs) {
|
|
263
|
+
const doc = formatJsDoc({ name: t.name ?? t.slug, updatedAt: GENERATED_AT }, " ");
|
|
264
|
+
if (doc !== "")
|
|
265
|
+
cdkLines.push(doc.trimEnd());
|
|
266
|
+
cdkLines.push(` ${jsonKey(t.slug)}: ${t.typeSrc};`);
|
|
267
|
+
}
|
|
268
|
+
cdkLines.push(` }`);
|
|
269
|
+
}
|
|
208
270
|
if (cdkLines.length > 0) {
|
|
209
271
|
blocks.push([`declare module "@cargo-ai/cdk" {`, ...cdkLines, `}`].join("\n"));
|
|
210
272
|
}
|
|
@@ -230,7 +292,10 @@ function renderTypes(payload) {
|
|
|
230
292
|
}, " ");
|
|
231
293
|
if (actionDoc !== "")
|
|
232
294
|
wfLines.push(actionDoc.trimEnd());
|
|
233
|
-
|
|
295
|
+
// Action outputs aren't schema-typed, so `any` (not `Record<string,
|
|
296
|
+
// unknown>`, which lowers to an unusable nested `Ref`) — the result is
|
|
297
|
+
// then usable as a string, an object, or in any typed slot.
|
|
298
|
+
wfLines.push(` ${jsonKey(action.slug)}: IntegrationAction<${action.inputTypeSrc}, any>;`);
|
|
234
299
|
}
|
|
235
300
|
wfLines.push(` };`);
|
|
236
301
|
}
|
|
@@ -242,7 +307,7 @@ function renderTypes(payload) {
|
|
|
242
307
|
const doc = formatJsDoc({ name: n.name, description: n.description, updatedAt: GENERATED_AT }, " ");
|
|
243
308
|
if (doc !== "")
|
|
244
309
|
wfLines.push(doc.trimEnd());
|
|
245
|
-
wfLines.push(` ${jsonKey(n.slug)}: NativeAction<Record<string, unknown>,
|
|
310
|
+
wfLines.push(` ${jsonKey(n.slug)}: NativeAction<Record<string, unknown>, any>;`);
|
|
246
311
|
}
|
|
247
312
|
wfLines.push(` }`);
|
|
248
313
|
}
|
|
@@ -274,32 +339,20 @@ function renderTypes(payload) {
|
|
|
274
339
|
preamble.push(`export {};`);
|
|
275
340
|
return `${HEADER.trim()}\n\n${[...preamble, ...blocks].join("\n\n")}\n`;
|
|
276
341
|
}
|
|
342
|
+
// Runtime registrations. Only `native` needs one: integration actions are now
|
|
343
|
+
// referenced by handle via `defineWorkflow`'s `uses` (no `integrations.*` runtime
|
|
344
|
+
// registry), so integrations contribute types only (see `renderTypes`).
|
|
277
345
|
function renderEagerRegistration(payload) {
|
|
278
346
|
const lines = [];
|
|
279
347
|
lines.push(HEADER.trim());
|
|
280
|
-
|
|
281
|
-
if (payload.integrations.length > 0)
|
|
282
|
-
imports.push("registerIntegration");
|
|
283
|
-
if (payload.native.length > 0)
|
|
284
|
-
imports.push("registerNative");
|
|
285
|
-
if (imports.length === 0) {
|
|
348
|
+
if (payload.native.length === 0) {
|
|
286
349
|
lines.push(``);
|
|
287
|
-
lines.push(`//
|
|
350
|
+
lines.push(`// No custom native actions in this workspace.`);
|
|
288
351
|
lines.push(``);
|
|
289
352
|
return lines.join("\n");
|
|
290
353
|
}
|
|
291
|
-
lines.push(`import {
|
|
354
|
+
lines.push(`import { registerNative } from "@cargo-ai/workflow-sdk";`);
|
|
292
355
|
lines.push(``);
|
|
293
|
-
for (const c of payload.integrations) {
|
|
294
|
-
lines.push(`registerIntegration(${JSON.stringify(c.slug)}, {`);
|
|
295
|
-
for (const action of c.actions) {
|
|
296
|
-
const displayName = action.name !== undefined && action.name.length > 0
|
|
297
|
-
? action.name
|
|
298
|
-
: `${capitalize(c.slug)} ${humanize(action.slug)}`;
|
|
299
|
-
lines.push(` ${jsonKey(action.slug)}: { name: ${JSON.stringify(displayName)} },`);
|
|
300
|
-
}
|
|
301
|
-
lines.push(`});`);
|
|
302
|
-
}
|
|
303
356
|
for (const n of payload.native) {
|
|
304
357
|
lines.push(`registerNative(${JSON.stringify(n.slug)}, ${JSON.stringify(n.name)});`);
|
|
305
358
|
}
|
|
@@ -361,21 +414,6 @@ function formatJsDoc(doc, indent) {
|
|
|
361
414
|
out.push(`${indent} */`);
|
|
362
415
|
return `${out.join("\n")}\n`;
|
|
363
416
|
}
|
|
364
|
-
function capitalize(s) {
|
|
365
|
-
if (s.length === 0)
|
|
366
|
-
return s;
|
|
367
|
-
const first = s[0];
|
|
368
|
-
if (first === undefined)
|
|
369
|
-
return s;
|
|
370
|
-
return first.toUpperCase() + s.slice(1);
|
|
371
|
-
}
|
|
372
|
-
function humanize(slug) {
|
|
373
|
-
return slug
|
|
374
|
-
.replace(/([A-Z])/g, " $1")
|
|
375
|
-
.replace(/[_-]+/g, " ")
|
|
376
|
-
.trim()
|
|
377
|
-
.toLowerCase();
|
|
378
|
-
}
|
|
379
417
|
function relativeToBase(base, path) {
|
|
380
418
|
if (path.startsWith(base)) {
|
|
381
419
|
const rel = path.slice(base.length);
|
package/build/src/core.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export type Token = {
|
|
|
5
5
|
};
|
|
6
6
|
export declare function token(resourceId: string, field: string): Token;
|
|
7
7
|
export declare function isToken(value: unknown): value is Token;
|
|
8
|
-
export type ResourceKind = "connector" | "model" | "agent" | "play" | "tool" | "mcpServer" | "folder" | "file" | "worker" | "app" | "context" | "capacity" | "territory" | "segment";
|
|
8
|
+
export type ResourceKind = "connector" | "customIntegration" | "model" | "agent" | "play" | "tool" | "mcpServer" | "folder" | "file" | "worker" | "app" | "context" | "capacity" | "territory" | "segment" | "relationship";
|
|
9
9
|
export type ResourceNode = {
|
|
10
10
|
readonly id: string;
|
|
11
11
|
readonly kind: ResourceKind;
|
package/build/src/core.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/core.ts"],"names":[],"mappings":"AAaA,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,wBAAgB,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,CAE9D;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,KAAK,CAMtD;AAGD,MAAM,MAAM,YAAY,GACpB,WAAW,GACX,OAAO,GACP,OAAO,GACP,MAAM,GACN,MAAM,GACN,WAAW,GACX,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,KAAK,GACL,SAAS,GACT,UAAU,GACV,WAAW,GACX,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/core.ts"],"names":[],"mappings":"AAaA,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,wBAAgB,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,CAE9D;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,KAAK,CAMtD;AAGD,MAAM,MAAM,YAAY,GACpB,WAAW,GACX,mBAAmB,GACnB,OAAO,GACP,OAAO,GACP,MAAM,GACN,MAAM,GACN,WAAW,GACX,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,KAAK,GACL,SAAS,GACT,UAAU,GACV,WAAW,GACX,SAAS,GACT,cAAc,CAAC;AAEnB,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC,CAAC;AAoBF;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAUjD;AAMD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEtD;AAgBD,sCAAsC;AACtC,wBAAgB,SAAS,IAAI,YAAY,EAAE,CAE1C;AAED,gFAAgF;AAChF,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAgCD,gFAAgF;AAChF,wBAAgB,UAAU,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMnE;AAGD,gFAAgF;AAChF,wBAAgB,cAAc,CAC5B,KAAK,EAAE,OAAO,EACd,GAAG,GAAE,GAAG,CAAC,MAAM,CAAa,GAC3B,GAAG,CAAC,MAAM,CAAC,CAcb;AAED,oFAAoF;AACpF,wBAAgB,aAAa,CAC3B,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAC3C,OAAO,CAoBT;AAGD;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGxC;AAED;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAE9C;AAED;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GACrB,SAAS,GACT;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,WAAW,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAM3D;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAmBtD"}
|
|
@@ -27,6 +27,9 @@ export type Executors = {
|
|
|
27
27
|
file(spec: Record<string, unknown>, prior: StateEntry | undefined): Promise<Outputs & {
|
|
28
28
|
uuid: string;
|
|
29
29
|
}>;
|
|
30
|
+
customIntegration(spec: Record<string, unknown>, prior: StateEntry | undefined): Promise<Outputs & {
|
|
31
|
+
uuid: string;
|
|
32
|
+
}>;
|
|
30
33
|
worker(spec: Record<string, unknown>, prior: StateEntry | undefined): Promise<Outputs & {
|
|
31
34
|
uuid: string;
|
|
32
35
|
url: string;
|
|
@@ -47,6 +50,9 @@ export type Executors = {
|
|
|
47
50
|
segment(spec: Record<string, unknown>, prior: StateEntry | undefined): Promise<Outputs & {
|
|
48
51
|
uuid: string;
|
|
49
52
|
}>;
|
|
53
|
+
relationship(spec: Record<string, unknown>, prior: StateEntry | undefined): Promise<Outputs & {
|
|
54
|
+
uuid: string;
|
|
55
|
+
}>;
|
|
50
56
|
};
|
|
51
57
|
export type ApplyResult = {
|
|
52
58
|
state: State;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../../src/deploy/apply.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../../src/deploy/apply.ts"],"names":[],"mappings":"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"}
|
|
@@ -209,6 +209,8 @@ function runExecutor(node, resolved, prior, executors) {
|
|
|
209
209
|
return executors.folder(resolved, prior);
|
|
210
210
|
case "file":
|
|
211
211
|
return executors.file(resolved, prior);
|
|
212
|
+
case "customIntegration":
|
|
213
|
+
return executors.customIntegration(resolved, prior);
|
|
212
214
|
case "worker":
|
|
213
215
|
return executors.worker(resolved, prior);
|
|
214
216
|
case "app":
|
|
@@ -221,5 +223,7 @@ function runExecutor(node, resolved, prior, executors) {
|
|
|
221
223
|
return executors.territory(resolved, prior);
|
|
222
224
|
case "segment":
|
|
223
225
|
return executors.segment(resolved, prior);
|
|
226
|
+
case "relationship":
|
|
227
|
+
return executors.relationship(resolved, prior);
|
|
224
228
|
}
|
|
225
229
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"destroy.d.ts","sourceRoot":"","sources":["../../../src/deploy/destroy.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAMzC,MAAM,MAAM,aAAa,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"destroy.d.ts","sourceRoot":"","sources":["../../../src/deploy/destroy.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAMzC,MAAM,MAAM,aAAa,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AA8ItE;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,MAAM,EAAE,GACZ,OAAO,CAAC,aAAa,CAAC,CA4BxB;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAC3B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,GAAG,EACR,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7B,OAAO,CAAC,aAAa,CAAC,CA4BxB"}
|
|
@@ -12,11 +12,13 @@ const REMOVE_ORDER = [
|
|
|
12
12
|
"context",
|
|
13
13
|
"capacity",
|
|
14
14
|
"territory",
|
|
15
|
+
"relationship",
|
|
15
16
|
"segment",
|
|
16
17
|
"play",
|
|
17
18
|
"agent",
|
|
18
19
|
"mcpServer",
|
|
19
20
|
"tool",
|
|
21
|
+
"customIntegration",
|
|
20
22
|
"worker",
|
|
21
23
|
"app",
|
|
22
24
|
"file",
|
|
@@ -68,6 +70,8 @@ async function remove(api, kind, uuid) {
|
|
|
68
70
|
switch (kind) {
|
|
69
71
|
case "connector":
|
|
70
72
|
return api.connection.connector.remove(uuid);
|
|
73
|
+
case "customIntegration":
|
|
74
|
+
return api.connection.customIntegration.remove(uuid);
|
|
71
75
|
case "model":
|
|
72
76
|
await api.storage.model.remove(uuid);
|
|
73
77
|
return;
|
|
@@ -101,6 +105,35 @@ async function remove(api, kind, uuid) {
|
|
|
101
105
|
// the error is surfaced (destroy prunes dependents first, so a CDK-managed
|
|
102
106
|
// play is already gone by the time its segment is removed).
|
|
103
107
|
return api.segmentation.segment.remove(uuid);
|
|
108
|
+
case "relationship": {
|
|
109
|
+
// No per-uuid delete: the backend `set` endpoint replaces a dataset's
|
|
110
|
+
// relationships. Find this row to learn its dataset, then re-set that
|
|
111
|
+
// dataset's relationships MINUS this one (preserving the rest verbatim).
|
|
112
|
+
const { relationships } = await api.storage.relationship.all();
|
|
113
|
+
const target = relationships.find((r) => r.uuid === uuid);
|
|
114
|
+
if (target === undefined)
|
|
115
|
+
return; // already gone
|
|
116
|
+
const datasetUuid = target.fromDatasetUuid;
|
|
117
|
+
const remaining = relationships
|
|
118
|
+
.filter((r) => r.fromDatasetUuid === datasetUuid && r.uuid !== uuid)
|
|
119
|
+
.map((r) => ({
|
|
120
|
+
uuid: r.uuid,
|
|
121
|
+
fromModelUuid: r.fromModelUuid,
|
|
122
|
+
fromColumnSlug: r.fromColumnSlug,
|
|
123
|
+
fromPropertySlug: r.fromPropertySlug ?? null,
|
|
124
|
+
toModelUuid: r.toModelUuid,
|
|
125
|
+
toColumnSlug: r.toColumnSlug,
|
|
126
|
+
toPropertySlug: r.toPropertySlug ?? null,
|
|
127
|
+
fromSelectedColumnSlugs: r.fromSelectedColumnSlugs ?? null,
|
|
128
|
+
toSelectedColumnSlugs: r.toSelectedColumnSlugs ?? null,
|
|
129
|
+
relation: r.relation,
|
|
130
|
+
}));
|
|
131
|
+
await api.storage.relationship.set({
|
|
132
|
+
datasetUuid,
|
|
133
|
+
relationships: remaining,
|
|
134
|
+
});
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
104
137
|
}
|
|
105
138
|
}
|
|
106
139
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executors.live.d.ts","sourceRoot":"","sources":["../../../src/deploy/executors.live.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAIzC,OAAO,KAAK,EAAE,SAAS,EAAW,MAAM,YAAY,CAAC;AA4BrD,wBAAgB,aAAa,CAAC,GAAG,EAAE,GAAG,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"executors.live.d.ts","sourceRoot":"","sources":["../../../src/deploy/executors.live.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAIzC,OAAO,KAAK,EAAE,SAAS,EAAW,MAAM,YAAY,CAAC;AA4BrD,wBAAgB,aAAa,CAAC,GAAG,EAAE,GAAG,GAAG,SAAS,CAkxBjD"}
|
|
@@ -108,6 +108,11 @@ export function liveExecutors(api) {
|
|
|
108
108
|
const slug = str(spec["slug"]);
|
|
109
109
|
const datasetUuid = str(spec["datasetUuid"]);
|
|
110
110
|
const schedule = spec["schedule"];
|
|
111
|
+
// Unification is not part of CreateModelPayload — it's set through an
|
|
112
|
+
// update, both when the model is first created and on later syncs. Left
|
|
113
|
+
// `undefined` when the spec omits it, so the source's default (integration
|
|
114
|
+
// mapping for connector models) is preserved.
|
|
115
|
+
const unification = spec["unification"];
|
|
111
116
|
if (prior !== undefined) {
|
|
112
117
|
// No extractorSlug — a model's extractor is immutable post-create
|
|
113
118
|
// (it's not part of UpdateModelPayload).
|
|
@@ -117,6 +122,7 @@ export function liveExecutors(api) {
|
|
|
117
122
|
description: optStr(spec["description"]) ?? null,
|
|
118
123
|
config: spec["config"] ?? {},
|
|
119
124
|
schedule: schedule ?? null,
|
|
125
|
+
unification,
|
|
120
126
|
});
|
|
121
127
|
const out = { uuid: prior.uuid };
|
|
122
128
|
if (prior.outputs["adopted"] !== undefined) {
|
|
@@ -131,7 +137,11 @@ export function liveExecutors(api) {
|
|
|
131
137
|
if (found === undefined) {
|
|
132
138
|
throw new Error(`model "${slug}" reported to exist but was not found`);
|
|
133
139
|
}
|
|
134
|
-
// Adopted an existing model —
|
|
140
|
+
// Adopted an existing model — apply the declared unification (create
|
|
141
|
+
// skips it), then release on destroy rather than delete.
|
|
142
|
+
if (unification !== undefined) {
|
|
143
|
+
await api.storage.model.update({ uuid: found.uuid, unification });
|
|
144
|
+
}
|
|
135
145
|
return { uuid: found.uuid, adopted: "true" };
|
|
136
146
|
}
|
|
137
147
|
const created = await api.storage.model.create({
|
|
@@ -144,6 +154,14 @@ export function liveExecutors(api) {
|
|
|
144
154
|
schedule,
|
|
145
155
|
folderUuid: optStr(spec["folderUuid"]),
|
|
146
156
|
});
|
|
157
|
+
// CreateModelPayload has no unification field, so a declared unification
|
|
158
|
+
// is applied with a follow-up update once the model exists.
|
|
159
|
+
if (unification !== undefined) {
|
|
160
|
+
await api.storage.model.update({
|
|
161
|
+
uuid: created.model.uuid,
|
|
162
|
+
unification,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
147
165
|
return { uuid: created.model.uuid };
|
|
148
166
|
},
|
|
149
167
|
async play(spec, prior) {
|
|
@@ -348,13 +366,30 @@ export function liveExecutors(api) {
|
|
|
348
366
|
const created = await api.ai.mcpServer.create(base);
|
|
349
367
|
return { uuid: created.mcpServer.uuid };
|
|
350
368
|
},
|
|
369
|
+
async customIntegration(spec, prior) {
|
|
370
|
+
const workerUuid = str(spec["workerUuid"]);
|
|
371
|
+
if (prior !== undefined) {
|
|
372
|
+
await api.connection.customIntegration.update({
|
|
373
|
+
uuid: prior.uuid,
|
|
374
|
+
workerUuid,
|
|
375
|
+
});
|
|
376
|
+
return { uuid: prior.uuid };
|
|
377
|
+
}
|
|
378
|
+
const created = await api.connection.customIntegration.create({
|
|
379
|
+
kind: "worker",
|
|
380
|
+
workerUuid,
|
|
381
|
+
});
|
|
382
|
+
return { uuid: created.customIntegration.uuid };
|
|
383
|
+
},
|
|
351
384
|
async worker(spec, prior) {
|
|
352
385
|
const files = readBundle(str(spec["path"]));
|
|
353
386
|
const slug = str(spec["slug"]);
|
|
387
|
+
const triggers = mapWorkerTriggers(spec["triggers"]);
|
|
354
388
|
let uuid;
|
|
355
389
|
let adopted = false;
|
|
356
390
|
if (prior !== undefined) {
|
|
357
391
|
uuid = prior.uuid;
|
|
392
|
+
await api.hosting.worker.update({ uuid, triggers });
|
|
358
393
|
}
|
|
359
394
|
else {
|
|
360
395
|
// Recover our own slot if a prior deploy created it but crashed before
|
|
@@ -367,6 +402,7 @@ export function liveExecutors(api) {
|
|
|
367
402
|
if (existing !== undefined) {
|
|
368
403
|
uuid = existing.uuid;
|
|
369
404
|
adopted = true;
|
|
405
|
+
await api.hosting.worker.update({ uuid, triggers });
|
|
370
406
|
}
|
|
371
407
|
else {
|
|
372
408
|
uuid = (await api.hosting.worker.create({
|
|
@@ -374,9 +410,11 @@ export function liveExecutors(api) {
|
|
|
374
410
|
slug,
|
|
375
411
|
description: optStr(spec["description"]) ?? null,
|
|
376
412
|
folderUuid: optStr(spec["folderUuid"]),
|
|
413
|
+
triggers,
|
|
377
414
|
})).worker.uuid;
|
|
378
415
|
}
|
|
379
416
|
}
|
|
417
|
+
await syncEnvVars(api, { kind: "worker", workerUuid: uuid }, spec["env"]);
|
|
380
418
|
const { deployment } = await api.hosting.deployment.create({
|
|
381
419
|
kind: "worker",
|
|
382
420
|
workerUuid: uuid,
|
|
@@ -424,6 +462,7 @@ export function liveExecutors(api) {
|
|
|
424
462
|
})).app.uuid;
|
|
425
463
|
}
|
|
426
464
|
}
|
|
465
|
+
await syncEnvVars(api, { kind: "app", appUuid: uuid }, spec["env"]);
|
|
427
466
|
const { deployment } = await api.hosting.deployment.create({
|
|
428
467
|
kind: "app",
|
|
429
468
|
appUuid: uuid,
|
|
@@ -619,6 +658,72 @@ export function liveExecutors(api) {
|
|
|
619
658
|
});
|
|
620
659
|
return { uuid: created.segment.uuid };
|
|
621
660
|
},
|
|
661
|
+
// A relationship joins two models within one dataset. The backend `set`
|
|
662
|
+
// endpoint is a per-dataset declarative REPLACE (rows absent from the
|
|
663
|
+
// payload are deleted), so this executor read-merges: it lists the dataset's
|
|
664
|
+
// live relationships, preserves every OTHER row (by uuid), and upserts this
|
|
665
|
+
// one. No server slug → identity is prior.uuid; a fresh row is reconciled by
|
|
666
|
+
// matching its join fields in the response. The dataset is derived from the
|
|
667
|
+
// `from` model. Sequential apply means a later relationship on the same
|
|
668
|
+
// dataset sees the rows earlier ones just created.
|
|
669
|
+
async relationship(spec, prior) {
|
|
670
|
+
const fromModelUuid = str(spec["fromModelUuid"]);
|
|
671
|
+
const { model } = await api.storage.model.get(fromModelUuid);
|
|
672
|
+
const datasetUuid = model.datasetUuid;
|
|
673
|
+
const row = {
|
|
674
|
+
fromModelUuid,
|
|
675
|
+
fromColumnSlug: str(spec["fromColumnSlug"]),
|
|
676
|
+
fromPropertySlug: optStr(spec["fromPropertySlug"]) ?? null,
|
|
677
|
+
toModelUuid: str(spec["toModelUuid"]),
|
|
678
|
+
toColumnSlug: str(spec["toColumnSlug"]),
|
|
679
|
+
toPropertySlug: optStr(spec["toPropertySlug"]) ?? null,
|
|
680
|
+
fromSelectedColumnSlugs: null,
|
|
681
|
+
toSelectedColumnSlugs: null,
|
|
682
|
+
relation: spec["relation"],
|
|
683
|
+
};
|
|
684
|
+
const { relationships } = await api.storage.relationship.all();
|
|
685
|
+
// Every row in this dataset except the one we manage — kept verbatim (with
|
|
686
|
+
// its uuid) so `set` updates it in place rather than deleting it.
|
|
687
|
+
const others = relationships
|
|
688
|
+
.filter((r) => r.fromDatasetUuid === datasetUuid && r.uuid !== prior?.uuid)
|
|
689
|
+
.map(toSetInput);
|
|
690
|
+
const ours = prior === undefined ? row : { ...row, uuid: prior.uuid };
|
|
691
|
+
const { relationships: after } = await api.storage.relationship.set({
|
|
692
|
+
datasetUuid,
|
|
693
|
+
relationships: [...others, ours],
|
|
694
|
+
});
|
|
695
|
+
if (prior !== undefined)
|
|
696
|
+
return { uuid: prior.uuid };
|
|
697
|
+
const created = after.find((r) => r.fromModelUuid === row.fromModelUuid &&
|
|
698
|
+
r.toModelUuid === row.toModelUuid &&
|
|
699
|
+
r.fromColumnSlug === row.fromColumnSlug &&
|
|
700
|
+
r.toColumnSlug === row.toColumnSlug &&
|
|
701
|
+
r.fromPropertySlug === row.fromPropertySlug &&
|
|
702
|
+
r.toPropertySlug === row.toPropertySlug &&
|
|
703
|
+
r.relation === row.relation);
|
|
704
|
+
if (created === undefined) {
|
|
705
|
+
throw new Error(`relationship was set but not found in the dataset's relationships`);
|
|
706
|
+
}
|
|
707
|
+
return { uuid: created.uuid };
|
|
708
|
+
},
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
// Project a live relationship into a `set` payload entry: drop the
|
|
712
|
+
// dataset-scoped fields (derived server-side, not author-set) but KEEP its uuid
|
|
713
|
+
// so `set` updates it in place instead of deleting it. `all()` returns nullable
|
|
714
|
+
// fields as `undefined` while `set()` expects `null`, so normalize each here.
|
|
715
|
+
function toSetInput(relationship) {
|
|
716
|
+
return {
|
|
717
|
+
uuid: relationship.uuid,
|
|
718
|
+
fromModelUuid: relationship.fromModelUuid,
|
|
719
|
+
fromColumnSlug: relationship.fromColumnSlug,
|
|
720
|
+
fromPropertySlug: relationship.fromPropertySlug ?? null,
|
|
721
|
+
toModelUuid: relationship.toModelUuid,
|
|
722
|
+
toColumnSlug: relationship.toColumnSlug,
|
|
723
|
+
toPropertySlug: relationship.toPropertySlug ?? null,
|
|
724
|
+
fromSelectedColumnSlugs: relationship.fromSelectedColumnSlugs ?? null,
|
|
725
|
+
toSelectedColumnSlugs: relationship.toSelectedColumnSlugs ?? null,
|
|
726
|
+
relation: relationship.relation,
|
|
622
727
|
};
|
|
623
728
|
}
|
|
624
729
|
// Carry the "adopted" marker forward across an update so destroy keeps releasing
|
|
@@ -707,6 +812,57 @@ function mapToolTriggers(value) {
|
|
|
707
812
|
data: t.data === undefined ? {} : t.data,
|
|
708
813
|
}));
|
|
709
814
|
}
|
|
815
|
+
// Upsert the spec's env vars before the build (values are baked into the
|
|
816
|
+
// bundle at build time). `secret("X")` values arrive as the encryption
|
|
817
|
+
// envelope after resolveSecrets and become secret env vars. Keys removed
|
|
818
|
+
// from the spec are left in place; secret values read back as null, so
|
|
819
|
+
// they are re-sent on every apply.
|
|
820
|
+
async function syncEnvVars(api, subject, value) {
|
|
821
|
+
const env = value;
|
|
822
|
+
const entries = Object.entries(env ?? {});
|
|
823
|
+
if (entries.length === 0)
|
|
824
|
+
return;
|
|
825
|
+
const { envVars } = await api.hosting.envVars.list(subject.kind === "worker"
|
|
826
|
+
? { workerUuid: subject.workerUuid }
|
|
827
|
+
: { appUuid: subject.appUuid });
|
|
828
|
+
for (const [key, raw] of entries) {
|
|
829
|
+
const isSecret = typeof raw !== "string";
|
|
830
|
+
const varValue = typeof raw === "string" ? raw : raw.value;
|
|
831
|
+
const existing = envVars.find((envVar) => envVar.key === key);
|
|
832
|
+
if (existing === undefined) {
|
|
833
|
+
await api.hosting.envVars.create({
|
|
834
|
+
...subject,
|
|
835
|
+
key,
|
|
836
|
+
value: varValue,
|
|
837
|
+
isSecret,
|
|
838
|
+
});
|
|
839
|
+
}
|
|
840
|
+
else if (existing.value !== varValue || existing.isSecret !== isSecret) {
|
|
841
|
+
await api.hosting.envVars.update({
|
|
842
|
+
uuid: existing.uuid,
|
|
843
|
+
value: varValue,
|
|
844
|
+
isSecret,
|
|
845
|
+
});
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
// Always an array (unlike tools): sending [] on update clears triggers
|
|
850
|
+
// removed from the spec.
|
|
851
|
+
function mapWorkerTriggers(value) {
|
|
852
|
+
const triggers = value;
|
|
853
|
+
if (triggers === undefined)
|
|
854
|
+
return [];
|
|
855
|
+
return triggers.map((t) => ({
|
|
856
|
+
type: "cron",
|
|
857
|
+
name: t.name === undefined ? t.path : t.name,
|
|
858
|
+
description: t.description,
|
|
859
|
+
cron: t.cron,
|
|
860
|
+
path: t.path,
|
|
861
|
+
method: t.method === undefined ? "POST" : t.method,
|
|
862
|
+
data: t.data,
|
|
863
|
+
headers: t.headers,
|
|
864
|
+
}));
|
|
865
|
+
}
|
|
710
866
|
function mapAgentTriggers(value) {
|
|
711
867
|
// triggers are optional on both agent.create and agent.update — omit the key
|
|
712
868
|
// entirely when there are none rather than sending an empty array.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readers.live.d.ts","sourceRoot":"","sources":["../../../src/deploy/readers.live.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,EAA8B,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAoD5E,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,WAAW,
|
|
1
|
+
{"version":3,"file":"readers.live.d.ts","sourceRoot":"","sources":["../../../src/deploy/readers.live.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,EAA8B,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAoD5E,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,WAAW,CA2TjD"}
|
|
@@ -228,6 +228,17 @@ export function liveReaders(api) {
|
|
|
228
228
|
return goneOrThrow(error);
|
|
229
229
|
}
|
|
230
230
|
},
|
|
231
|
+
async customIntegration(entry) {
|
|
232
|
+
try {
|
|
233
|
+
const { connector } = await api.connection.customIntegration.get({
|
|
234
|
+
uuid: entry.uuid,
|
|
235
|
+
});
|
|
236
|
+
return present(pick(connector, ["kind", "workerUuid"]));
|
|
237
|
+
}
|
|
238
|
+
catch (error) {
|
|
239
|
+
return goneOrThrow(error);
|
|
240
|
+
}
|
|
241
|
+
},
|
|
231
242
|
async worker(entry) {
|
|
232
243
|
try {
|
|
233
244
|
const { worker } = await api.hosting.worker.get(entry.uuid);
|
|
@@ -237,7 +248,7 @@ export function liveReaders(api) {
|
|
|
237
248
|
? undefined
|
|
238
249
|
: promoted["meta"];
|
|
239
250
|
return present({
|
|
240
|
-
...pick(w, ["name", "description", "slug", "folderUuid"]),
|
|
251
|
+
...pick(w, ["name", "description", "slug", "folderUuid", "triggers"]),
|
|
241
252
|
bundle: meta === undefined ? undefined : meta["bundleSha256"],
|
|
242
253
|
outboundAllowlist: meta === undefined ? undefined : meta["outboundAllowlist"],
|
|
243
254
|
});
|
|
@@ -314,5 +325,27 @@ export function liveReaders(api) {
|
|
|
314
325
|
return goneOrThrow(error);
|
|
315
326
|
}
|
|
316
327
|
},
|
|
328
|
+
// No per-uuid get — list all and find by the state uuid. Fingerprint only
|
|
329
|
+
// the join fields the executor reconciles.
|
|
330
|
+
async relationship(entry) {
|
|
331
|
+
try {
|
|
332
|
+
const { relationships } = await api.storage.relationship.all();
|
|
333
|
+
const found = relationships.find((r) => r.uuid === entry.uuid);
|
|
334
|
+
if (found === undefined)
|
|
335
|
+
return GONE;
|
|
336
|
+
return present(pick(found, [
|
|
337
|
+
"fromModelUuid",
|
|
338
|
+
"fromColumnSlug",
|
|
339
|
+
"fromPropertySlug",
|
|
340
|
+
"toModelUuid",
|
|
341
|
+
"toColumnSlug",
|
|
342
|
+
"toPropertySlug",
|
|
343
|
+
"relation",
|
|
344
|
+
]));
|
|
345
|
+
}
|
|
346
|
+
catch (error) {
|
|
347
|
+
return goneOrThrow(error);
|
|
348
|
+
}
|
|
349
|
+
},
|
|
317
350
|
};
|
|
318
351
|
}
|