witnora 0.18.4 → 0.18.6
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/gateway.js +18 -2
- package/dist/onboard.js +5 -3
- package/dist/real-path-activation.js +19 -8
- package/dist/vendor/onegent-runtime/managed-workflow-harness.d.ts +1 -0
- package/dist/vendor/onegent-runtime/managed-workflow-harness.d.ts.map +1 -1
- package/dist/vendor/onegent-runtime/managed-workflow-harness.js +6 -2
- package/package.json +1 -1
package/dist/gateway.js
CHANGED
|
@@ -655,6 +655,9 @@ export async function createConfiguredWorkflowHarness(input) {
|
|
|
655
655
|
client: hosted,
|
|
656
656
|
checkpoints: new input.managed.FileWorkflowEvaluationCheckpointStore(join(input.directory, "data", "workflow-evaluations")),
|
|
657
657
|
maxConcurrency: input.config.maxConcurrency,
|
|
658
|
+
supportedModes: Array.isArray(healthBody.modes)
|
|
659
|
+
? healthBody.modes.filter((mode) => mode === "REPLAY" || mode === "SHADOW")
|
|
660
|
+
: [],
|
|
658
661
|
evaluate: async ({ task, evaluation }) => {
|
|
659
662
|
const response = await requestFetch(`${evaluatorOrigin}/v1/evaluate`, {
|
|
660
663
|
method: "POST",
|
|
@@ -1257,20 +1260,33 @@ export async function activateManagedWorkflowHarness(options) {
|
|
|
1257
1260
|
const path = join(directory, "workflow-harness.json");
|
|
1258
1261
|
const serialized = `${JSON.stringify(config, null, 2)}\n`;
|
|
1259
1262
|
let created = false;
|
|
1263
|
+
let changed = false;
|
|
1260
1264
|
if (await exists(path)) {
|
|
1261
1265
|
const current = await readFile(path, "utf8");
|
|
1262
1266
|
if (current !== serialized) {
|
|
1263
1267
|
const parsed = parseManagedWorkflowHarnessConfig(current);
|
|
1264
|
-
if (parsed.schemaVersion !== MANAGED_WORKFLOW_HARNESS_SCHEMA
|
|
1268
|
+
if (parsed.schemaVersion !== MANAGED_WORKFLOW_HARNESS_SCHEMA
|
|
1269
|
+
|| (canonicalHarnessConfig(parsed) !== canonicalHarnessConfig(config)
|
|
1270
|
+
&& !isExactGeneratedHarnessUpgrade(parsed, config, options.previousGeneratedModuleSha256))) {
|
|
1265
1271
|
throw new Error("Existing workflow-harness.json differs from the generated Assurance Harness binding; refusing to overwrite customer configuration.");
|
|
1272
|
+
}
|
|
1266
1273
|
await writeFile(path, serialized, { encoding: "utf8", mode: 0o600 });
|
|
1274
|
+
changed = true;
|
|
1267
1275
|
}
|
|
1268
1276
|
}
|
|
1269
1277
|
else {
|
|
1270
1278
|
await writeFile(path, serialized, { encoding: "utf8", mode: 0o600, flag: "wx" });
|
|
1271
1279
|
created = true;
|
|
1280
|
+
changed = true;
|
|
1272
1281
|
}
|
|
1273
|
-
return { state: "READY_TO_START", path, modulePath: evaluatorModulePath, config, created };
|
|
1282
|
+
return { state: "READY_TO_START", path, modulePath: evaluatorModulePath, config, created, changed };
|
|
1283
|
+
}
|
|
1284
|
+
function isExactGeneratedHarnessUpgrade(current, next, previousGeneratedModuleSha256) {
|
|
1285
|
+
if (!previousGeneratedModuleSha256 || current.evaluatorModuleSha256 !== previousGeneratedModuleSha256 || current.evaluatorContractSha256 !== previousGeneratedModuleSha256)
|
|
1286
|
+
return false;
|
|
1287
|
+
const { realPathActivations: _currentActivations, evaluatorModuleSha256: _currentModule, evaluatorContractSha256: _currentContract, ...currentStable } = current;
|
|
1288
|
+
const { realPathActivations: _nextActivations, evaluatorModuleSha256: _nextModule, evaluatorContractSha256: _nextContract, ...nextStable } = next;
|
|
1289
|
+
return JSON.stringify(currentStable) === JSON.stringify(nextStable);
|
|
1274
1290
|
}
|
|
1275
1291
|
function canonicalHarnessConfig(value) {
|
|
1276
1292
|
const { realPathActivations: _activations, ...stable } = value;
|
package/dist/onboard.js
CHANGED
|
@@ -88,6 +88,7 @@ export async function runOnboard(options) {
|
|
|
88
88
|
let gatewayMigration;
|
|
89
89
|
let managedGateway;
|
|
90
90
|
let runtimeUpgrade;
|
|
91
|
+
let realPathActivation;
|
|
91
92
|
let assuranceHarnessReadiness = {
|
|
92
93
|
state: "WAITING_FOR_CUSTOMER_HARNESS",
|
|
93
94
|
limitation: "No approved customer Harness module is bound to this Agent repository.",
|
|
@@ -196,13 +197,13 @@ export async function runOnboard(options) {
|
|
|
196
197
|
}
|
|
197
198
|
const runtimeConfigured = await gatewayHasRuntimeWorker(repositoryPath);
|
|
198
199
|
generatedFiles.push(...await generateAutopilotFiles(repositoryPath, repository.name, runtimeConfigured));
|
|
199
|
-
|
|
200
|
+
realPathActivation = await activateRealPathIntegrations({ repository: repositoryPath, server, projectId: token.projectId, apiKey: token.apiKey, env: options.env, fetch: requestFetch });
|
|
200
201
|
generatedFiles.push(...realPathActivation.generatedFiles);
|
|
201
202
|
try {
|
|
202
|
-
const activation = await activateManagedWorkflowHarness({ repository: repositoryPath, realPathActivations: realPathActivation.activations });
|
|
203
|
+
const activation = await activateManagedWorkflowHarness({ repository: repositoryPath, realPathActivations: realPathActivation.activations, previousGeneratedModuleSha256: realPathActivation.previousGeneratedModuleSha256 });
|
|
203
204
|
if (activation.created)
|
|
204
205
|
generatedFiles.push(activation.path);
|
|
205
|
-
assuranceHarnessChanged = activation.
|
|
206
|
+
assuranceHarnessChanged = activation.changed;
|
|
206
207
|
assuranceHarnessReadiness = { state: "ACTIVE" };
|
|
207
208
|
}
|
|
208
209
|
catch (error) {
|
|
@@ -266,6 +267,7 @@ export async function runOnboard(options) {
|
|
|
266
267
|
if (managedGateway?.started) {
|
|
267
268
|
await gatewayLifecycle.stop({ repository: repositoryPath, configHome: options.configHome, fetch: requestFetch }).catch(() => undefined);
|
|
268
269
|
}
|
|
270
|
+
await realPathActivation?.rollback().catch(() => undefined);
|
|
269
271
|
await rollbackGeneratedFiles(generatedFiles);
|
|
270
272
|
await runtimeUpgrade?.rollback().catch(() => undefined);
|
|
271
273
|
if (gatewayMigration)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
-
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
2
|
+
import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
3
3
|
import { dirname, join, resolve } from "node:path";
|
|
4
4
|
export async function activateRealPathIntegrations(options) {
|
|
5
5
|
const repository = resolve(options.repository ?? process.cwd());
|
|
@@ -7,14 +7,14 @@ export async function activateRealPathIntegrations(options) {
|
|
|
7
7
|
const base = options.server.replace(/\/$/, "");
|
|
8
8
|
const response = await request(`${base}/v1/projects/${encodeURIComponent(options.projectId)}/real-path-integrations`, { headers: { authorization: `Bearer ${options.apiKey}` } });
|
|
9
9
|
if (response.status === 404)
|
|
10
|
-
return { state: "NOT_CONFIGURED", created: false, activations: [], generatedFiles: [] };
|
|
10
|
+
return { state: "NOT_CONFIGURED", created: false, activations: [], generatedFiles: [], rollback: async () => undefined };
|
|
11
11
|
if (!response.ok)
|
|
12
12
|
throw new Error(`Could not load approved real-path integrations (${response.status}).`);
|
|
13
13
|
const body = await boundedJson(response);
|
|
14
14
|
const approved = Array.isArray(body.integrations) ? body.integrations.map(parsePlan).filter((plan) => plan.status === "READY_TO_ACTIVATE") : [];
|
|
15
15
|
const plans = approved.filter((plan) => ["STRIPE_REFUND", "SHOPIFY_DISPUTE", "ZENDESK_TICKET", "SALESFORCE_RECORD", "HUBSPOT_CRM_RECORD", "POSTGRES_RECORD"].includes(plan.generated.providerPackId) && plan.environment === "sandbox" && plan.customerSummary.evaluationMode === "SHADOW");
|
|
16
16
|
if (!plans.length)
|
|
17
|
-
return { state: "NOT_CONFIGURED", created: false, activations: [], generatedFiles: [] };
|
|
17
|
+
return { state: "NOT_CONFIGURED", created: false, activations: [], generatedFiles: [], rollback: async () => undefined };
|
|
18
18
|
const environment = options.env ?? process.env;
|
|
19
19
|
const activations = [];
|
|
20
20
|
const scenarios = [];
|
|
@@ -32,7 +32,9 @@ export async function activateRealPathIntegrations(options) {
|
|
|
32
32
|
let created = false;
|
|
33
33
|
const generatedFiles = [];
|
|
34
34
|
const current = await readFile(modulePath, "utf8").catch((error) => error.code === "ENOENT" ? undefined : Promise.reject(error));
|
|
35
|
-
const
|
|
35
|
+
const priorSource = await readFile(manifestPath, "utf8").catch((error) => error.code === "ENOENT" ? undefined : Promise.reject(error));
|
|
36
|
+
const prior = priorSource === undefined ? undefined : JSON.parse(priorSource);
|
|
37
|
+
const previousGeneratedModuleSha256 = current !== undefined && sha(current) === prior?.moduleDigestSha256 ? prior.moduleDigestSha256 : undefined;
|
|
36
38
|
if (current === undefined) {
|
|
37
39
|
await writeFile(modulePath, source, { encoding: "utf8", mode: 0o600, flag: "wx" });
|
|
38
40
|
created = true;
|
|
@@ -44,12 +46,12 @@ export async function activateRealPathIntegrations(options) {
|
|
|
44
46
|
const temporary = `${modulePath}.${randomUUID()}.tmp`;
|
|
45
47
|
await writeFile(temporary, source, { encoding: "utf8", mode: 0o600, flag: "wx" });
|
|
46
48
|
await rename(temporary, modulePath);
|
|
47
|
-
generatedFiles.push(modulePath);
|
|
48
49
|
}
|
|
49
50
|
const manifest = { schemaVersion: "witnora.real_path_activation_manifest.v0.1", projectId: options.projectId, moduleDigestSha256, activations };
|
|
50
51
|
await mkdir(dirname(manifestPath), { recursive: true });
|
|
51
52
|
await writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, { encoding: "utf8", mode: 0o600 });
|
|
52
|
-
|
|
53
|
+
if (priorSource === undefined)
|
|
54
|
+
generatedFiles.push(manifestPath);
|
|
53
55
|
for (const item of scenarios) {
|
|
54
56
|
const path = join(repository, ".witnora", "scenarios", `${item.plan.taskContractId}.json`);
|
|
55
57
|
await mkdir(dirname(path), { recursive: true });
|
|
@@ -62,7 +64,16 @@ export async function activateRealPathIntegrations(options) {
|
|
|
62
64
|
throw error;
|
|
63
65
|
}
|
|
64
66
|
}
|
|
65
|
-
return { state: "READY_TO_START", created, modulePath: "witnora.assurance-harness.mjs", activations, generatedFiles }
|
|
67
|
+
return { state: "READY_TO_START", created, modulePath: "witnora.assurance-harness.mjs", activations, generatedFiles, ...(previousGeneratedModuleSha256 ? { previousGeneratedModuleSha256 } : {}), rollback: async () => {
|
|
68
|
+
if (current === undefined)
|
|
69
|
+
await rm(modulePath, { force: true });
|
|
70
|
+
else
|
|
71
|
+
await writeFile(modulePath, current, { encoding: "utf8", mode: 0o600 });
|
|
72
|
+
if (priorSource === undefined)
|
|
73
|
+
await rm(manifestPath, { force: true });
|
|
74
|
+
else
|
|
75
|
+
await writeFile(manifestPath, priorSource, { encoding: "utf8", mode: 0o600 });
|
|
76
|
+
} };
|
|
66
77
|
}
|
|
67
78
|
async function providerPreflight(request, env, plan, now, postgresClientFactory) {
|
|
68
79
|
if (plan.generated.providerPackId === "STRIPE_REFUND") {
|
|
@@ -231,7 +242,7 @@ const sha=(value)=>createHash("sha256").update(typeof value==="string"?value:JSO
|
|
|
231
242
|
const request=async(url,key)=>{const response=await fetch(url,{method:"GET",headers:{accept:"application/json",authorization:"Bearer "+key},redirect:"error",signal:AbortSignal.timeout(5000)});if(!response.ok)throw new Error("Provider read-only observation failed ("+response.status+").");return response.json();};
|
|
232
243
|
const observe=async(contract,resourceId,repository)=>{if(contract.sandboxObservation)return structuredClone(contract.sandboxObservation);const key=(await readFile(join(repository,contract.credentialHandle),"utf8")).trim();if(!key)throw new Error("The local read-only Provider credential is unavailable.");if(contract.providerPackId==="STRIPE_REFUND"){if(!key.startsWith("sk_test_"))throw new Error("Stripe test-mode credential is unavailable.");return request("https://api.stripe.com/v1/refunds/"+encodeURIComponent(resourceId),key);}if(contract.providerPackId==="SHOPIFY_DISPUTE"){const response=await fetch(contract.providerConfiguration.origin+"/admin/api/2025-07/shopify_payments/disputes/"+encodeURIComponent(resourceId)+".json",{method:"GET",headers:{accept:"application/json","x-shopify-access-token":key},redirect:"error",signal:AbortSignal.timeout(5000)});if(!response.ok)throw new Error("Provider read-only observation failed ("+response.status+").");return (await response.json()).dispute;}if(contract.providerPackId==="ZENDESK_TICKET")return (await request(contract.providerConfiguration.origin+"/api/v2/tickets/"+encodeURIComponent(resourceId)+".json",key)).ticket;if(contract.providerPackId==="SALESFORCE_RECORD")return request(contract.providerConfiguration.origin+"/services/data/v61.0/sobjects/"+encodeURIComponent(contract.providerConfiguration.resourceType)+"/"+encodeURIComponent(resourceId),key);if(contract.providerPackId==="HUBSPOT_CRM_RECORD")return (await request("https://api.hubapi.com/crm/v3/objects/"+encodeURIComponent(contract.providerConfiguration.resourceType)+"/"+encodeURIComponent(resourceId)+"?properties="+encodeURIComponent(contract.criterion.field),key)).properties;if(contract.providerPackId==="POSTGRES_RECORD"){for(const name of [contract.providerConfiguration.viewName,contract.providerConfiguration.idColumn,contract.criterion.field])if(!/^[A-Za-z][A-Za-z0-9_]{0,99}$/.test(name))throw new Error("PostgreSQL identifier is invalid.");const {Client}=await import("pg");const client=new Client({connectionString:key,application_name:"witnora-read-only-probe"});await client.connect();try{await client.query("BEGIN READ ONLY");const result=await client.query({name:"witnora-provider-observe",text:'SELECT "'+contract.criterion.field+'" FROM "'+contract.providerConfiguration.viewName+'" WHERE "'+contract.providerConfiguration.idColumn+'" = $1 LIMIT 1',values:[resourceId]});await client.query("ROLLBACK");return result.rows[0]??{};}catch(error){await client.query("ROLLBACK").catch(()=>{});throw error;}finally{await client.end();}}throw new Error("Provider Harness contract is unsupported.");};
|
|
233
244
|
export function createWitnoraBusinessTaskEvaluatorOptions(context){return {
|
|
234
|
-
loadShadowObservations:async(task)=>{const contract=contracts.find((item)=>item.taskContractId===task.id);if(!contract)throw new Error("No exact real-path contract.");const path=join(context.repository,".witnora","scenarios",task.id+".json");const value=JSON.parse(await readFile(path,"utf8"));if(!Array.isArray(value)||value.length>100)throw new Error("Local scenario file is invalid.");return value;},
|
|
245
|
+
loadShadowObservations:async(task)=>{const contract=contracts.find((item)=>item.taskContractId===task.id);if(!contract)throw new Error("No exact real-path contract.");const path=join(context.repository,".witnora","scenarios",task.id+".json");const value=JSON.parse(await readFile(path,"utf8"));if(!Array.isArray(value)||value.length>100)throw new Error("Local scenario file is invalid.");return value.map((item)=>({...item,source:"LIVE_SHADOW"}));},
|
|
235
246
|
evaluateShadowCandidate:async(candidate,task)=>{const contract=contracts.find((item)=>item.taskContractId===task.id);if(!contract)throw new Error("No exact real-path contract.");const resourceId=String(candidate.input?.resourceId??"");if(!/^[A-Za-z0-9._:-]{1,200}$/.test(resourceId))throw new Error("Provider resourceId is invalid.");for(const pathId of contract.actionPathIds)candidate.propose({pathId,parametersDigestSha256:sha(resourceId)});const raw=await observe(contract,resourceId,context.repository);const actual=raw?.[contract.criterion.field];const observed=actual===undefined?{}:{[contract.criterion.field]:actual};return {resultDigestSha256:sha(observed),criteria:[{id:contract.criterion.id,passed:actual===contract.criterion.expected}]};}
|
|
236
247
|
};}
|
|
237
248
|
export async function checkWitnoraProviderHealth(context){for(const contract of contracts){const path=join(context.repository,".witnora","scenarios",contract.taskContractId+".json");const scenarios=JSON.parse(await readFile(path,"utf8"));const resourceId=String(scenarios?.[0]?.input?.resourceId??"");if(!/^[A-Za-z0-9._:-]{1,200}$/.test(resourceId))throw new Error("Provider health scenario is unavailable.");const raw=await observe(contract,resourceId,context.repository);if(raw?.[contract.criterion.field]===undefined)throw new Error("The approved Provider result field is no longer observable.");}return {ready:true,checked:contracts.length};}
|
|
@@ -126,6 +126,7 @@ export declare class ManagedBusinessWorkflowHarness {
|
|
|
126
126
|
evaluation: ManagedWorkflowReadyEvaluation;
|
|
127
127
|
}) => Promise<TaskEvaluationReport>;
|
|
128
128
|
maxConcurrency?: number;
|
|
129
|
+
supportedModes?: Array<"REPLAY" | "SHADOW">;
|
|
129
130
|
});
|
|
130
131
|
tick(): Promise<ManagedBusinessWorkflowHarnessResult>;
|
|
131
132
|
private runTick;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"managed-workflow-harness.d.ts","sourceRoot":"","sources":["../../../../onegent-runtime/src/managed-workflow-harness.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAGzF,MAAM,MAAM,6BAA6B,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEhE,MAAM,WAAW,4BAA4B;IAC3C,aAAa,EAAE,+CAA+C,CAAC;IAC/D,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAA;KAAE,CAAC;IAC7E,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,gBAAgB,GAAG,WAAW,CAAA;KAAE,CAAC,CAAC;IACvG,gBAAgB,EAAE,8BAA8B,EAAE,CAAC;IACnD,gBAAgB,EAAE,OAAO,CAAC;IAC1B,MAAM,EAAE;QAAE,gBAAgB,EAAE,CAAC,CAAC;QAAC,uBAAuB,EAAE,KAAK,CAAC;QAAC,uBAAuB,EAAE,IAAI,CAAA;KAAE,CAAC;IAC/F,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,8BAA8B;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,wBAAwB,EAAE,MAAM,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,IAAI,EAAE,6BAA6B,CAAC;IACpC,gBAAgB,CAAC,EAAE;QACjB,MAAM,EAAE,iBAAiB,GAAG,gBAAgB,CAAC;QAC7C,sBAAsB,EAAE,MAAM,EAAE,CAAC;QACjC,gBAAgB,EAAE,MAAM,CAAC;QACzB,aAAa,EAAE,MAAM,CAAC;QACtB,eAAe,EAAE,MAAM,CAAC;QACxB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,MAAM,WAAW,4BAA4B;IAC3C,aAAa,EAAE,uCAAuC,CAAC;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,KAAK,CAAC;QAChB,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAC;QAAC,wBAAwB,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAC9H,OAAO,EAAE,MAAM,CAAC;QAAC,oBAAoB,EAAE,MAAM,CAAC;QAAC,qBAAqB,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,6BAA6B,CAAC;QAClH,SAAS,EAAE,MAAM,EAAE,CAAC;QAAC,qBAAqB,EAAE,MAAM,CAAC;QAAC,qBAAqB,EAAE,MAAM,EAAE,CAAC;QACpF,gBAAgB,EAAE,WAAW,CAAC,8BAA8B,CAAC,kBAAkB,CAAC,CAAC,CAAC;QAClF,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,WAAW,GAAG,gBAAgB,GAAG,SAAS,CAAC;KAC1E,CAAC,CAAC;IACH,MAAM,EAAE;QAAE,gBAAgB,EAAE,CAAC,CAAC;QAAC,2BAA2B,EAAE,IAAI,CAAC;QAAC,uBAAuB,EAAE,IAAI,CAAC;QAAC,sBAAsB,EAAE,KAAK,CAAA;KAAE,CAAC;IACjI,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,2BAA2B;IAC1C,mBAAmB,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAA;KAAE,CAAC,CAAC,CAAC;IAC1G,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAAC;IAC5E,OAAO,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACjE,gBAAgB,CAAC,IAAI,OAAO,CAAC,4BAA4B,CAAC,CAAC;IAC3D,MAAM,CAAC,MAAM,EAAE,oBAAoB,EAAE,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,4BAA4B,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACvJ;AAED,wBAAgB,iCAAiC,CAAC,OAAO,EAAE;IACzD,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB,GAAG,2BAA2B,CAqD9B;AAED,MAAM,WAAW,iCAAiC;IAChD,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAAC;IAC7D,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAED,qBAAa,uCAAwC,YAAW,iCAAiC;;IAGzF,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;IAK5D,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9D,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG3C;AAED,qBAAa,qCAAsC,YAAW,iCAAiC;IACjF,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,MAAM;IAIxC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;IAS5D,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ9D,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C,OAAO,CAAC,IAAI;CAGb;AAED,MAAM,WAAW,oCAAoC;IACnD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,4BAA4B,EAAE,MAAM,CAAC;IACrC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,qBAAa,8BAA8B;;
|
|
1
|
+
{"version":3,"file":"managed-workflow-harness.d.ts","sourceRoot":"","sources":["../../../../onegent-runtime/src/managed-workflow-harness.ts"],"names":[],"mappings":"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"}
|
|
@@ -99,15 +99,19 @@ export class ManagedBusinessWorkflowHarness {
|
|
|
99
99
|
#checkpoints;
|
|
100
100
|
#evaluate;
|
|
101
101
|
#maxConcurrency;
|
|
102
|
+
#supportedModes;
|
|
102
103
|
#activeTick;
|
|
103
104
|
constructor(options) {
|
|
104
105
|
this.#client = options.client;
|
|
105
106
|
this.#checkpoints = options.checkpoints;
|
|
106
107
|
this.#evaluate = options.evaluate;
|
|
107
108
|
this.#maxConcurrency = options.maxConcurrency ?? 4;
|
|
109
|
+
this.#supportedModes = new Set(options.supportedModes ?? ["REPLAY", "SHADOW"]);
|
|
108
110
|
if (!Number.isSafeInteger(this.#maxConcurrency) || this.#maxConcurrency < 1 || this.#maxConcurrency > 16) {
|
|
109
111
|
throw new Error("Managed Workflow Harness maxConcurrency must be between 1 and 16.");
|
|
110
112
|
}
|
|
113
|
+
if (!this.#supportedModes.size)
|
|
114
|
+
throw new Error("Managed Workflow Harness requires at least one supported evaluation mode.");
|
|
111
115
|
}
|
|
112
116
|
tick() {
|
|
113
117
|
if (this.#activeTick)
|
|
@@ -129,7 +133,7 @@ export class ManagedBusinessWorkflowHarness {
|
|
|
129
133
|
limitations.push(`Workflow ${workflow.id} was not scheduled because its authoritative Run inspection was truncated.`);
|
|
130
134
|
break;
|
|
131
135
|
}
|
|
132
|
-
const ready = plan.readyEvaluations.filter((evaluation) => !seen.has(checkpointKey(plan, evaluation)));
|
|
136
|
+
const ready = plan.readyEvaluations.filter((evaluation) => this.#supportedModes.has(evaluation.mode) && !seen.has(checkpointKey(plan, evaluation)));
|
|
133
137
|
if (!ready.length)
|
|
134
138
|
break;
|
|
135
139
|
const results = await mapLimit(ready, this.#maxConcurrency, async (evaluation) => {
|
|
@@ -171,7 +175,7 @@ export class ManagedBusinessWorkflowHarness {
|
|
|
171
175
|
limitations: ["This client does not expose Nora Autopilot dispatches."],
|
|
172
176
|
};
|
|
173
177
|
validateAutopilotPlan(autopilot);
|
|
174
|
-
const readyDispatches = autopilot.dispatches.filter((dispatch) => dispatch.status === "READY");
|
|
178
|
+
const readyDispatches = autopilot.dispatches.filter((dispatch) => dispatch.status === "READY" && this.#supportedModes.has(dispatch.mode));
|
|
175
179
|
const autopilotResults = await mapLimit(readyDispatches, this.#maxConcurrency, async (dispatch) => {
|
|
176
180
|
const evaluation = {
|
|
177
181
|
nodeId: `autopilot:${dispatch.id}`,
|