@oxygen-agent/cli 1.591.1 → 1.615.0
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.d.ts +18 -0
- package/dist/command-manifest.js +106 -5
- package/dist/help.js +2 -1
- package/dist/index.js +273 -38
- package/dist/skills.d.ts +6 -0
- package/dist/skills.js +200 -1
- package/node_modules/@oxygen/shared/dist/capability-discovery.d.ts +36 -0
- package/node_modules/@oxygen/shared/dist/capability-discovery.js +766 -0
- package/node_modules/@oxygen/shared/dist/cli-result.js +4 -3
- package/node_modules/@oxygen/shared/dist/index.d.ts +2 -0
- package/node_modules/@oxygen/shared/dist/index.js +2 -0
- package/node_modules/@oxygen/shared/dist/pricing-sheet.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/pricing-sheet.js +1 -1
- package/node_modules/@oxygen/shared/dist/recipes.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/recipes.js +4 -2
- package/node_modules/@oxygen/shared/dist/sequence-template.js +0 -0
- package/node_modules/@oxygen/shared/dist/sequence-terminal-events.d.ts +47 -0
- package/node_modules/@oxygen/shared/dist/sequence-terminal-events.js +70 -0
- package/node_modules/@oxygen/shared/dist/version.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/version.js +1 -1
- package/node_modules/@oxygen/workflows/dist/graph/lint.js +3 -0
- package/node_modules/@oxygen/workflows/dist/graph/manifest-schema.d.ts +5 -0
- package/node_modules/@oxygen/workflows/dist/graph/manifest-schema.js +5 -0
- package/node_modules/@oxygen/workflows/dist/graph/types.d.ts +2 -0
- package/node_modules/@oxygen/workflows/dist/index.d.ts +4 -0
- package/node_modules/@oxygen/workflows/dist/index.js +5 -0
- package/package.json +1 -1
|
@@ -26,8 +26,8 @@ export class OxygenError extends Error {
|
|
|
26
26
|
// 0 ok · 1 unclassified error · 2 usage / input validation · 3 auth or CLI
|
|
27
27
|
// compatibility (not_authenticated, cli_update_required) · 4 not found ·
|
|
28
28
|
// 5 provider / server failure · 6 rate limit (details.retry_after_seconds
|
|
29
|
-
// says how long to wait) · 7 approval / spend gate
|
|
30
|
-
//
|
|
29
|
+
// says how long to wait) · 7 approval / spend gate / subscription recovery
|
|
30
|
+
// (follow error.details.next_step) · 8 timeout.
|
|
31
31
|
export const CLI_EXIT_CODE_TABLE = {
|
|
32
32
|
0: "ok",
|
|
33
33
|
1: "unclassified error",
|
|
@@ -36,7 +36,7 @@ export const CLI_EXIT_CODE_TABLE = {
|
|
|
36
36
|
4: "not found",
|
|
37
37
|
5: "provider or server failure",
|
|
38
38
|
6: "rate limited (wait details.retry_after_seconds, then retry)",
|
|
39
|
-
7: "approval / spend gate
|
|
39
|
+
7: "approval / spend gate / subscription recovery (follow error.details.next_step)",
|
|
40
40
|
8: "timeout",
|
|
41
41
|
};
|
|
42
42
|
export function exitCodeForErrorCode(code) {
|
|
@@ -56,6 +56,7 @@ export function exitCodeForErrorCode(code) {
|
|
|
56
56
|
case "insufficient_credits":
|
|
57
57
|
case "workspace_credit_cap_exceeded":
|
|
58
58
|
case "byok_requires_paid_plan":
|
|
59
|
+
case "subscription_access_required":
|
|
59
60
|
return 7;
|
|
60
61
|
case "network_timeout":
|
|
61
62
|
return 8;
|
|
@@ -4,6 +4,7 @@ export { WORKFLOW_STATUS_CHANGE_METADATA_KEY, type WorkflowStatusChange, type Wo
|
|
|
4
4
|
export * from "./billing.js";
|
|
5
5
|
export * from "./billing-anchors.js";
|
|
6
6
|
export * from "./budget-scopes.js";
|
|
7
|
+
export * from "./capability-discovery.js";
|
|
7
8
|
export * from "./plan-limits.js";
|
|
8
9
|
export * from "./spend-safety.js";
|
|
9
10
|
export * from "./cell-format.js";
|
|
@@ -35,6 +36,7 @@ export * from "./networks.js";
|
|
|
35
36
|
export * from "./recipes.js";
|
|
36
37
|
export * from "./sequence-template.js";
|
|
37
38
|
export * from "./sequence-crm-events.js";
|
|
39
|
+
export * from "./sequence-terminal-events.js";
|
|
38
40
|
export * from "./call-outcomes.js";
|
|
39
41
|
export * from "./dial-guardrail-overrides.js";
|
|
40
42
|
export * from "./sequences.js";
|
|
@@ -4,6 +4,7 @@ export { WORKFLOW_STATUS_CHANGE_METADATA_KEY, describeWorkflowStatusChange, form
|
|
|
4
4
|
export * from "./billing.js";
|
|
5
5
|
export * from "./billing-anchors.js";
|
|
6
6
|
export * from "./budget-scopes.js";
|
|
7
|
+
export * from "./capability-discovery.js";
|
|
7
8
|
export * from "./plan-limits.js";
|
|
8
9
|
export * from "./spend-safety.js";
|
|
9
10
|
export * from "./cell-format.js";
|
|
@@ -35,6 +36,7 @@ export * from "./networks.js";
|
|
|
35
36
|
export * from "./recipes.js";
|
|
36
37
|
export * from "./sequence-template.js";
|
|
37
38
|
export * from "./sequence-crm-events.js";
|
|
39
|
+
export * from "./sequence-terminal-events.js";
|
|
38
40
|
export * from "./call-outcomes.js";
|
|
39
41
|
export * from "./dial-guardrail-overrides.js";
|
|
40
42
|
export * from "./sequences.js";
|
|
@@ -142,7 +142,7 @@ export declare const ENRICHMENT_CREDITS: {
|
|
|
142
142
|
readonly company_enrich_typical: 99;
|
|
143
143
|
readonly web_search: 5;
|
|
144
144
|
readonly page_scrape: 40;
|
|
145
|
-
readonly linkedin_profile_scrape:
|
|
145
|
+
readonly linkedin_profile_scrape: 25.5;
|
|
146
146
|
};
|
|
147
147
|
/** Editable calculator default: blended credits per fully-enriched row. */
|
|
148
148
|
export declare const ENRICHMENT_CREDITS_PER_ROW_TYPICAL = 100;
|
|
@@ -134,7 +134,7 @@ export const ENRICHMENT_CREDITS = {
|
|
|
134
134
|
company_enrich_typical: 99,
|
|
135
135
|
web_search: 5, // Serper
|
|
136
136
|
page_scrape: 40, // Firecrawl (wedge price)
|
|
137
|
-
linkedin_profile_scrape:
|
|
137
|
+
linkedin_profile_scrape: 25.5, // HarvestAPI Basic full-profile job, exactly 5x COGS
|
|
138
138
|
};
|
|
139
139
|
/** Editable calculator default: blended credits per fully-enriched row. */
|
|
140
140
|
export const ENRICHMENT_CREDITS_PER_ROW_TYPICAL = 100;
|
|
@@ -9,7 +9,7 @@ export declare const RECIPE_STATUSES: readonly ["draft", "beta", "stable", "depr
|
|
|
9
9
|
export type RecipeStatus = typeof RECIPE_STATUSES[number];
|
|
10
10
|
export declare const RECIPE_BENCHMARK_BASES: readonly ["estimate", "observed"];
|
|
11
11
|
export type RecipeBenchmarkBasis = typeof RECIPE_BENCHMARK_BASES[number];
|
|
12
|
-
export declare const RECIPE_PRIMITIVES: readonly ["knowledge-graph", "recipes", "records", "tables", "messages", "posts", "signals", "dashboards", "ads", "sequences", "publishing", "workflows", "observability"];
|
|
12
|
+
export declare const RECIPE_PRIMITIVES: readonly ["knowledge-graph", "recipes", "records", "tables", "messages", "posts", "signals", "dashboards", "ads", "tags", "sequences", "publishing", "workflows", "agents", "observability"];
|
|
13
13
|
export type RecipePrimitive = typeof RECIPE_PRIMITIVES[number];
|
|
14
14
|
export declare const RECIPE_PREREQUISITE_KINDS: readonly ["sender", "mailbox", "domain", "integration", "knowledge", "asset", "plan", "data"];
|
|
15
15
|
export type RecipePrerequisiteKind = typeof RECIPE_PREREQUISITE_KINDS[number];
|
|
@@ -37,8 +37,8 @@ export const RECIPE_STATUSES = ["draft", "beta", "stable", "deprecated"];
|
|
|
37
37
|
// Oxygen cohort data (with provenance). Estimates are the launch posture;
|
|
38
38
|
// observed values replace them as real usage accrues.
|
|
39
39
|
export const RECIPE_BENCHMARK_BASES = ["estimate", "observed"];
|
|
40
|
-
// The
|
|
41
|
-
// ADR 0006/0008). Control surfaces and External integrations are not
|
|
40
|
+
// The fifteen product primitives a recipe may exercise (five-layer model,
|
|
41
|
+
// ADR 0006/0008/0011/0012). Control surfaces and External integrations are not
|
|
42
42
|
// primitives and never appear here.
|
|
43
43
|
export const RECIPE_PRIMITIVES = [
|
|
44
44
|
"knowledge-graph",
|
|
@@ -50,9 +50,11 @@ export const RECIPE_PRIMITIVES = [
|
|
|
50
50
|
"signals",
|
|
51
51
|
"dashboards",
|
|
52
52
|
"ads",
|
|
53
|
+
"tags",
|
|
53
54
|
"sequences",
|
|
54
55
|
"publishing",
|
|
55
56
|
"workflows",
|
|
57
|
+
"agents",
|
|
56
58
|
"observability",
|
|
57
59
|
];
|
|
58
60
|
export const RECIPE_PREREQUISITE_KINDS = [
|
|
Binary file
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow-event contract emitted when one sequence enrollment becomes terminal.
|
|
3
|
+
*
|
|
4
|
+
* A terminal outcome (reply, bounce, failure, timeout) is not necessarily a
|
|
5
|
+
* literal node in the sequence graph. `endpoint_*` is therefore nullable and is
|
|
6
|
+
* populated only when the runtime reaches a visible graph endpoint: the trunk
|
|
7
|
+
* end, a branch-arm end, or an explicit stop step.
|
|
8
|
+
*/
|
|
9
|
+
export declare const SEQUENCE_TERMINAL_EVENT_SOURCE = "sequencer";
|
|
10
|
+
export declare const SEQUENCE_ENROLLMENT_TERMINAL_EVENT = "enrollment_terminal";
|
|
11
|
+
export declare const SEQUENCE_TERMINAL_STATUSES: readonly ["completed", "replied", "stopped", "failed", "excluded"];
|
|
12
|
+
export type SequenceTerminalStatus = (typeof SEQUENCE_TERMINAL_STATUSES)[number];
|
|
13
|
+
export declare const SEQUENCE_TERMINAL_ENDPOINT_KINDS: readonly ["end", "branch_end", "stop"];
|
|
14
|
+
export type SequenceTerminalEndpointKind = (typeof SEQUENCE_TERMINAL_ENDPOINT_KINDS)[number];
|
|
15
|
+
export type SequenceTerminalBranchArm = "then" | "else";
|
|
16
|
+
export type SequenceTerminalEndpoint = {
|
|
17
|
+
id: string;
|
|
18
|
+
kind: SequenceTerminalEndpointKind;
|
|
19
|
+
stepId: string | null;
|
|
20
|
+
branchId: string | null;
|
|
21
|
+
branchArm: SequenceTerminalBranchArm | null;
|
|
22
|
+
};
|
|
23
|
+
export type SequenceEnrollmentTerminalPayload = {
|
|
24
|
+
occurred_at: string;
|
|
25
|
+
sequence_id: string;
|
|
26
|
+
enrollment_id: string;
|
|
27
|
+
status: SequenceTerminalStatus;
|
|
28
|
+
reason: string | null;
|
|
29
|
+
endpoint_id: string | null;
|
|
30
|
+
endpoint_kind: SequenceTerminalEndpointKind | null;
|
|
31
|
+
step_id: string | null;
|
|
32
|
+
branch_id: string | null;
|
|
33
|
+
branch_arm: SequenceTerminalBranchArm | null;
|
|
34
|
+
lead_name: string | null;
|
|
35
|
+
email: string | null;
|
|
36
|
+
linkedin_url: string | null;
|
|
37
|
+
};
|
|
38
|
+
export declare function sequenceEndEndpoint(): SequenceTerminalEndpoint;
|
|
39
|
+
export declare function sequenceBranchEndEndpoint(branchId: string, branchArm: SequenceTerminalBranchArm): SequenceTerminalEndpoint;
|
|
40
|
+
export declare function sequenceStopEndpoint(stepId: string): SequenceTerminalEndpoint;
|
|
41
|
+
export declare function readSequenceTerminalEndpoint(value: unknown): SequenceTerminalEndpoint | null;
|
|
42
|
+
export declare function sequenceTerminalEventIdempotencyKey(input: {
|
|
43
|
+
enrollmentId: string;
|
|
44
|
+
status: SequenceTerminalStatus;
|
|
45
|
+
endpointId?: string | null;
|
|
46
|
+
reason?: string | null;
|
|
47
|
+
}): string;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow-event contract emitted when one sequence enrollment becomes terminal.
|
|
3
|
+
*
|
|
4
|
+
* A terminal outcome (reply, bounce, failure, timeout) is not necessarily a
|
|
5
|
+
* literal node in the sequence graph. `endpoint_*` is therefore nullable and is
|
|
6
|
+
* populated only when the runtime reaches a visible graph endpoint: the trunk
|
|
7
|
+
* end, a branch-arm end, or an explicit stop step.
|
|
8
|
+
*/
|
|
9
|
+
export const SEQUENCE_TERMINAL_EVENT_SOURCE = "sequencer";
|
|
10
|
+
export const SEQUENCE_ENROLLMENT_TERMINAL_EVENT = "enrollment_terminal";
|
|
11
|
+
export const SEQUENCE_TERMINAL_STATUSES = [
|
|
12
|
+
"completed",
|
|
13
|
+
"replied",
|
|
14
|
+
"stopped",
|
|
15
|
+
"failed",
|
|
16
|
+
"excluded",
|
|
17
|
+
];
|
|
18
|
+
export const SEQUENCE_TERMINAL_ENDPOINT_KINDS = ["end", "branch_end", "stop"];
|
|
19
|
+
export function sequenceEndEndpoint() {
|
|
20
|
+
return {
|
|
21
|
+
id: "end",
|
|
22
|
+
kind: "end",
|
|
23
|
+
stepId: null,
|
|
24
|
+
branchId: null,
|
|
25
|
+
branchArm: null,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export function sequenceBranchEndEndpoint(branchId, branchArm) {
|
|
29
|
+
return {
|
|
30
|
+
id: `end:${branchId}:${branchArm}`,
|
|
31
|
+
kind: "branch_end",
|
|
32
|
+
stepId: null,
|
|
33
|
+
branchId,
|
|
34
|
+
branchArm,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export function sequenceStopEndpoint(stepId) {
|
|
38
|
+
return {
|
|
39
|
+
id: stepId,
|
|
40
|
+
kind: "stop",
|
|
41
|
+
stepId,
|
|
42
|
+
branchId: null,
|
|
43
|
+
branchArm: null,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export function readSequenceTerminalEndpoint(value) {
|
|
47
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
48
|
+
return null;
|
|
49
|
+
const row = value;
|
|
50
|
+
const id = typeof row.id === "string" ? row.id.trim() : "";
|
|
51
|
+
const kind = row.kind;
|
|
52
|
+
if (!id || !SEQUENCE_TERMINAL_ENDPOINT_KINDS.includes(kind))
|
|
53
|
+
return null;
|
|
54
|
+
const branchArm = row.branchArm === "then" || row.branchArm === "else" ? row.branchArm : null;
|
|
55
|
+
return {
|
|
56
|
+
id,
|
|
57
|
+
kind: kind,
|
|
58
|
+
stepId: typeof row.stepId === "string" && row.stepId.trim() ? row.stepId.trim() : null,
|
|
59
|
+
branchId: typeof row.branchId === "string" && row.branchId.trim() ? row.branchId.trim() : null,
|
|
60
|
+
branchArm,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export function sequenceTerminalEventIdempotencyKey(input) {
|
|
64
|
+
return [
|
|
65
|
+
"sequence-terminal",
|
|
66
|
+
input.enrollmentId,
|
|
67
|
+
input.status,
|
|
68
|
+
input.endpointId ?? input.reason ?? "terminal",
|
|
69
|
+
].join(":");
|
|
70
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const OXYGEN_VERSION = "1.
|
|
1
|
+
export const OXYGEN_VERSION = "1.615.0";
|
|
2
2
|
// The GLOBAL CLI compatibility floor: the oldest CLI allowed to call any
|
|
3
3
|
// operational route. Raising it hard-rejects every older CLI from the entire
|
|
4
4
|
// product, so it obeys one law, enforced by scripts/ci/cli-min-version-gate.mjs:
|
|
@@ -335,6 +335,9 @@ function lintToolNode(node, path, add, options) {
|
|
|
335
335
|
if (node.mode !== undefined && (typeof node.mode !== "string" || !STEP_MODES.has(node.mode))) {
|
|
336
336
|
add(`${path}.mode`, "invalid_step_mode", "Node mode is invalid.");
|
|
337
337
|
}
|
|
338
|
+
if (node.connection_id !== undefined && !isNonEmptyString(node.connection_id)) {
|
|
339
|
+
add(`${path}.connection_id`, "invalid_connection_id", "Tool node connection_id must be a non-empty string.");
|
|
340
|
+
}
|
|
338
341
|
validateOptionalMaxCredits(node.max_credits, `${path}.max_credits`, add);
|
|
339
342
|
validateValueRefRecord(node.params, `${path}.params`, add);
|
|
340
343
|
}
|
|
@@ -108,6 +108,11 @@ export declare const workflowGraphManifestSchema: {
|
|
|
108
108
|
readonly mode: {
|
|
109
109
|
readonly enum: readonly ["dry_run", "live", "smoke_test"];
|
|
110
110
|
};
|
|
111
|
+
readonly connection_id: {
|
|
112
|
+
readonly type: "string";
|
|
113
|
+
readonly minLength: 1;
|
|
114
|
+
readonly description: "tool nodes: optional active organization connection id to pin for execution.";
|
|
115
|
+
};
|
|
111
116
|
readonly max_credits: {
|
|
112
117
|
readonly type: "number";
|
|
113
118
|
readonly exclusiveMinimum: 0;
|
|
@@ -111,6 +111,11 @@ const nodeSchema = {
|
|
|
111
111
|
description: "tool nodes: must equal the tool's canonical effect.",
|
|
112
112
|
},
|
|
113
113
|
mode: { enum: ["dry_run", "live", "smoke_test"] },
|
|
114
|
+
connection_id: {
|
|
115
|
+
type: "string",
|
|
116
|
+
minLength: 1,
|
|
117
|
+
description: "tool nodes: optional active organization connection id to pin for execution.",
|
|
118
|
+
},
|
|
114
119
|
max_credits: { type: "number", exclusiveMinimum: 0, description: "Per-node managed-credit ceiling." },
|
|
115
120
|
params: {
|
|
116
121
|
type: "object",
|
|
@@ -139,6 +139,8 @@ export type WorkflowGraphNode =
|
|
|
139
139
|
tool: string;
|
|
140
140
|
effect: WorkflowStepEffect;
|
|
141
141
|
mode?: WorkflowMode;
|
|
142
|
+
/** Pin this invocation to one active organization integration connection. */
|
|
143
|
+
connection_id?: string;
|
|
142
144
|
/** Per-node managed-credit ceiling, same semantics as v1 tool steps. */
|
|
143
145
|
max_credits?: number;
|
|
144
146
|
params: Record<string, WorkflowValueRef>;
|
|
@@ -74,6 +74,8 @@ export type WorkflowToolStepManifest = {
|
|
|
74
74
|
tool: string;
|
|
75
75
|
effect: WorkflowStepEffect;
|
|
76
76
|
mode?: WorkflowMode;
|
|
77
|
+
/** Pin this invocation to one active organization integration connection. */
|
|
78
|
+
connection_id?: string;
|
|
77
79
|
payload_source: string;
|
|
78
80
|
max_credits?: number;
|
|
79
81
|
};
|
|
@@ -249,6 +251,7 @@ export type WorkflowToolStepDefinition = {
|
|
|
249
251
|
tool: string;
|
|
250
252
|
effect?: WorkflowStepEffect;
|
|
251
253
|
mode?: WorkflowMode;
|
|
254
|
+
connectionId?: string;
|
|
252
255
|
maxCredits?: number;
|
|
253
256
|
payload: WorkflowFunction;
|
|
254
257
|
};
|
|
@@ -341,6 +344,7 @@ export declare function toolStep(input: {
|
|
|
341
344
|
tool: string;
|
|
342
345
|
effect?: WorkflowStepEffect;
|
|
343
346
|
mode?: WorkflowMode;
|
|
347
|
+
connectionId?: string;
|
|
344
348
|
maxCredits?: number;
|
|
345
349
|
payload: WorkflowFunction;
|
|
346
350
|
}): WorkflowToolStepDefinition;
|
|
@@ -166,6 +166,7 @@ export function toolStep(input) {
|
|
|
166
166
|
tool: input.tool,
|
|
167
167
|
...(input.effect ? { effect: input.effect } : {}),
|
|
168
168
|
...(input.mode ? { mode: input.mode } : {}),
|
|
169
|
+
...(input.connectionId !== undefined ? { connectionId: input.connectionId } : {}),
|
|
169
170
|
...(input.maxCredits != null ? { maxCredits: input.maxCredits } : {}),
|
|
170
171
|
payload: input.payload,
|
|
171
172
|
};
|
|
@@ -260,6 +261,7 @@ definition, options = {}) {
|
|
|
260
261
|
tool: step.tool,
|
|
261
262
|
effect: step.effect ?? "external_read",
|
|
262
263
|
...(step.mode ? { mode: step.mode } : {}),
|
|
264
|
+
...(step.connectionId !== undefined ? { connection_id: step.connectionId } : {}),
|
|
263
265
|
...(step.maxCredits != null ? { max_credits: step.maxCredits } : {}),
|
|
264
266
|
payload_source: serializeWorkflowFunction(step.payload, `steps.${step.id}.payload`),
|
|
265
267
|
};
|
|
@@ -440,6 +442,9 @@ value, options = {}) {
|
|
|
440
442
|
&& step.mode !== "smoke_test") {
|
|
441
443
|
add(`${path}.mode`, "invalid_step_mode", "Step mode is invalid.");
|
|
442
444
|
}
|
|
445
|
+
if (step.connection_id !== undefined && !isNonEmptyString(step.connection_id)) {
|
|
446
|
+
add(`${path}.connection_id`, "invalid_connection_id", "Tool step connection_id must be a non-empty string.");
|
|
447
|
+
}
|
|
443
448
|
validateOptionalMaxCredits(step.max_credits, `${path}.max_credits`, add);
|
|
444
449
|
return;
|
|
445
450
|
}
|