@oxygen-agent/cli 1.750.4 → 1.782.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/README.md +1 -1
- package/dist/command-manifest.js +11 -1
- package/dist/help.js +8 -0
- package/dist/index.js +492 -96
- package/node_modules/@oxygen/shared/dist/billing.d.ts +88 -46
- package/node_modules/@oxygen/shared/dist/billing.js +134 -74
- package/node_modules/@oxygen/shared/dist/capability-discovery.js +12 -4
- package/node_modules/@oxygen/shared/dist/cli-result.js +1 -0
- package/node_modules/@oxygen/shared/dist/copilot-journeys.d.ts +8 -0
- package/node_modules/@oxygen/shared/dist/copilot-journeys.js +23 -5
- package/node_modules/@oxygen/shared/dist/future-signup-events.d.ts +13 -2
- package/node_modules/@oxygen/shared/dist/future-signup-events.js +17 -2
- package/node_modules/@oxygen/shared/dist/future-signup-lifecycle-projection.d.ts +106 -1
- package/node_modules/@oxygen/shared/dist/future-signup-lifecycle-projection.js +156 -45
- package/node_modules/@oxygen/shared/dist/index.d.ts +5 -0
- package/node_modules/@oxygen/shared/dist/index.js +5 -0
- package/node_modules/@oxygen/shared/dist/object-storage.d.ts +33 -0
- package/node_modules/@oxygen/shared/dist/object-storage.js +69 -4
- package/node_modules/@oxygen/shared/dist/person-name.d.ts +40 -0
- package/node_modules/@oxygen/shared/dist/person-name.js +23 -0
- package/node_modules/@oxygen/shared/dist/plan-capabilities.d.ts +82 -0
- package/node_modules/@oxygen/shared/dist/plan-capabilities.js +130 -0
- package/node_modules/@oxygen/shared/dist/plan-limits.d.ts +2 -2
- package/node_modules/@oxygen/shared/dist/plan-limits.js +18 -2
- package/node_modules/@oxygen/shared/dist/pricing-sheet.d.ts +50 -56
- package/node_modules/@oxygen/shared/dist/pricing-sheet.js +77 -90
- package/node_modules/@oxygen/shared/dist/pricing-snapshot.generated.d.ts +62 -0
- package/node_modules/@oxygen/shared/dist/pricing-snapshot.generated.js +91 -0
- package/node_modules/@oxygen/shared/dist/provider-funding-errors.d.ts +44 -0
- package/node_modules/@oxygen/shared/dist/provider-funding-errors.js +81 -0
- package/node_modules/@oxygen/shared/dist/publishing-limits.d.ts +24 -0
- package/node_modules/@oxygen/shared/dist/publishing-limits.js +24 -0
- package/node_modules/@oxygen/shared/dist/spend-safety.d.ts +27 -6
- package/node_modules/@oxygen/shared/dist/spend-safety.js +34 -6
- package/node_modules/@oxygen/shared/dist/table-capacity.d.ts +13 -0
- package/node_modules/@oxygen/shared/dist/table-capacity.js +14 -0
- package/node_modules/@oxygen/shared/dist/version.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/version.js +6 -3
- package/node_modules/@oxygen/shared/package.json +10 -0
- package/node_modules/@oxygen/workflows/dist/graph/diff.d.ts +33 -0
- package/node_modules/@oxygen/workflows/dist/graph/diff.js +75 -0
- package/node_modules/@oxygen/workflows/dist/graph/expression.js +17 -1
- package/node_modules/@oxygen/workflows/dist/graph/index.d.ts +1 -0
- package/node_modules/@oxygen/workflows/dist/graph/index.js +1 -0
- package/node_modules/@oxygen/workflows/dist/graph/lint.js +30 -28
- package/node_modules/@oxygen/workflows/dist/graph/manifest-schema.d.ts +2 -2
- package/node_modules/@oxygen/workflows/dist/graph/manifest-schema.js +1 -1
- package/node_modules/@oxygen/workflows/dist/graph/remap.js +0 -5
- package/node_modules/@oxygen/workflows/dist/graph/topology.d.ts +27 -0
- package/node_modules/@oxygen/workflows/dist/graph/topology.js +95 -0
- package/node_modules/@oxygen/workflows/dist/graph/types.d.ts +27 -8
- package/node_modules/@oxygen/workflows/dist/graph/types.js +2 -4
- package/node_modules/@oxygen/workflows/dist/index.js +0 -1
- package/node_modules/@oxygen/workflows/dist/portable.js +0 -9
- package/package.json +1 -1
|
@@ -282,6 +282,101 @@ export function dominatingNodeIds(graph, targetNodeId) {
|
|
|
282
282
|
}
|
|
283
283
|
return dominators.get(targetNodeId) ?? new Set();
|
|
284
284
|
}
|
|
285
|
+
/** Add every forward-graph predecessor of `startIds` to `selected`. */
|
|
286
|
+
function addForwardAncestors(startIds, incoming, selected) {
|
|
287
|
+
const queue = [...startIds];
|
|
288
|
+
let changed = false;
|
|
289
|
+
while (queue.length > 0) {
|
|
290
|
+
const current = queue.pop();
|
|
291
|
+
if (current === undefined || selected.has(current))
|
|
292
|
+
continue;
|
|
293
|
+
selected.add(current);
|
|
294
|
+
changed = true;
|
|
295
|
+
for (const predecessor of incoming.get(current) ?? [])
|
|
296
|
+
queue.push(predecessor);
|
|
297
|
+
}
|
|
298
|
+
return changed;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Plan a safe selected-node test over the canonical graph.
|
|
302
|
+
*
|
|
303
|
+
* The slice contains the target and every possible predecessor, not every node
|
|
304
|
+
* that happens to appear earlier in topological order. Legal loop back-edges are
|
|
305
|
+
* ignored while finding predecessors so selecting a node halfway through a loop
|
|
306
|
+
* does not accidentally pull later body nodes into the test. Conversely, when a
|
|
307
|
+
* completed loop is upstream of the target (or is itself the target), its whole
|
|
308
|
+
* body is required because the loop's output includes those executions.
|
|
309
|
+
*/
|
|
310
|
+
export function planWorkflowGraphNodeTest(graph, targetNodeId) {
|
|
311
|
+
const nodes = nodeIndex(graph);
|
|
312
|
+
const target = nodes.get(targetNodeId);
|
|
313
|
+
if (!target) {
|
|
314
|
+
return {
|
|
315
|
+
ok: false,
|
|
316
|
+
code: "workflow_test_target_not_found",
|
|
317
|
+
message: `Workflow node '${targetNodeId}' does not exist in this revision.`,
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
if (isTriggerNode(target)) {
|
|
321
|
+
return {
|
|
322
|
+
ok: false,
|
|
323
|
+
code: "workflow_test_target_is_trigger",
|
|
324
|
+
message: "Choose an executable workflow step, not the trigger node.",
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
if (target.disabled === true) {
|
|
328
|
+
return {
|
|
329
|
+
ok: false,
|
|
330
|
+
code: "workflow_test_target_disabled",
|
|
331
|
+
message: `Workflow node '${targetNodeId}' is disabled and cannot be tested.`,
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
if (!reachableNodeIds(graph).has(targetNodeId)) {
|
|
335
|
+
return {
|
|
336
|
+
ok: false,
|
|
337
|
+
code: "workflow_test_target_unreachable",
|
|
338
|
+
message: `Workflow node '${targetNodeId}' is not reachable from the trigger.`,
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
const forward = forwardOutgoing(graph);
|
|
342
|
+
const incoming = new Map();
|
|
343
|
+
for (const id of nodes.keys())
|
|
344
|
+
incoming.set(id, []);
|
|
345
|
+
for (const [source, edges] of forward) {
|
|
346
|
+
for (const edge of edges)
|
|
347
|
+
incoming.get(edge.target)?.push(source);
|
|
348
|
+
}
|
|
349
|
+
const selected = new Set();
|
|
350
|
+
addForwardAncestors([targetNodeId], incoming, selected);
|
|
351
|
+
const loopBodies = graph.nodes
|
|
352
|
+
.filter(isLoopNode)
|
|
353
|
+
.map((loop) => ({ loop, body: loopBodyNodeIds(graph, loop.id) }));
|
|
354
|
+
let expanded = true;
|
|
355
|
+
while (expanded) {
|
|
356
|
+
expanded = false;
|
|
357
|
+
for (const { loop, body } of loopBodies) {
|
|
358
|
+
if (!selected.has(loop.id) || body.has(targetNodeId))
|
|
359
|
+
continue;
|
|
360
|
+
if (addForwardAncestors(body, incoming, selected))
|
|
361
|
+
expanded = true;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
const nodeIds = graph.nodes
|
|
365
|
+
.map((node) => node.id)
|
|
366
|
+
.filter((id) => selected.has(id));
|
|
367
|
+
return {
|
|
368
|
+
ok: true,
|
|
369
|
+
plan: {
|
|
370
|
+
targetNodeId,
|
|
371
|
+
nodeIds,
|
|
372
|
+
manifest: {
|
|
373
|
+
...graph,
|
|
374
|
+
nodes: graph.nodes.filter((node) => selected.has(node.id)),
|
|
375
|
+
edges: graph.edges.filter((edge) => selected.has(edge.source) && selected.has(edge.target)),
|
|
376
|
+
},
|
|
377
|
+
},
|
|
378
|
+
};
|
|
379
|
+
}
|
|
285
380
|
/**
|
|
286
381
|
* Illegal cycles: one entry per strongly connected component that still contains
|
|
287
382
|
* a cycle once legal loop back-edges are removed.
|
|
@@ -3,6 +3,32 @@ export declare const WORKFLOW_GRAPH_MANIFEST_VERSION = 2;
|
|
|
3
3
|
export declare const WORKFLOW_GRAPH_COMPILER_VERSION = "oxygen-workflows-v2";
|
|
4
4
|
export declare const PORTABLE_WORKFLOW_DEFINITION_VERSION = 1;
|
|
5
5
|
export declare const PORTABLE_WORKFLOW_DEFINITION_COMPILER_VERSION = "oxygen-workflow-definition-v1";
|
|
6
|
+
/** Source-run metadata key for the exact non-live graph scope a test executed. */
|
|
7
|
+
export declare const WORKFLOW_TEST_SCOPE_METADATA_KEY = "workflow_test_scope";
|
|
8
|
+
/**
|
|
9
|
+
* Optional execution scope for a non-live Workflow call.
|
|
10
|
+
*
|
|
11
|
+
* Omission keeps the historic whole-workflow behavior. A node scope is a
|
|
12
|
+
* server-planned backward slice of the same immutable graph revision; callers
|
|
13
|
+
* never submit a second graph or a list of nodes to trust.
|
|
14
|
+
*/
|
|
15
|
+
export type WorkflowTestScope = {
|
|
16
|
+
type: "workflow";
|
|
17
|
+
} | {
|
|
18
|
+
type: "node";
|
|
19
|
+
node_id: string;
|
|
20
|
+
};
|
|
21
|
+
/** Durable evidence recorded on the source run after the server plans a test. */
|
|
22
|
+
export type WorkflowTestScopeReceipt = WorkflowTestScope & {
|
|
23
|
+
source_hash: string;
|
|
24
|
+
planned_node_ids: string[];
|
|
25
|
+
/**
|
|
26
|
+
* The nodes this scope deliberately excludes. Recorded so "the downstream step
|
|
27
|
+
* did not run" is something the product states, not something a reader infers
|
|
28
|
+
* from a missing row in the step list.
|
|
29
|
+
*/
|
|
30
|
+
excluded_node_ids?: string[];
|
|
31
|
+
};
|
|
6
32
|
export declare const RESERVED_NODE_IDS: ReadonlySet<string>;
|
|
7
33
|
/**
|
|
8
34
|
* Named Code inputs and declared output fields become dotted scope paths and
|
|
@@ -356,13 +382,7 @@ export type WorkflowGraphNode =
|
|
|
356
382
|
request?: Record<string, WorkflowValueRef>;
|
|
357
383
|
})
|
|
358
384
|
/** Legacy source, imported durable recipe, or typed oxygen-js-v1 code. */
|
|
359
|
-
| WorkflowGraphCodeNode
|
|
360
|
-
/** Calls another workflow as a child run. */
|
|
361
|
-
| (WorkflowGraphNodeBase & {
|
|
362
|
-
kind: "workflow";
|
|
363
|
-
workflow_id: string;
|
|
364
|
-
input: Record<string, WorkflowValueRef>;
|
|
365
|
-
});
|
|
385
|
+
| WorkflowGraphCodeNode;
|
|
366
386
|
export type WorkflowGraphNodeKind = WorkflowGraphNode["kind"];
|
|
367
387
|
/** Narrow a node union member by its `kind` discriminant. */
|
|
368
388
|
export type WorkflowGraphNodeOfKind<K extends WorkflowGraphNodeKind> = Extract<WorkflowGraphNode, {
|
|
@@ -455,5 +475,4 @@ export declare function isTriggerNode(node: WorkflowGraphNode): node is Workflow
|
|
|
455
475
|
export declare function isToolNode(node: WorkflowGraphNode): node is WorkflowGraphNodeOfKind<"tool">;
|
|
456
476
|
export declare function isSwitchNode(node: WorkflowGraphNode): node is WorkflowGraphNodeOfKind<"switch">;
|
|
457
477
|
export declare function isLoopNode(node: WorkflowGraphNode): node is WorkflowGraphNodeOfKind<"loop">;
|
|
458
|
-
export declare function isWorkflowSubgraphNode(node: WorkflowGraphNode): node is WorkflowGraphNodeOfKind<"workflow">;
|
|
459
478
|
export {};
|
|
@@ -2,6 +2,8 @@ export const WORKFLOW_GRAPH_MANIFEST_VERSION = 2;
|
|
|
2
2
|
export const WORKFLOW_GRAPH_COMPILER_VERSION = "oxygen-workflows-v2";
|
|
3
3
|
export const PORTABLE_WORKFLOW_DEFINITION_VERSION = 1;
|
|
4
4
|
export const PORTABLE_WORKFLOW_DEFINITION_COMPILER_VERSION = "oxygen-workflow-definition-v1";
|
|
5
|
+
/** Source-run metadata key for the exact non-live graph scope a test executed. */
|
|
6
|
+
export const WORKFLOW_TEST_SCOPE_METADATA_KEY = "workflow_test_scope";
|
|
5
7
|
// Node ids become keys on the runtime scope object (`steps.<id>.output`), exactly
|
|
6
8
|
// as v1 step ids become keys on ctx.steps. The same JavaScript-internals collision
|
|
7
9
|
// applies: a node named `__proto__` would silently lose its output.
|
|
@@ -63,7 +65,6 @@ export const MAX_WORKFLOW_LOOP_ITERATIONS = 1_000;
|
|
|
63
65
|
*/
|
|
64
66
|
export const BILLABLE_WORKFLOW_GRAPH_NODE_KINDS = new Set([
|
|
65
67
|
"tool",
|
|
66
|
-
"workflow",
|
|
67
68
|
]);
|
|
68
69
|
/** Whether a v2 node of this kind draws an automation action when it executes. */
|
|
69
70
|
export function workflowGraphNodeKindBills(kind) {
|
|
@@ -159,6 +160,3 @@ export function isSwitchNode(node) {
|
|
|
159
160
|
export function isLoopNode(node) {
|
|
160
161
|
return isNodeOfKind(node, "loop");
|
|
161
162
|
}
|
|
162
|
-
export function isWorkflowSubgraphNode(node) {
|
|
163
|
-
return isNodeOfKind(node, "workflow");
|
|
164
|
-
}
|
|
@@ -1938,7 +1938,6 @@ export function workflowManifestCanInvokeTool(manifest) {
|
|
|
1938
1938
|
&& manifest.tools_used.some((toolId) => isNonEmptyString(toolId));
|
|
1939
1939
|
const viaGraph = Array.isArray(manifest.nodes)
|
|
1940
1940
|
&& manifest.nodes.some((node) => isRecord(node) && (node.kind === "tool"
|
|
1941
|
-
|| node.kind === "workflow"
|
|
1942
1941
|
|| (isRecord(node.recipe)
|
|
1943
1942
|
&& Array.isArray(node.recipe.tools_used)
|
|
1944
1943
|
&& node.recipe.tools_used.some((toolId) => isNonEmptyString(toolId)))));
|
|
@@ -69,13 +69,6 @@ function portableNodeIssue(node, index) {
|
|
|
69
69
|
message: "Legacy execution context cannot be represented as a portable editable graph.",
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
|
-
if (node.kind === "workflow") {
|
|
73
|
-
return {
|
|
74
|
-
path: `$.graph.nodes.${index}`,
|
|
75
|
-
code: "workflow_node_not_portable",
|
|
76
|
-
message: "Child-workflow nodes are not executable yet and cannot be exported as a portable definition.",
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
72
|
return null;
|
|
80
73
|
}
|
|
81
74
|
function valueRefUsesWorkspaceAsset(ref) {
|
|
@@ -114,8 +107,6 @@ function nodeUsesWorkspaceAsset(node) {
|
|
|
114
107
|
return node.code !== undefined
|
|
115
108
|
? Object.values(node.code.inputs).some(valueRefUsesWorkspaceAsset)
|
|
116
109
|
: Object.values(node.configuration ?? {}).some(valueRefUsesWorkspaceAsset);
|
|
117
|
-
case "workflow":
|
|
118
|
-
return Object.values(node.input).some(valueRefUsesWorkspaceAsset);
|
|
119
110
|
case "trigger":
|
|
120
111
|
case "merge":
|
|
121
112
|
return false;
|