@x12i/memorix-service 3.1.0 → 3.2.1
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/dist/ai-services/associate-prep.d.ts +37 -0
- package/dist/ai-services/associate-prep.d.ts.map +1 -0
- package/dist/ai-services/associate-prep.js +208 -0
- package/dist/ai-services/associate-prep.js.map +1 -0
- package/dist/ai-services/chunk-markdown.d.ts +22 -0
- package/dist/ai-services/chunk-markdown.d.ts.map +1 -0
- package/dist/ai-services/chunk-markdown.js +159 -0
- package/dist/ai-services/chunk-markdown.js.map +1 -0
- package/dist/ai-services/client.d.ts +1 -1
- package/dist/ai-services/client.d.ts.map +1 -1
- package/dist/ai-services/client.js +2 -2
- package/dist/ai-services/client.js.map +1 -1
- package/dist/ai-services/normalize-output.d.ts +7 -1
- package/dist/ai-services/normalize-output.d.ts.map +1 -1
- package/dist/ai-services/normalize-output.js +340 -60
- package/dist/ai-services/normalize-output.js.map +1 -1
- package/dist/ai-services/skill-execution.d.ts +3 -2
- package/dist/ai-services/skill-execution.d.ts.map +1 -1
- package/dist/ai-services/skill-execution.js +24 -4
- package/dist/ai-services/skill-execution.js.map +1 -1
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +4 -0
- package/dist/app.js.map +1 -1
- package/dist/connector-catalog.d.ts +79 -0
- package/dist/connector-catalog.d.ts.map +1 -0
- package/dist/connector-catalog.js +286 -0
- package/dist/connector-catalog.js.map +1 -0
- package/dist/connector-role.d.ts +22 -0
- package/dist/connector-role.d.ts.map +1 -0
- package/dist/connector-role.js +71 -0
- package/dist/connector-role.js.map +1 -0
- package/dist/destination-runtime.d.ts +8 -0
- package/dist/destination-runtime.d.ts.map +1 -0
- package/dist/destination-runtime.js +11 -0
- package/dist/destination-runtime.js.map +1 -0
- package/dist/execution-target.d.ts +141 -0
- package/dist/execution-target.d.ts.map +1 -0
- package/dist/execution-target.js +853 -0
- package/dist/execution-target.js.map +1 -0
- package/dist/generic-connectors.d.ts +43 -0
- package/dist/generic-connectors.d.ts.map +1 -0
- package/dist/generic-connectors.js +198 -0
- package/dist/generic-connectors.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/jobs-scope.d.ts +21 -0
- package/dist/jobs-scope.d.ts.map +1 -0
- package/dist/jobs-scope.js +83 -0
- package/dist/jobs-scope.js.map +1 -0
- package/dist/live.d.ts +11 -0
- package/dist/live.d.ts.map +1 -1
- package/dist/live.js +700 -73
- package/dist/live.js.map +1 -1
- package/dist/magit/magit-pack-service.d.ts +80 -0
- package/dist/magit/magit-pack-service.d.ts.map +1 -1
- package/dist/magit/magit-pack-service.js +233 -11
- package/dist/magit/magit-pack-service.js.map +1 -1
- package/dist/magit/pack-to-patchset.d.ts +16 -0
- package/dist/magit/pack-to-patchset.d.ts.map +1 -1
- package/dist/magit/pack-to-patchset.js +46 -0
- package/dist/magit/pack-to-patchset.js.map +1 -1
- package/dist/magit/package-catalog-bridge.d.ts +5 -5
- package/dist/magit/package-catalog-bridge.d.ts.map +1 -1
- package/dist/magit/package-catalog-bridge.js +3 -3
- package/dist/magit/package-catalog-bridge.js.map +1 -1
- package/dist/mgc-packages.d.ts +11 -0
- package/dist/mgc-packages.d.ts.map +1 -0
- package/dist/mgc-packages.js +11 -0
- package/dist/mgc-packages.js.map +1 -0
- package/dist/openapi/openapi.json +3445 -791
- package/dist/pipeline-compile.d.ts +46 -3
- package/dist/pipeline-compile.d.ts.map +1 -1
- package/dist/pipeline-compile.js +455 -89
- package/dist/pipeline-compile.js.map +1 -1
- package/dist/pipeline-invoke.d.ts +63 -0
- package/dist/pipeline-invoke.d.ts.map +1 -0
- package/dist/pipeline-invoke.js +114 -0
- package/dist/pipeline-invoke.js.map +1 -0
- package/dist/pipeline-ports.d.ts +13 -0
- package/dist/pipeline-ports.d.ts.map +1 -0
- package/dist/pipeline-ports.js +104 -0
- package/dist/pipeline-ports.js.map +1 -0
- package/dist/platform.d.ts +30 -1
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +239 -8
- package/dist/platform.js.map +1 -1
- package/dist/routes/connector-invocations.d.ts.map +1 -1
- package/dist/routes/connector-invocations.js +18 -21
- package/dist/routes/connector-invocations.js.map +1 -1
- package/dist/routes/jobs.d.ts +4 -0
- package/dist/routes/jobs.d.ts.map +1 -0
- package/dist/routes/jobs.js +888 -0
- package/dist/routes/jobs.js.map +1 -0
- package/dist/routes/memory.d.ts.map +1 -1
- package/dist/routes/memory.js +148 -79
- package/dist/routes/memory.js.map +1 -1
- package/dist/routes/metadata.d.ts.map +1 -1
- package/dist/routes/metadata.js +171 -40
- package/dist/routes/metadata.js.map +1 -1
- package/dist/routes/pipelines.d.ts.map +1 -1
- package/dist/routes/pipelines.js +98 -22
- package/dist/routes/pipelines.js.map +1 -1
- package/dist/routes/relationships.d.ts.map +1 -1
- package/dist/routes/relationships.js +80 -2
- package/dist/routes/relationships.js.map +1 -1
- package/dist/runx/client.d.ts +18 -0
- package/dist/runx/client.d.ts.map +1 -0
- package/dist/runx/client.js +59 -0
- package/dist/runx/client.js.map +1 -0
- package/openapi/openapi.json +3445 -791
- package/package.json +16 -9
|
@@ -0,0 +1,853 @@
|
|
|
1
|
+
import { AI_SERVICE_ORIGIN_SPECS, defaultEndpointEnvForType, resolveAiServiceOriginUrl, resolveConfiguredAiServiceOrigins, } from "./ai-services/config.js";
|
|
2
|
+
import { createAiServicesClient } from "./ai-services/client.js";
|
|
3
|
+
import { compileAuthoringPipeline, resolveKnowxWorkerBaseUrl, } from "./pipeline-compile.js";
|
|
4
|
+
import { listUnifiedConnectors } from "./connector-catalog.js";
|
|
5
|
+
import { loadGenericConnectorsConfig } from "./generic-connectors.js";
|
|
6
|
+
export { classifyConnectorRole, normalizeCapabilityKeys, } from "./connector-role.js";
|
|
7
|
+
const SYNTHETIC_PREFIX = "jm:";
|
|
8
|
+
// Remove old local role helpers — re-exported from connector-role.ts above.
|
|
9
|
+
export function isSyntheticPipelineId(pipelineId) {
|
|
10
|
+
return pipelineId.startsWith(SYNTHETIC_PREFIX);
|
|
11
|
+
}
|
|
12
|
+
export function syntheticPipelineId(target) {
|
|
13
|
+
switch (target.kind) {
|
|
14
|
+
case "pipeline":
|
|
15
|
+
return target.pipelineId;
|
|
16
|
+
case "connector":
|
|
17
|
+
return `${SYNTHETIC_PREFIX}connector:${encodeURIComponent(target.connectorId)}:${encodeURIComponent(target.sourceId)}`;
|
|
18
|
+
case "destination":
|
|
19
|
+
return `${SYNTHETIC_PREFIX}destination:${encodeURIComponent(target.connectorId)}:${encodeURIComponent(target.destinationId)}`;
|
|
20
|
+
case "service":
|
|
21
|
+
return `${SYNTHETIC_PREFIX}service:${encodeURIComponent(target.serviceId)}`;
|
|
22
|
+
case "ai-service":
|
|
23
|
+
return `${SYNTHETIC_PREFIX}ai:${encodeURIComponent(target.aiServiceType)}:${encodeURIComponent(target.itemId)}`;
|
|
24
|
+
case "runx":
|
|
25
|
+
return `${SYNTHETIC_PREFIX}runx:${encodeURIComponent(target.capabilityId)}`;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export function parseSyntheticPipelineId(pipelineId) {
|
|
29
|
+
if (!isSyntheticPipelineId(pipelineId))
|
|
30
|
+
return null;
|
|
31
|
+
const rest = pipelineId.slice(SYNTHETIC_PREFIX.length);
|
|
32
|
+
const [kind, ...parts] = rest.split(":");
|
|
33
|
+
if (kind === "connector" && parts.length >= 2) {
|
|
34
|
+
const connectorId = decodeURIComponent(parts[0] ?? "");
|
|
35
|
+
const sourceId = decodeURIComponent(parts.slice(1).join(":"));
|
|
36
|
+
if (!connectorId || !sourceId)
|
|
37
|
+
return null;
|
|
38
|
+
return { kind: "connector", connectorId, sourceId };
|
|
39
|
+
}
|
|
40
|
+
if (kind === "destination" && parts.length >= 2) {
|
|
41
|
+
const connectorId = decodeURIComponent(parts[0] ?? "");
|
|
42
|
+
const destinationId = decodeURIComponent(parts.slice(1).join(":"));
|
|
43
|
+
if (!connectorId || !destinationId)
|
|
44
|
+
return null;
|
|
45
|
+
return { kind: "destination", connectorId, destinationId };
|
|
46
|
+
}
|
|
47
|
+
if (kind === "service" && parts.length >= 1) {
|
|
48
|
+
const serviceId = decodeURIComponent(parts.join(":"));
|
|
49
|
+
if (!serviceId)
|
|
50
|
+
return null;
|
|
51
|
+
return { kind: "service", serviceId };
|
|
52
|
+
}
|
|
53
|
+
if (kind === "ai" && parts.length >= 2) {
|
|
54
|
+
const aiServiceType = decodeURIComponent(parts[0] ?? "");
|
|
55
|
+
const itemId = decodeURIComponent(parts.slice(1).join(":"));
|
|
56
|
+
if (!aiServiceType || !itemId)
|
|
57
|
+
return null;
|
|
58
|
+
return { kind: "ai-service", aiServiceType, itemId };
|
|
59
|
+
}
|
|
60
|
+
if (kind === "runx" && parts.length >= 1) {
|
|
61
|
+
const capabilityId = decodeURIComponent(parts.join(":"));
|
|
62
|
+
if (!capabilityId)
|
|
63
|
+
return null;
|
|
64
|
+
return { kind: "runx", capabilityId };
|
|
65
|
+
}
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
function asRecord(value) {
|
|
69
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
70
|
+
? value
|
|
71
|
+
: null;
|
|
72
|
+
}
|
|
73
|
+
/** Parse body.executionTarget or legacy body.pipelineId. */
|
|
74
|
+
export function parseExecutionTarget(body) {
|
|
75
|
+
const rec = asRecord(body) ?? {};
|
|
76
|
+
const target = asRecord(rec.executionTarget) ?? asRecord(rec.target);
|
|
77
|
+
if (target) {
|
|
78
|
+
const kind = String(target.kind ?? "").trim();
|
|
79
|
+
if (kind === "pipeline") {
|
|
80
|
+
const pipelineId = String(target.pipelineId ?? "").trim();
|
|
81
|
+
if (!pipelineId)
|
|
82
|
+
throw new Error("executionTarget.pipelineId required");
|
|
83
|
+
return { kind: "pipeline", pipelineId };
|
|
84
|
+
}
|
|
85
|
+
if (kind === "connector") {
|
|
86
|
+
const connectorId = String(target.connectorId ?? "").trim();
|
|
87
|
+
const sourceId = String(target.sourceId ?? "").trim();
|
|
88
|
+
if (!connectorId)
|
|
89
|
+
throw new Error("executionTarget.connectorId required");
|
|
90
|
+
if (!sourceId) {
|
|
91
|
+
throw new Error("executionTarget.sourceId required (connector needs a configured source)");
|
|
92
|
+
}
|
|
93
|
+
return { kind: "connector", connectorId, sourceId };
|
|
94
|
+
}
|
|
95
|
+
if (kind === "destination") {
|
|
96
|
+
const connectorId = String(target.connectorId ?? "").trim();
|
|
97
|
+
const destinationId = String(target.destinationId ?? "").trim();
|
|
98
|
+
if (!connectorId)
|
|
99
|
+
throw new Error("executionTarget.connectorId required");
|
|
100
|
+
if (!destinationId) {
|
|
101
|
+
throw new Error("executionTarget.destinationId required (destination needs a configured destination)");
|
|
102
|
+
}
|
|
103
|
+
return { kind: "destination", connectorId, destinationId };
|
|
104
|
+
}
|
|
105
|
+
if (kind === "service") {
|
|
106
|
+
const serviceId = String(target.serviceId ?? "").trim();
|
|
107
|
+
if (!serviceId)
|
|
108
|
+
throw new Error("executionTarget.serviceId required");
|
|
109
|
+
return { kind: "service", serviceId };
|
|
110
|
+
}
|
|
111
|
+
if (kind === "ai-service" || kind === "ai") {
|
|
112
|
+
const aiServiceType = String(target.aiServiceType ?? "").trim();
|
|
113
|
+
const itemId = String(target.itemId ?? "").trim();
|
|
114
|
+
if (!aiServiceType)
|
|
115
|
+
throw new Error("executionTarget.aiServiceType required");
|
|
116
|
+
if (!itemId)
|
|
117
|
+
throw new Error("executionTarget.itemId required");
|
|
118
|
+
return { kind: "ai-service", aiServiceType, itemId };
|
|
119
|
+
}
|
|
120
|
+
if (kind === "runx") {
|
|
121
|
+
const capabilityId = String(target.capabilityId ?? "").trim();
|
|
122
|
+
if (!capabilityId)
|
|
123
|
+
throw new Error("executionTarget.capabilityId required");
|
|
124
|
+
return { kind: "runx", capabilityId };
|
|
125
|
+
}
|
|
126
|
+
throw new Error(`unsupported executionTarget.kind "${kind}"`);
|
|
127
|
+
}
|
|
128
|
+
const pipelineId = String(rec.pipelineId ?? "").trim();
|
|
129
|
+
if (pipelineId)
|
|
130
|
+
return { kind: "pipeline", pipelineId };
|
|
131
|
+
throw new Error("executionTarget or pipelineId required");
|
|
132
|
+
}
|
|
133
|
+
export function buildSyntheticAuthoringDefinition(target, opts) {
|
|
134
|
+
const pipelineId = syntheticPipelineId(target);
|
|
135
|
+
if (target.kind === "pipeline") {
|
|
136
|
+
throw new Error("buildSyntheticAuthoringDefinition requires a non-pipeline target");
|
|
137
|
+
}
|
|
138
|
+
if (target.kind === "connector") {
|
|
139
|
+
return {
|
|
140
|
+
id: pipelineId,
|
|
141
|
+
pipelineId,
|
|
142
|
+
name: opts?.sourceName
|
|
143
|
+
? `Pull ${opts.sourceName}`
|
|
144
|
+
: `Pull ${target.sourceId}`,
|
|
145
|
+
version: "1",
|
|
146
|
+
trigger: "on-demand",
|
|
147
|
+
steps: [
|
|
148
|
+
{
|
|
149
|
+
id: "pull",
|
|
150
|
+
kind: "memory-pull",
|
|
151
|
+
sourceId: target.sourceId,
|
|
152
|
+
portConfig: {
|
|
153
|
+
sourceId: target.sourceId,
|
|
154
|
+
connectorId: target.connectorId,
|
|
155
|
+
mode: "knowledge",
|
|
156
|
+
trigger: "on-demand",
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
if (target.kind === "destination") {
|
|
163
|
+
return {
|
|
164
|
+
id: pipelineId,
|
|
165
|
+
pipelineId,
|
|
166
|
+
name: opts?.sourceName
|
|
167
|
+
? `Deliver ${opts.sourceName}`
|
|
168
|
+
: `Deliver ${target.destinationId}`,
|
|
169
|
+
version: "1",
|
|
170
|
+
trigger: "on-demand",
|
|
171
|
+
steps: [
|
|
172
|
+
{
|
|
173
|
+
id: "deliver",
|
|
174
|
+
kind: "analyze",
|
|
175
|
+
serviceId: `dest:${target.connectorId}:${target.destinationId}`,
|
|
176
|
+
portConfig: {
|
|
177
|
+
invokeProtocol: "memorix-destination/1",
|
|
178
|
+
connectorId: target.connectorId,
|
|
179
|
+
destinationId: target.destinationId,
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
],
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
if (target.kind === "service") {
|
|
186
|
+
const svc = (opts?.serviceDefs ?? []).find((s) => String(s.serviceId ?? s.id ?? "").trim() === target.serviceId);
|
|
187
|
+
const caps = Array.isArray(svc?.capabilities)
|
|
188
|
+
? (svc.capabilities)
|
|
189
|
+
: [];
|
|
190
|
+
const kind = caps.includes("analyze") || caps.includes("enrich")
|
|
191
|
+
? caps.includes("enrich")
|
|
192
|
+
? "enrich"
|
|
193
|
+
: "analyze"
|
|
194
|
+
: "analyze";
|
|
195
|
+
return {
|
|
196
|
+
id: pipelineId,
|
|
197
|
+
pipelineId,
|
|
198
|
+
name: opts?.serviceName ?? target.serviceId,
|
|
199
|
+
version: "1",
|
|
200
|
+
trigger: "on-demand",
|
|
201
|
+
steps: [
|
|
202
|
+
{
|
|
203
|
+
id: "invoke",
|
|
204
|
+
kind,
|
|
205
|
+
serviceId: target.serviceId,
|
|
206
|
+
},
|
|
207
|
+
],
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
if (target.kind === "runx") {
|
|
211
|
+
return {
|
|
212
|
+
id: pipelineId,
|
|
213
|
+
pipelineId,
|
|
214
|
+
name: `Runx ${target.capabilityId}`,
|
|
215
|
+
version: "1",
|
|
216
|
+
trigger: "on-demand",
|
|
217
|
+
steps: [
|
|
218
|
+
{
|
|
219
|
+
id: "runx",
|
|
220
|
+
kind: "runx",
|
|
221
|
+
capabilityId: target.capabilityId,
|
|
222
|
+
portConfig: {
|
|
223
|
+
capabilityId: target.capabilityId,
|
|
224
|
+
invokeProtocol: "runx/1",
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
],
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
// ai-service
|
|
231
|
+
return {
|
|
232
|
+
id: pipelineId,
|
|
233
|
+
pipelineId,
|
|
234
|
+
name: opts?.itemTitle ?? `${target.aiServiceType}/${target.itemId}`,
|
|
235
|
+
version: "1",
|
|
236
|
+
trigger: "on-demand",
|
|
237
|
+
steps: [
|
|
238
|
+
{
|
|
239
|
+
id: "invoke",
|
|
240
|
+
kind: "analyze",
|
|
241
|
+
serviceId: `ai:${target.aiServiceType}:${target.itemId}`,
|
|
242
|
+
aiService: {
|
|
243
|
+
aiServiceType: target.aiServiceType,
|
|
244
|
+
itemId: target.itemId,
|
|
245
|
+
endpointEnv: defaultEndpointEnvForType(target.aiServiceType),
|
|
246
|
+
},
|
|
247
|
+
portConfig: {
|
|
248
|
+
aiServiceType: target.aiServiceType,
|
|
249
|
+
itemId: target.itemId,
|
|
250
|
+
invokeProtocol: "ai-services/1",
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
],
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
function serviceDefsFromEffective(platform, agentIds) {
|
|
257
|
+
const effective = platform.metadata.resolveEffective(agentIds);
|
|
258
|
+
return (effective.effective ?? [])
|
|
259
|
+
.filter((e) => e.kind === "services")
|
|
260
|
+
.map((e) => e.definition);
|
|
261
|
+
}
|
|
262
|
+
function compileWithServices(platform, agentIds, definition) {
|
|
263
|
+
const serviceDefs = serviceDefsFromEffective(platform, agentIds);
|
|
264
|
+
const knownServiceIds = new Set(serviceDefs
|
|
265
|
+
.map((s) => String(s.serviceId ?? s.id ?? "").trim())
|
|
266
|
+
.filter(Boolean));
|
|
267
|
+
// Allow synthetic AI service ids through validation.
|
|
268
|
+
for (const step of (definition
|
|
269
|
+
.steps ?? [])) {
|
|
270
|
+
if (step.serviceId)
|
|
271
|
+
knownServiceIds.add(step.serviceId);
|
|
272
|
+
}
|
|
273
|
+
return compileAuthoringPipeline(definition, {
|
|
274
|
+
knownServiceIds,
|
|
275
|
+
workerBaseUrl: resolveKnowxWorkerBaseUrl(),
|
|
276
|
+
serviceDefs,
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
function findSource(platform, agentIds, orgId, sourceId) {
|
|
280
|
+
const effective = platform.metadata.resolveEffective(agentIds);
|
|
281
|
+
const pack = (effective.effective ?? []).find((e) => e.kind === "sources" && e.id === sourceId);
|
|
282
|
+
if (pack) {
|
|
283
|
+
const d = pack.definition;
|
|
284
|
+
return {
|
|
285
|
+
definition: d,
|
|
286
|
+
connectorRef: typeof d.connectorRef === "string"
|
|
287
|
+
? d.connectorRef
|
|
288
|
+
: typeof d.kind === "string"
|
|
289
|
+
? d.kind
|
|
290
|
+
: undefined,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
async function findSourceIncludingOrg(platform, agentIds, orgId, sourceId) {
|
|
296
|
+
const pack = findSource(platform, agentIds, orgId, sourceId);
|
|
297
|
+
if (pack)
|
|
298
|
+
return pack;
|
|
299
|
+
if (!orgId)
|
|
300
|
+
return null;
|
|
301
|
+
const orgRows = await platform.orgRuntimeSourcesFor(orgId).list({ agentIds });
|
|
302
|
+
const row = orgRows.find((r) => r.sourceId === sourceId);
|
|
303
|
+
if (!row)
|
|
304
|
+
return null;
|
|
305
|
+
const d = row.definition;
|
|
306
|
+
return {
|
|
307
|
+
definition: d,
|
|
308
|
+
connectorRef: typeof d.connectorRef === "string"
|
|
309
|
+
? d.connectorRef
|
|
310
|
+
: typeof d.kind === "string"
|
|
311
|
+
? d.kind
|
|
312
|
+
: row.origin,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
export async function resolveExecutionTarget(platform, opts) {
|
|
316
|
+
const { agentIds, orgId, target } = opts;
|
|
317
|
+
if (target.kind === "pipeline") {
|
|
318
|
+
const raw = platform.metadata.getDefinition(agentIds, "pipelines", target.pipelineId)?.definition;
|
|
319
|
+
if (!raw) {
|
|
320
|
+
throw new Error(`pipeline ${target.pipelineId} not found`);
|
|
321
|
+
}
|
|
322
|
+
const compiled = compileWithServices(platform, agentIds, raw);
|
|
323
|
+
const name = typeof raw.name === "string"
|
|
324
|
+
? String(raw.name)
|
|
325
|
+
: target.pipelineId;
|
|
326
|
+
return {
|
|
327
|
+
target,
|
|
328
|
+
pipelineId: compiled.pipelineId || target.pipelineId,
|
|
329
|
+
compiled,
|
|
330
|
+
label: name,
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
if (target.kind === "connector") {
|
|
334
|
+
const source = await findSourceIncludingOrg(platform, agentIds, orgId, target.sourceId);
|
|
335
|
+
if (!source) {
|
|
336
|
+
throw new Error(`source ${target.sourceId} not found`);
|
|
337
|
+
}
|
|
338
|
+
const ref = source.connectorRef ?? "";
|
|
339
|
+
if (ref && ref !== target.connectorId) {
|
|
340
|
+
throw new Error(`source ${target.sourceId} is bound to connector ${ref}, not ${target.connectorId}`);
|
|
341
|
+
}
|
|
342
|
+
const sourceName = typeof source.definition.name === "string"
|
|
343
|
+
? source.definition.name
|
|
344
|
+
: target.sourceId;
|
|
345
|
+
const authoring = buildSyntheticAuthoringDefinition(target, {
|
|
346
|
+
sourceName,
|
|
347
|
+
serviceDefs: serviceDefsFromEffective(platform, agentIds),
|
|
348
|
+
});
|
|
349
|
+
const compiled = compileWithServices(platform, agentIds, authoring);
|
|
350
|
+
// Ensure portConfig keeps sourceId after compile.
|
|
351
|
+
const step = compiled.steps[0];
|
|
352
|
+
if (step) {
|
|
353
|
+
step.portConfig = {
|
|
354
|
+
...(step.portConfig ?? {}),
|
|
355
|
+
sourceId: target.sourceId,
|
|
356
|
+
connectorId: target.connectorId,
|
|
357
|
+
mode: "knowledge",
|
|
358
|
+
trigger: "on-demand",
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
return {
|
|
362
|
+
target,
|
|
363
|
+
pipelineId: syntheticPipelineId(target),
|
|
364
|
+
compiled: { ...compiled, pipelineId: syntheticPipelineId(target) },
|
|
365
|
+
label: sourceName,
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
if (target.kind === "destination") {
|
|
369
|
+
if (!orgId) {
|
|
370
|
+
throw new Error("orgId required for destination execution target");
|
|
371
|
+
}
|
|
372
|
+
if (!platform.destinationStore) {
|
|
373
|
+
throw new Error("destination store not available on platform");
|
|
374
|
+
}
|
|
375
|
+
const doc = await platform.destinationStore.get(orgId, target.destinationId);
|
|
376
|
+
if (!doc) {
|
|
377
|
+
throw new Error(`destination ${target.destinationId} not found`);
|
|
378
|
+
}
|
|
379
|
+
const ref = doc.definition.connectorRef ?? "";
|
|
380
|
+
if (ref && ref !== target.connectorId) {
|
|
381
|
+
throw new Error(`destination ${target.destinationId} is bound to connector ${ref}, not ${target.connectorId}`);
|
|
382
|
+
}
|
|
383
|
+
const destName = doc.definition.name || target.destinationId;
|
|
384
|
+
const authoring = buildSyntheticAuthoringDefinition(target, {
|
|
385
|
+
sourceName: destName,
|
|
386
|
+
serviceDefs: serviceDefsFromEffective(platform, agentIds),
|
|
387
|
+
});
|
|
388
|
+
const compiled = compileWithServices(platform, agentIds, authoring);
|
|
389
|
+
const step = compiled.steps[0];
|
|
390
|
+
if (step) {
|
|
391
|
+
step.portConfig = {
|
|
392
|
+
...(step.portConfig ?? {}),
|
|
393
|
+
invokeProtocol: "memorix-destination/1",
|
|
394
|
+
connectorId: target.connectorId,
|
|
395
|
+
destinationId: target.destinationId,
|
|
396
|
+
};
|
|
397
|
+
// Ensure synthetic service id survives validation.
|
|
398
|
+
if (!step.serviceId) {
|
|
399
|
+
step.serviceId =
|
|
400
|
+
`dest:${target.connectorId}:${target.destinationId}`;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
return {
|
|
404
|
+
target,
|
|
405
|
+
pipelineId: syntheticPipelineId(target),
|
|
406
|
+
compiled: { ...compiled, pipelineId: syntheticPipelineId(target) },
|
|
407
|
+
label: destName,
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
if (target.kind === "service") {
|
|
411
|
+
const serviceDefs = serviceDefsFromEffective(platform, agentIds);
|
|
412
|
+
const svc = serviceDefs.find((s) => String(s.serviceId ?? s.id ?? "").trim() === target.serviceId);
|
|
413
|
+
if (!svc) {
|
|
414
|
+
throw new Error(`service ${target.serviceId} not found`);
|
|
415
|
+
}
|
|
416
|
+
const serviceName = typeof svc.name === "string"
|
|
417
|
+
? String(svc.name)
|
|
418
|
+
: target.serviceId;
|
|
419
|
+
const authoring = buildSyntheticAuthoringDefinition(target, {
|
|
420
|
+
serviceDefs,
|
|
421
|
+
serviceName,
|
|
422
|
+
});
|
|
423
|
+
const compiled = compileWithServices(platform, agentIds, authoring);
|
|
424
|
+
const endpoint = compiled.steps[0]?.portConfig
|
|
425
|
+
?.endpoint;
|
|
426
|
+
if (!endpoint && !compiled.steps[0]?.portConfig?.invokeProtocol) {
|
|
427
|
+
// Worker endpoint always resolves to a default base; AI may fall through.
|
|
428
|
+
// Accept as available — runtime will fail clearly if worker is down.
|
|
429
|
+
}
|
|
430
|
+
return {
|
|
431
|
+
target,
|
|
432
|
+
pipelineId: syntheticPipelineId(target),
|
|
433
|
+
compiled: { ...compiled, pipelineId: syntheticPipelineId(target) },
|
|
434
|
+
label: serviceName,
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
if (target.kind === "runx") {
|
|
438
|
+
const authoring = buildSyntheticAuthoringDefinition(target);
|
|
439
|
+
const compiled = compileWithServices(platform, agentIds, authoring);
|
|
440
|
+
return {
|
|
441
|
+
target,
|
|
442
|
+
pipelineId: syntheticPipelineId(target),
|
|
443
|
+
compiled: { ...compiled, pipelineId: syntheticPipelineId(target) },
|
|
444
|
+
label: `Runx ${target.capabilityId}`,
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
// ai-service
|
|
448
|
+
const origin = resolveAiServiceOriginUrl(target.aiServiceType);
|
|
449
|
+
if (!origin) {
|
|
450
|
+
throw new Error(`No origin configured for aiServiceType "${target.aiServiceType}"`);
|
|
451
|
+
}
|
|
452
|
+
const authoring = buildSyntheticAuthoringDefinition(target, {
|
|
453
|
+
serviceDefs: serviceDefsFromEffective(platform, agentIds),
|
|
454
|
+
itemTitle: `${target.aiServiceType}/${target.itemId}`,
|
|
455
|
+
});
|
|
456
|
+
// Inject a synthetic service def so compile stamps AI portConfig.
|
|
457
|
+
const aiServiceDef = {
|
|
458
|
+
id: `ai:${target.aiServiceType}:${target.itemId}`,
|
|
459
|
+
serviceId: `ai:${target.aiServiceType}:${target.itemId}`,
|
|
460
|
+
aiService: {
|
|
461
|
+
aiServiceType: target.aiServiceType,
|
|
462
|
+
itemId: target.itemId,
|
|
463
|
+
endpointEnv: defaultEndpointEnvForType(target.aiServiceType),
|
|
464
|
+
},
|
|
465
|
+
invocation: {
|
|
466
|
+
operation: target.itemId,
|
|
467
|
+
aiServiceType: target.aiServiceType,
|
|
468
|
+
itemId: target.itemId,
|
|
469
|
+
endpointEnv: defaultEndpointEnvForType(target.aiServiceType),
|
|
470
|
+
},
|
|
471
|
+
};
|
|
472
|
+
const serviceDefs = [
|
|
473
|
+
...serviceDefsFromEffective(platform, agentIds),
|
|
474
|
+
aiServiceDef,
|
|
475
|
+
];
|
|
476
|
+
const knownServiceIds = new Set(serviceDefs
|
|
477
|
+
.map((s) => String(s.serviceId ?? s.id ?? "").trim())
|
|
478
|
+
.filter(Boolean));
|
|
479
|
+
const compiled = compileAuthoringPipeline(authoring, {
|
|
480
|
+
knownServiceIds,
|
|
481
|
+
workerBaseUrl: resolveKnowxWorkerBaseUrl(),
|
|
482
|
+
serviceDefs,
|
|
483
|
+
});
|
|
484
|
+
const pc = compiled.steps[0]?.portConfig;
|
|
485
|
+
if (pc?.invokeProtocol !== "ai-services/1" || !pc.endpoint) {
|
|
486
|
+
// Force stamp if compile fell through to worker.
|
|
487
|
+
if (compiled.steps[0]) {
|
|
488
|
+
compiled.steps[0].portConfig = {
|
|
489
|
+
...(compiled.steps[0].portConfig ?? {}),
|
|
490
|
+
serviceId: aiServiceDef.serviceId,
|
|
491
|
+
operation: target.itemId,
|
|
492
|
+
endpoint: origin,
|
|
493
|
+
aiServiceType: target.aiServiceType,
|
|
494
|
+
itemId: target.itemId,
|
|
495
|
+
invokeProtocol: "ai-services/1",
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
return {
|
|
500
|
+
target,
|
|
501
|
+
pipelineId: syntheticPipelineId(target),
|
|
502
|
+
compiled: { ...compiled, pipelineId: syntheticPipelineId(target) },
|
|
503
|
+
label: `${target.aiServiceType}/${target.itemId}`,
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
/** Resolve by pipelineId — installed or synthetic. */
|
|
507
|
+
export async function resolvePipelineIdAsTarget(platform, opts) {
|
|
508
|
+
const fromSynthetic = parseSyntheticPipelineId(opts.pipelineId);
|
|
509
|
+
if (fromSynthetic) {
|
|
510
|
+
return resolveExecutionTarget(platform, {
|
|
511
|
+
agentIds: opts.agentIds,
|
|
512
|
+
orgId: opts.orgId,
|
|
513
|
+
target: fromSynthetic,
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
return resolveExecutionTarget(platform, {
|
|
517
|
+
agentIds: opts.agentIds,
|
|
518
|
+
orgId: opts.orgId,
|
|
519
|
+
target: { kind: "pipeline", pipelineId: opts.pipelineId },
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
export async function listExecutionTargets(platform, opts) {
|
|
523
|
+
const { agentIds, orgId } = opts;
|
|
524
|
+
const effective = platform.metadata.resolveEffective(agentIds);
|
|
525
|
+
const entries = effective.effective ?? [];
|
|
526
|
+
const pipelines = entries
|
|
527
|
+
.filter((e) => e.kind === "pipelines")
|
|
528
|
+
.map((e) => {
|
|
529
|
+
const d = e.definition;
|
|
530
|
+
const pipelineId = String(d.id ?? d.pipelineId ?? e.id).trim();
|
|
531
|
+
const steps = Array.isArray(d.steps) ? d.steps : [];
|
|
532
|
+
return {
|
|
533
|
+
kind: "pipeline",
|
|
534
|
+
id: pipelineId,
|
|
535
|
+
name: typeof d.name === "string" ? d.name : pipelineId,
|
|
536
|
+
description: typeof d.description === "string" ? d.description : undefined,
|
|
537
|
+
available: true,
|
|
538
|
+
capabilities: [`${steps.length} steps`],
|
|
539
|
+
target: { kind: "pipeline", pipelineId },
|
|
540
|
+
meta: {
|
|
541
|
+
trigger: typeof d.trigger === "string" ? d.trigger : undefined,
|
|
542
|
+
stepCount: steps.length,
|
|
543
|
+
},
|
|
544
|
+
};
|
|
545
|
+
});
|
|
546
|
+
// Sources (pack + org)
|
|
547
|
+
const packSources = entries
|
|
548
|
+
.filter((e) => e.kind === "sources")
|
|
549
|
+
.map((e) => ({
|
|
550
|
+
sourceId: e.id,
|
|
551
|
+
definition: e.definition,
|
|
552
|
+
connectorRef: typeof e.definition.connectorRef === "string"
|
|
553
|
+
? e.definition.connectorRef
|
|
554
|
+
: typeof e.definition.kind === "string"
|
|
555
|
+
? String(e.definition.kind)
|
|
556
|
+
: undefined,
|
|
557
|
+
}));
|
|
558
|
+
const orgSources = orgId != null
|
|
559
|
+
? (await platform.orgRuntimeSourcesFor(orgId).list({ agentIds })).map((r) => ({
|
|
560
|
+
sourceId: r.sourceId,
|
|
561
|
+
definition: r.definition,
|
|
562
|
+
connectorRef: typeof r.definition.connectorRef === "string"
|
|
563
|
+
? r.definition.connectorRef
|
|
564
|
+
: typeof r.definition.kind === "string"
|
|
565
|
+
? String(r.definition.kind)
|
|
566
|
+
: r.origin,
|
|
567
|
+
}))
|
|
568
|
+
: [];
|
|
569
|
+
const sourceById = new Map();
|
|
570
|
+
for (const s of [...packSources, ...orgSources]) {
|
|
571
|
+
if (!sourceById.has(s.sourceId))
|
|
572
|
+
sourceById.set(s.sourceId, s);
|
|
573
|
+
}
|
|
574
|
+
const unified = await listUnifiedConnectors({
|
|
575
|
+
connectorRegistry: platform.connectorRegistry,
|
|
576
|
+
genericConnectors: platform.genericConnectors ?? loadGenericConnectorsConfig(),
|
|
577
|
+
});
|
|
578
|
+
const destinations = orgId != null && platform.destinationStore
|
|
579
|
+
? await platform.destinationStore.list(orgId)
|
|
580
|
+
: [];
|
|
581
|
+
const sourceConnectors = [];
|
|
582
|
+
const targetConnectors = [];
|
|
583
|
+
for (const c of unified) {
|
|
584
|
+
if (!c.connectorRole)
|
|
585
|
+
continue;
|
|
586
|
+
const sources = [...sourceById.values()].filter((s) => s.connectorRef === c.id);
|
|
587
|
+
const sourceChildren = sources.map((s) => {
|
|
588
|
+
const name = typeof s.definition.name === "string" ? s.definition.name : s.sourceId;
|
|
589
|
+
return {
|
|
590
|
+
kind: "connector",
|
|
591
|
+
id: `${c.id}:${s.sourceId}`,
|
|
592
|
+
name,
|
|
593
|
+
description: `Source ${s.sourceId} via ${c.displayName}`,
|
|
594
|
+
available: c.enabled && !c.unavailableReason,
|
|
595
|
+
unavailableReason: c.enabled
|
|
596
|
+
? c.unavailableReason
|
|
597
|
+
: "Connector disabled",
|
|
598
|
+
target: {
|
|
599
|
+
kind: "connector",
|
|
600
|
+
connectorId: c.id,
|
|
601
|
+
sourceId: s.sourceId,
|
|
602
|
+
},
|
|
603
|
+
meta: {
|
|
604
|
+
connectorId: c.id,
|
|
605
|
+
sourceId: s.sourceId,
|
|
606
|
+
origin: c.origin,
|
|
607
|
+
},
|
|
608
|
+
};
|
|
609
|
+
});
|
|
610
|
+
const destChildren = destinations
|
|
611
|
+
.filter((d) => d.definition.connectorRef === c.id)
|
|
612
|
+
.map((d) => {
|
|
613
|
+
const destId = d.definition.id;
|
|
614
|
+
return {
|
|
615
|
+
kind: "destination",
|
|
616
|
+
id: `${c.id}:dest:${destId}`,
|
|
617
|
+
name: d.definition.name || destId,
|
|
618
|
+
description: `Destination ${destId} via ${c.displayName}`,
|
|
619
|
+
available: c.enabled && !c.unavailableReason,
|
|
620
|
+
unavailableReason: c.unavailableReason,
|
|
621
|
+
target: {
|
|
622
|
+
kind: "destination",
|
|
623
|
+
connectorId: c.id,
|
|
624
|
+
destinationId: destId,
|
|
625
|
+
},
|
|
626
|
+
meta: {
|
|
627
|
+
connectorId: c.id,
|
|
628
|
+
destinationId: destId,
|
|
629
|
+
origin: c.origin,
|
|
630
|
+
hostBaseUrl: d.definition.hostBaseUrl ?? c.hostBaseUrl,
|
|
631
|
+
},
|
|
632
|
+
};
|
|
633
|
+
});
|
|
634
|
+
const baseMeta = {
|
|
635
|
+
connectorId: c.id,
|
|
636
|
+
connectorRole: c.connectorRole,
|
|
637
|
+
origin: c.origin,
|
|
638
|
+
...(c.hostBaseUrl ? { hostBaseUrl: c.hostBaseUrl } : {}),
|
|
639
|
+
...(c.remoteHosting ? { remoteHosting: true } : {}),
|
|
640
|
+
};
|
|
641
|
+
if (c.isSource) {
|
|
642
|
+
const hostBlock = c.unavailableReason;
|
|
643
|
+
sourceConnectors.push({
|
|
644
|
+
kind: "connector",
|
|
645
|
+
id: c.id,
|
|
646
|
+
name: c.displayName,
|
|
647
|
+
description: hostBlock
|
|
648
|
+
? hostBlock
|
|
649
|
+
: `Source connector · ${sourceChildren.length} configured source(s)${c.origin === "generic-connectors" ? " · Generic" : ""}`,
|
|
650
|
+
available: sourceChildren.length > 0 && c.enabled && !hostBlock,
|
|
651
|
+
unavailableReason: !c.enabled
|
|
652
|
+
? "Connector disabled"
|
|
653
|
+
: hostBlock
|
|
654
|
+
? hostBlock
|
|
655
|
+
: sourceChildren.length === 0
|
|
656
|
+
? "No configured source — bind a source in Studio first"
|
|
657
|
+
: undefined,
|
|
658
|
+
capabilities: c.capabilityKeys,
|
|
659
|
+
target: {
|
|
660
|
+
kind: "connector",
|
|
661
|
+
connectorId: c.id,
|
|
662
|
+
sourceId: sourceChildren[0]?.meta?.sourceId
|
|
663
|
+
? String(sourceChildren[0].meta.sourceId)
|
|
664
|
+
: "",
|
|
665
|
+
},
|
|
666
|
+
children: sourceChildren,
|
|
667
|
+
meta: baseMeta,
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
if (c.isTarget) {
|
|
671
|
+
const hostBlock = c.unavailableReason;
|
|
672
|
+
targetConnectors.push({
|
|
673
|
+
kind: "destination",
|
|
674
|
+
id: c.id,
|
|
675
|
+
name: c.displayName,
|
|
676
|
+
description: hostBlock
|
|
677
|
+
? hostBlock
|
|
678
|
+
: `Target connector · ${destChildren.length} configured destination(s)${c.origin === "generic-connectors" ? " · Generic" : ""}`,
|
|
679
|
+
available: destChildren.length > 0 && c.enabled && !hostBlock,
|
|
680
|
+
unavailableReason: !c.enabled
|
|
681
|
+
? "Connector disabled"
|
|
682
|
+
: hostBlock
|
|
683
|
+
? hostBlock
|
|
684
|
+
: destChildren.length === 0
|
|
685
|
+
? "No configured destination — create one via Memory destinations API first"
|
|
686
|
+
: undefined,
|
|
687
|
+
capabilities: c.capabilityKeys,
|
|
688
|
+
target: {
|
|
689
|
+
kind: "destination",
|
|
690
|
+
connectorId: c.id,
|
|
691
|
+
destinationId: destChildren[0]?.meta?.destinationId
|
|
692
|
+
? String(destChildren[0].meta.destinationId)
|
|
693
|
+
: "",
|
|
694
|
+
},
|
|
695
|
+
children: destChildren,
|
|
696
|
+
meta: baseMeta,
|
|
697
|
+
});
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
/** Compat alias — source connectors only. */
|
|
701
|
+
const connectors = sourceConnectors;
|
|
702
|
+
const services = entries
|
|
703
|
+
.filter((e) => e.kind === "services")
|
|
704
|
+
.map((e) => {
|
|
705
|
+
const d = e.definition;
|
|
706
|
+
const serviceId = String(d.id ?? d.serviceId ?? e.id).trim();
|
|
707
|
+
const caps = Array.isArray(d.capabilities)
|
|
708
|
+
? d.capabilities
|
|
709
|
+
: [];
|
|
710
|
+
const ai = asRecord(d.aiService);
|
|
711
|
+
return {
|
|
712
|
+
kind: "service",
|
|
713
|
+
id: serviceId,
|
|
714
|
+
name: typeof d.name === "string" ? d.name : serviceId,
|
|
715
|
+
description: typeof d.description === "string" ? d.description : undefined,
|
|
716
|
+
available: true,
|
|
717
|
+
capabilities: caps,
|
|
718
|
+
target: { kind: "service", serviceId },
|
|
719
|
+
meta: {
|
|
720
|
+
role: typeof d.role === "string" ? d.role : undefined,
|
|
721
|
+
aiServiceType: typeof ai?.aiServiceType === "string" ? ai.aiServiceType : undefined,
|
|
722
|
+
itemId: typeof ai?.itemId === "string" ? ai.itemId : undefined,
|
|
723
|
+
},
|
|
724
|
+
};
|
|
725
|
+
});
|
|
726
|
+
const client = createAiServicesClient({ timeoutMs: 4_000 });
|
|
727
|
+
const origins = resolveConfiguredAiServiceOrigins();
|
|
728
|
+
const aiServices = await Promise.all(AI_SERVICE_ORIGIN_SPECS.map(async (spec) => {
|
|
729
|
+
const origin = origins.find((o) => o.aiServiceType === spec.aiServiceType);
|
|
730
|
+
const url = origin?.url ?? null;
|
|
731
|
+
if (!url) {
|
|
732
|
+
return {
|
|
733
|
+
kind: "ai-service",
|
|
734
|
+
id: spec.aiServiceType,
|
|
735
|
+
name: spec.aiServiceType,
|
|
736
|
+
description: `Set ${spec.env} to enable`,
|
|
737
|
+
available: false,
|
|
738
|
+
unavailableReason: `No origin configured (${spec.env})`,
|
|
739
|
+
target: {
|
|
740
|
+
kind: "ai-service",
|
|
741
|
+
aiServiceType: spec.aiServiceType,
|
|
742
|
+
itemId: "",
|
|
743
|
+
},
|
|
744
|
+
children: [],
|
|
745
|
+
meta: { aiServiceType: spec.aiServiceType, env: spec.env },
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
try {
|
|
749
|
+
const health = await client.getHealth(url);
|
|
750
|
+
if (!health.ok) {
|
|
751
|
+
return {
|
|
752
|
+
kind: "ai-service",
|
|
753
|
+
id: spec.aiServiceType,
|
|
754
|
+
name: spec.aiServiceType,
|
|
755
|
+
description: url,
|
|
756
|
+
available: false,
|
|
757
|
+
unavailableReason: `Companion unreachable (HTTP ${health.status})`,
|
|
758
|
+
target: {
|
|
759
|
+
kind: "ai-service",
|
|
760
|
+
aiServiceType: spec.aiServiceType,
|
|
761
|
+
itemId: "",
|
|
762
|
+
},
|
|
763
|
+
children: [],
|
|
764
|
+
meta: { aiServiceType: spec.aiServiceType, url },
|
|
765
|
+
};
|
|
766
|
+
}
|
|
767
|
+
const items = await client.listItems(url, { limit: 200 });
|
|
768
|
+
const children = items.map((item) => ({
|
|
769
|
+
kind: "ai-service",
|
|
770
|
+
id: `${spec.aiServiceType}:${item.id}`,
|
|
771
|
+
name: item.title || item.id,
|
|
772
|
+
description: item.summary,
|
|
773
|
+
available: true,
|
|
774
|
+
capabilities: item.tags,
|
|
775
|
+
target: {
|
|
776
|
+
kind: "ai-service",
|
|
777
|
+
aiServiceType: spec.aiServiceType,
|
|
778
|
+
itemId: item.id,
|
|
779
|
+
},
|
|
780
|
+
meta: {
|
|
781
|
+
aiServiceType: spec.aiServiceType,
|
|
782
|
+
itemId: item.id,
|
|
783
|
+
version: item.version,
|
|
784
|
+
},
|
|
785
|
+
}));
|
|
786
|
+
return {
|
|
787
|
+
kind: "ai-service",
|
|
788
|
+
id: spec.aiServiceType,
|
|
789
|
+
name: spec.aiServiceType,
|
|
790
|
+
description: `${children.length} item(s) · ${url}`,
|
|
791
|
+
available: children.length > 0,
|
|
792
|
+
unavailableReason: children.length === 0 ? "No catalog items" : undefined,
|
|
793
|
+
target: {
|
|
794
|
+
kind: "ai-service",
|
|
795
|
+
aiServiceType: spec.aiServiceType,
|
|
796
|
+
itemId: children[0]?.meta?.itemId
|
|
797
|
+
? String(children[0].meta.itemId)
|
|
798
|
+
: "",
|
|
799
|
+
},
|
|
800
|
+
children,
|
|
801
|
+
meta: { aiServiceType: spec.aiServiceType, url },
|
|
802
|
+
};
|
|
803
|
+
}
|
|
804
|
+
catch (err) {
|
|
805
|
+
return {
|
|
806
|
+
kind: "ai-service",
|
|
807
|
+
id: spec.aiServiceType,
|
|
808
|
+
name: spec.aiServiceType,
|
|
809
|
+
description: url,
|
|
810
|
+
available: false,
|
|
811
|
+
unavailableReason: err instanceof Error ? err.message : String(err),
|
|
812
|
+
target: {
|
|
813
|
+
kind: "ai-service",
|
|
814
|
+
aiServiceType: spec.aiServiceType,
|
|
815
|
+
itemId: "",
|
|
816
|
+
},
|
|
817
|
+
children: [],
|
|
818
|
+
meta: { aiServiceType: spec.aiServiceType, url },
|
|
819
|
+
};
|
|
820
|
+
}
|
|
821
|
+
}));
|
|
822
|
+
const runxEnabled = process.env.RUNX_ENABLED === "1" ||
|
|
823
|
+
process.env.RUNX_ENABLED === "true" ||
|
|
824
|
+
Boolean(process.env.FIREBASE_PROJECT_ID?.trim() ||
|
|
825
|
+
process.env.GOOGLE_SERVICE_ACCOUNT_BASE64?.trim() ||
|
|
826
|
+
process.env.CATALOX_MONGO_URI?.trim());
|
|
827
|
+
const runx = [
|
|
828
|
+
{
|
|
829
|
+
kind: "runx",
|
|
830
|
+
id: "runx",
|
|
831
|
+
name: "Runx",
|
|
832
|
+
description: runxEnabled
|
|
833
|
+
? "Run a Runx capability by id (set capabilityId on work target)"
|
|
834
|
+
: "Configure Catalox/Runx (RUNX_ENABLED or FIREBASE_*/CATALOX_*)",
|
|
835
|
+
available: runxEnabled,
|
|
836
|
+
unavailableReason: runxEnabled
|
|
837
|
+
? undefined
|
|
838
|
+
: "Runx not configured",
|
|
839
|
+
target: { kind: "runx", capabilityId: "" },
|
|
840
|
+
meta: { note: "Pass capabilityId in executionTarget" },
|
|
841
|
+
},
|
|
842
|
+
];
|
|
843
|
+
return {
|
|
844
|
+
pipelines,
|
|
845
|
+
connectors,
|
|
846
|
+
sourceConnectors,
|
|
847
|
+
targetConnectors,
|
|
848
|
+
services,
|
|
849
|
+
aiServices,
|
|
850
|
+
runx,
|
|
851
|
+
};
|
|
852
|
+
}
|
|
853
|
+
//# sourceMappingURL=execution-target.js.map
|