@cargo-ai/cli 1.0.120 → 1.0.122
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 +2 -1
- package/build/api.d.ts +6 -1
- package/build/api.d.ts.map +1 -1
- package/build/commands/connection/action.d.ts +1 -1
- package/build/commands/connection/action.d.ts.map +1 -1
- package/build/commands/connection/action.js +4 -2
- package/build/commands/connection/index.d.ts +1 -1
- package/build/commands/connection/index.d.ts.map +1 -1
- package/build/commands/connection/index.js +4 -4
- package/build/commands/connection/integration.d.ts +1 -1
- package/build/commands/connection/integration.d.ts.map +1 -1
- package/build/commands/connection/integration.js +11 -5
- package/build/commands/connection/nativeIntegration.d.ts +1 -1
- package/build/commands/connection/nativeIntegration.d.ts.map +1 -1
- package/build/commands/connection/nativeIntegration.js +4 -2
- package/build/commands/content/file.d.ts.map +1 -1
- package/build/commands/content/file.js +163 -2
- package/build/commands/orchestration/action.d.ts +1 -1
- package/build/commands/orchestration/action.d.ts.map +1 -1
- package/build/commands/orchestration/action.js +100 -4
- package/build/commands/orchestration/index.d.ts +1 -1
- package/build/commands/orchestration/index.d.ts.map +1 -1
- package/build/commands/orchestration/index.js +2 -2
- package/build/commands/signedOutNotice.d.ts +4 -0
- package/build/commands/signedOutNotice.d.ts.map +1 -0
- package/build/commands/signedOutNotice.js +11 -0
- package/build/index.js +18 -3
- package/build/utils/actionDryRun.d.ts +90 -0
- package/build/utils/actionDryRun.d.ts.map +1 -0
- package/build/utils/actionDryRun.js +145 -0
- package/build/utils/sampleFromSchema.d.ts +15 -0
- package/build/utils/sampleFromSchema.d.ts.map +1 -0
- package/build/utils/sampleFromSchema.js +474 -0
- package/package.json +6 -5
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { type SampleSubject } from "./sampleFromSchema.js";
|
|
2
|
+
/** A single action runs as one node with this slug (`ACTION_NODE_SLUG`). */
|
|
3
|
+
export declare const DRY_RUN_NODE_SLUG = "action";
|
|
4
|
+
export declare const DRY_RUN_NOTE = "Sample data generated from the output schema. Nothing ran and no credits were used.";
|
|
5
|
+
export type DryRunCreditsCost = {
|
|
6
|
+
type: string;
|
|
7
|
+
cost: number;
|
|
8
|
+
unit?: string;
|
|
9
|
+
unitsCount?: number;
|
|
10
|
+
fixedCost?: number;
|
|
11
|
+
config?: {
|
|
12
|
+
jsonSchema?: unknown;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
/** The fields of an integration or native action this needs. */
|
|
16
|
+
export type DryRunActionDefinition = {
|
|
17
|
+
name?: string;
|
|
18
|
+
config?: {
|
|
19
|
+
schema?: unknown;
|
|
20
|
+
};
|
|
21
|
+
output?: {
|
|
22
|
+
schema?: unknown;
|
|
23
|
+
};
|
|
24
|
+
credits?: {
|
|
25
|
+
costs?: DryRunCreditsCost[];
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
export type DataValidation = {
|
|
29
|
+
valid: true;
|
|
30
|
+
} | {
|
|
31
|
+
valid: false;
|
|
32
|
+
errors: string[];
|
|
33
|
+
};
|
|
34
|
+
export type CreditsEstimate = {
|
|
35
|
+
/** What one call costs; for a metered price, one unit or one block of them. */
|
|
36
|
+
credits: number;
|
|
37
|
+
/** How the number was reached, and what it scales with when it does. */
|
|
38
|
+
formula: string;
|
|
39
|
+
};
|
|
40
|
+
export type DryRunResult = {
|
|
41
|
+
run: {
|
|
42
|
+
status: "success";
|
|
43
|
+
executions: {
|
|
44
|
+
nodeSlug: string;
|
|
45
|
+
title: string;
|
|
46
|
+
status: "success";
|
|
47
|
+
creditsUsedCount: number;
|
|
48
|
+
}[];
|
|
49
|
+
};
|
|
50
|
+
runContext: {
|
|
51
|
+
action: unknown;
|
|
52
|
+
};
|
|
53
|
+
runComputedConfigs: {
|
|
54
|
+
action: unknown;
|
|
55
|
+
};
|
|
56
|
+
dryRun: {
|
|
57
|
+
sample: true;
|
|
58
|
+
estimatedCredits: number;
|
|
59
|
+
creditsFormula: string;
|
|
60
|
+
note: string;
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Check `--data` against the action's input schema, the way the run would.
|
|
65
|
+
* A missing or empty schema accepts anything: the action takes no declared
|
|
66
|
+
* inputs, or declares them at run time.
|
|
67
|
+
*/
|
|
68
|
+
export declare function validateActionData(schema: unknown, data: unknown): DataValidation;
|
|
69
|
+
/**
|
|
70
|
+
* The price of one call, read the way billing reads it: the first cost entry
|
|
71
|
+
* whose `config.jsonSchema` the inputs match (an LLM model, a phone-or-email
|
|
72
|
+
* toggle), then that entry's shape.
|
|
73
|
+
*
|
|
74
|
+
* A metered price depends on what the call returns, so it is shown for one
|
|
75
|
+
* unit (or one block of them) with the formula that scales it.
|
|
76
|
+
*/
|
|
77
|
+
export declare function estimateCredits(costs: DryRunCreditsCost[] | undefined, data: unknown): CreditsEstimate;
|
|
78
|
+
/**
|
|
79
|
+
* Whether the action is about a company or a person, read off its slug and
|
|
80
|
+
* name, so a bare `name` in its output samples as the right kind of name.
|
|
81
|
+
*/
|
|
82
|
+
export declare function sampleSubjectFor(actionSlug: string, actionName: string | undefined): SampleSubject;
|
|
83
|
+
export declare function buildDryRunResult(input: {
|
|
84
|
+
title: string;
|
|
85
|
+
data: unknown;
|
|
86
|
+
outputSchema: unknown;
|
|
87
|
+
subject: SampleSubject;
|
|
88
|
+
estimate: CreditsEstimate;
|
|
89
|
+
}): DryRunResult;
|
|
90
|
+
//# sourceMappingURL=actionDryRun.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actionDryRun.d.ts","sourceRoot":"","sources":["../../src/utils/actionDryRun.ts"],"names":[],"mappings":"AASA,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE7E,4EAA4E;AAC5E,eAAO,MAAM,iBAAiB,WAAW,CAAC;AAE1C,eAAO,MAAM,YAAY,wFAC8D,CAAC;AAExF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CACnC,CAAC;AAEF,gEAAgE;AAChE,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC9B,MAAM,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC9B,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,iBAAiB,EAAE,CAAA;KAAE,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,cAAc,GACtB;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GACf;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEvC,MAAM,MAAM,eAAe,GAAG;IAC5B,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE;QACH,MAAM,EAAE,SAAS,CAAC;QAClB,UAAU,EAAE;YACV,QAAQ,EAAE,MAAM,CAAC;YACjB,KAAK,EAAE,MAAM,CAAC;YACd,MAAM,EAAE,SAAS,CAAC;YAClB,gBAAgB,EAAE,MAAM,CAAC;SAC1B,EAAE,CAAC;KACL,CAAC;IACF,UAAU,EAAE;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC;IAChC,kBAAkB,EAAE;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC;IACxC,MAAM,EAAE;QACN,MAAM,EAAE,IAAI,CAAC;QACb,gBAAgB,EAAE,MAAM,CAAC;QACzB,cAAc,EAAE,MAAM,CAAC;QACvB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,OAAO,EACf,IAAI,EAAE,OAAO,GACZ,cAAc,CAYhB;AAkBD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,iBAAiB,EAAE,GAAG,SAAS,EACtC,IAAI,EAAE,OAAO,GACZ,eAAe,CAiDjB;AAWD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,aAAa,CA2Bf;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,eAAe,CAAC;CAC3B,GAAG,YAAY,CAwBf"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// The pure half of `cargo-ai orchestration action execute --dry-run`: check the
|
|
2
|
+
// inputs against the action's own schema, price the call, and dress a sample
|
|
3
|
+
// output in the shape a real waited run returns. The command fetches the
|
|
4
|
+
// action definition and hands it here; nothing in this file touches the
|
|
5
|
+
// network.
|
|
6
|
+
import { validate as jsonSchemaValidate } from "jsonschema";
|
|
7
|
+
import { sampleFromSchema } from "./sampleFromSchema.js";
|
|
8
|
+
/** A single action runs as one node with this slug (`ACTION_NODE_SLUG`). */
|
|
9
|
+
export const DRY_RUN_NODE_SLUG = "action";
|
|
10
|
+
export const DRY_RUN_NOTE = "Sample data generated from the output schema. Nothing ran and no credits were used.";
|
|
11
|
+
/**
|
|
12
|
+
* Check `--data` against the action's input schema, the way the run would.
|
|
13
|
+
* A missing or empty schema accepts anything: the action takes no declared
|
|
14
|
+
* inputs, or declares them at run time.
|
|
15
|
+
*/
|
|
16
|
+
export function validateActionData(schema, data) {
|
|
17
|
+
if (isObject(schema) === false || Object.keys(schema).length === 0) {
|
|
18
|
+
return { valid: true };
|
|
19
|
+
}
|
|
20
|
+
const result = jsonSchemaValidate(data, schema);
|
|
21
|
+
if (result.valid === true) {
|
|
22
|
+
return { valid: true };
|
|
23
|
+
}
|
|
24
|
+
return { valid: false, errors: result.errors.map(formatValidationError) };
|
|
25
|
+
}
|
|
26
|
+
function formatValidationError(error) {
|
|
27
|
+
const path = error.property
|
|
28
|
+
.replace(/^instance\.?/, "")
|
|
29
|
+
.replace(/^\[/, "")
|
|
30
|
+
.replace(/\]\[/g, ".")
|
|
31
|
+
.replace(/[[\]]/g, "");
|
|
32
|
+
if (error.name === "required" && typeof error.argument === "string") {
|
|
33
|
+
const field = path === "" ? error.argument : `${path}.${error.argument}`;
|
|
34
|
+
return `Missing required field: ${field}`;
|
|
35
|
+
}
|
|
36
|
+
return `${path === "" ? "data" : path}: ${error.message}`;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The price of one call, read the way billing reads it: the first cost entry
|
|
40
|
+
* whose `config.jsonSchema` the inputs match (an LLM model, a phone-or-email
|
|
41
|
+
* toggle), then that entry's shape.
|
|
42
|
+
*
|
|
43
|
+
* A metered price depends on what the call returns, so it is shown for one
|
|
44
|
+
* unit (or one block of them) with the formula that scales it.
|
|
45
|
+
*/
|
|
46
|
+
export function estimateCredits(costs, data) {
|
|
47
|
+
if (costs === undefined || costs.length === 0) {
|
|
48
|
+
return { credits: 0, formula: "This action costs no credits." };
|
|
49
|
+
}
|
|
50
|
+
const cost = costs.find((entry) => {
|
|
51
|
+
if (entry.config === undefined || entry.config.jsonSchema === undefined) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
return (jsonSchemaValidate(data, entry.config.jsonSchema).valid === true);
|
|
55
|
+
});
|
|
56
|
+
if (cost === undefined) {
|
|
57
|
+
return {
|
|
58
|
+
credits: 0,
|
|
59
|
+
formula: "No price matches these inputs, so billing would charge nothing for them.",
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const fixedCost = cost.fixedCost === undefined ? 0 : cost.fixedCost;
|
|
63
|
+
const base = fixedCost === 0 ? "" : `${formatCredits(fixedCost)} + `;
|
|
64
|
+
if (cost.type === "unit") {
|
|
65
|
+
const unit = cost.unit === undefined ? "unit" : cost.unit;
|
|
66
|
+
return {
|
|
67
|
+
credits: roundCredits(fixedCost + cost.cost),
|
|
68
|
+
formula: `${base}${formatCredits(cost.cost)} × <${unit}s returned> credits (shown for 1 ${unit})`,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
if (cost.type === "package") {
|
|
72
|
+
const unit = cost.unit === undefined ? "unit" : cost.unit;
|
|
73
|
+
const unitsCount = cost.unitsCount === undefined ? 1 : cost.unitsCount;
|
|
74
|
+
return {
|
|
75
|
+
credits: roundCredits(fixedCost + cost.cost),
|
|
76
|
+
formula: `${base}${formatCredits(cost.cost)} × ceil(<${unit}s used> / ${String(unitsCount)}) credits (shown for one block of ${String(unitsCount)} ${unit}s)`,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
credits: roundCredits(cost.cost),
|
|
81
|
+
formula: `${formatCredits(cost.cost)} credits per call`,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/** Prices from the API (`0.175 + 0.025`) print without their float artifacts. */
|
|
85
|
+
function roundCredits(value) {
|
|
86
|
+
return Math.round(value * 10000) / 10000;
|
|
87
|
+
}
|
|
88
|
+
function formatCredits(value) {
|
|
89
|
+
return String(roundCredits(value));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Whether the action is about a company or a person, read off its slug and
|
|
93
|
+
* name, so a bare `name` in its output samples as the right kind of name.
|
|
94
|
+
*/
|
|
95
|
+
export function sampleSubjectFor(actionSlug, actionName) {
|
|
96
|
+
const text = `${actionSlug} ${actionName === undefined ? "" : actionName}`
|
|
97
|
+
.toLowerCase()
|
|
98
|
+
.replace(/[^a-z]/g, "");
|
|
99
|
+
if (text.includes("person") ||
|
|
100
|
+
text.includes("people") ||
|
|
101
|
+
text.includes("contact") ||
|
|
102
|
+
text.includes("email") ||
|
|
103
|
+
text.includes("phone") ||
|
|
104
|
+
text.includes("lead")) {
|
|
105
|
+
return "person";
|
|
106
|
+
}
|
|
107
|
+
if (text.includes("company") ||
|
|
108
|
+
text.includes("companies") ||
|
|
109
|
+
text.includes("organization") ||
|
|
110
|
+
text.includes("account") ||
|
|
111
|
+
text.includes("domain")) {
|
|
112
|
+
return "company";
|
|
113
|
+
}
|
|
114
|
+
return "person";
|
|
115
|
+
}
|
|
116
|
+
export function buildDryRunResult(input) {
|
|
117
|
+
return {
|
|
118
|
+
run: {
|
|
119
|
+
status: "success",
|
|
120
|
+
executions: [
|
|
121
|
+
{
|
|
122
|
+
nodeSlug: DRY_RUN_NODE_SLUG,
|
|
123
|
+
title: input.title,
|
|
124
|
+
status: "success",
|
|
125
|
+
creditsUsedCount: 0,
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
},
|
|
129
|
+
runContext: {
|
|
130
|
+
action: sampleFromSchema(input.outputSchema, { subject: input.subject }),
|
|
131
|
+
},
|
|
132
|
+
runComputedConfigs: { action: input.data },
|
|
133
|
+
dryRun: {
|
|
134
|
+
sample: true,
|
|
135
|
+
estimatedCredits: input.estimate.credits,
|
|
136
|
+
creditsFormula: input.estimate.formula,
|
|
137
|
+
note: DRY_RUN_NOTE,
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function isObject(value) {
|
|
142
|
+
return (typeof value === "object" &&
|
|
143
|
+
value !== null &&
|
|
144
|
+
Array.isArray(value) === false);
|
|
145
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** What the whole sample is about, which decides what a bare `name` means. */
|
|
2
|
+
export type SampleSubject = "person" | "company";
|
|
3
|
+
export type SampleOptions = {
|
|
4
|
+
/** Defaults to "person". A company enrichment's `name` is a company name. */
|
|
5
|
+
subject?: SampleSubject;
|
|
6
|
+
};
|
|
7
|
+
export declare function sampleFromSchema(schema: unknown, options?: SampleOptions): unknown;
|
|
8
|
+
/**
|
|
9
|
+
* Whether a schema says enough about an output to sample it. `{}`, a bare
|
|
10
|
+
* `{ type: "object" }` and a free-form record all describe "some object", and
|
|
11
|
+
* a sample of one would be `{}` — which reads as "this action returns nothing"
|
|
12
|
+
* rather than "the shape is decided at run time".
|
|
13
|
+
*/
|
|
14
|
+
export declare function describesOutput(schema: unknown): boolean;
|
|
15
|
+
//# sourceMappingURL=sampleFromSchema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sampleFromSchema.d.ts","sourceRoot":"","sources":["../../src/utils/sampleFromSchema.ts"],"names":[],"mappings":"AAcA,8EAA8E;AAC9E,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEjD,MAAM,MAAM,aAAa,GAAG;IAC1B,6EAA6E;IAC7E,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB,CAAC;AAmBF,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,OAAO,EACf,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAST;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAExD"}
|