@cargo-ai/cli 1.0.73 → 1.0.74
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 +21 -0
- package/build/commands/ai/agent.js +2 -2
- package/build/commands/ai/chat.js +1 -1
- package/build/commands/ai/document.js +1 -1
- package/build/commands/ai/memory.js +3 -3
- package/build/commands/ai/message.js +2 -2
- package/build/commands/ai/release.d.ts.map +1 -1
- package/build/commands/ai/release.js +3 -3
- package/build/commands/ai/vote.d.ts.map +1 -1
- package/build/commands/ai/vote.js +1 -1
- package/build/commands/auth/index.js +2 -2
- package/build/commands/billing/subscription.d.ts.map +1 -1
- package/build/commands/billing/subscription.js +3 -3
- package/build/commands/billing/usage.d.ts.map +1 -1
- package/build/commands/billing/usage.js +1 -1
- package/build/commands/connection/action.d.ts.map +1 -1
- package/build/commands/connection/action.js +1 -1
- package/build/commands/connection/connector.js +1 -1
- package/build/commands/connection/integration.d.ts.map +1 -1
- package/build/commands/connection/integration.js +1 -1
- package/build/commands/content/library.js +1 -1
- package/build/commands/context/runtime.js +1 -1
- package/build/commands/expression/recipe.d.ts.map +1 -1
- package/build/commands/expression/recipe.js +9 -9
- package/build/commands/mailboxManagement/event.js +1 -1
- package/build/commands/mailboxManagement/mailbox.d.ts.map +1 -1
- package/build/commands/mailboxManagement/mailbox.js +3 -3
- package/build/commands/mailboxManagement/message.js +1 -1
- package/build/commands/mailboxManagement/suppression.js +1 -1
- package/build/commands/mailboxManagement/thread.js +1 -1
- package/build/commands/observability/alert.js +2 -2
- package/build/commands/orchestration/action.d.ts.map +1 -1
- package/build/commands/orchestration/action.js +18 -63
- package/build/commands/orchestration/batch.js +7 -7
- package/build/commands/orchestration/node.js +2 -2
- package/build/commands/orchestration/play.d.ts.map +1 -1
- package/build/commands/orchestration/play.js +9 -9
- package/build/commands/orchestration/record.d.ts.map +1 -1
- package/build/commands/orchestration/record.js +10 -10
- package/build/commands/orchestration/release.js +1 -1
- package/build/commands/orchestration/run.d.ts.map +1 -1
- package/build/commands/orchestration/run.js +14 -14
- package/build/commands/orchestration/span.d.ts.map +1 -1
- package/build/commands/orchestration/span.js +4 -4
- package/build/commands/orchestration/tool.js +2 -2
- package/build/commands/orchestration/trace.d.ts.map +1 -1
- package/build/commands/orchestration/trace.js +2 -2
- package/build/commands/revenueOrganization/capacity.d.ts.map +1 -1
- package/build/commands/revenueOrganization/capacity.js +2 -2
- package/build/commands/revenueOrganization/territory.js +2 -2
- package/build/commands/segmentation/change.d.ts.map +1 -1
- package/build/commands/segmentation/change.js +4 -4
- package/build/commands/segmentation/record.js +1 -1
- package/build/commands/segmentation/segment.js +2 -2
- package/build/commands/start/index.js +1 -1
- package/build/commands/storage/query.js +1 -1
- package/build/commands/storage/record.js +2 -2
- package/build/commands/storage/run.js +2 -2
- package/build/commands/systemOfRecordIntegration/log.js +1 -1
- package/build/commands/systemOfRecordIntegration/systemOfRecord.js +1 -1
- package/build/commands/version.js +1 -1
- package/build/commands/workspaceManagement/folder.d.ts.map +1 -1
- package/build/commands/workspaceManagement/folder.js +1 -1
- package/build/commands/workspaceManagement/role.d.ts.map +1 -1
- package/build/commands/workspaceManagement/role.js +2 -2
- package/build/commands/workspaceManagement/session.js +1 -1
- package/build/commands/workspaceManagement/user.d.ts.map +1 -1
- package/build/commands/workspaceManagement/user.js +2 -2
- package/build/commands/workspaceManagement/workspaces.js +1 -1
- package/build/utils/booleanOption.d.ts.map +1 -1
- package/build/utils/booleanOption.js +5 -4
- package/package.json +3 -3
- package/build/commands/orchestration/costTable.d.ts +0 -121
- package/build/commands/orchestration/costTable.d.ts.map +0 -1
- package/build/commands/orchestration/costTable.js +0 -363
|
@@ -14,7 +14,7 @@ export function registerRoleCommands(parent, getApi) {
|
|
|
14
14
|
.description("Create a custom role")
|
|
15
15
|
.requiredOption("--name <name>", "Display name for the role")
|
|
16
16
|
.requiredOption("--slug <slug>", "Unique identifier for the role")
|
|
17
|
-
.option("--color <
|
|
17
|
+
.option("--color <orange|red|purple|green|yellow|grey>", "Role color (dot in the UI)", "grey")
|
|
18
18
|
.option("--description <description>", "Role description")
|
|
19
19
|
.option("--permissions <json>", "JSON array of permission objects", "[]")
|
|
20
20
|
.action(async (opts) => {
|
|
@@ -33,7 +33,7 @@ export function registerRoleCommands(parent, getApi) {
|
|
|
33
33
|
.description("Update a custom role")
|
|
34
34
|
.requiredOption("--uuid <uuid>", "Role UUID")
|
|
35
35
|
.option("--name <name>", "Display name for the role")
|
|
36
|
-
.option("--color <
|
|
36
|
+
.option("--color <orange|red|purple|green|yellow|grey>", "Role color (dot in the UI)")
|
|
37
37
|
.option("--description <description>", "Role description")
|
|
38
38
|
.option("--permissions <json>", "JSON array of permission objects")
|
|
39
39
|
.action(async (opts) => {
|
|
@@ -10,7 +10,7 @@ export function registerSessionCommands(parent, getApi) {
|
|
|
10
10
|
.requiredOption("--session-id <sessionId>", "Claude Code session id")
|
|
11
11
|
.requiredOption("--title <title>", "Short title for the session")
|
|
12
12
|
.requiredOption("--summary <summary>", "Summary of what happened in the session")
|
|
13
|
-
.option("--finished [
|
|
13
|
+
.option("--finished [true|false]", "Mark the session as finished now (sets finishedAt = now)", parseBooleanOption)
|
|
14
14
|
.option("--finished-at <timestamp>", "Explicit ISO timestamp for when the session finished")
|
|
15
15
|
.action(async (opts) => {
|
|
16
16
|
let finishedAt;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../src/commands/workspaceManagement/user.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAGxC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../src/commands/workspaceManagement/user.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAGxC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,IAAI,CAwM7E"}
|
|
@@ -78,7 +78,7 @@ Example:
|
|
|
78
78
|
.option("--emails <emails>", "Target user emails (comma-separated strings). At least one of --user-uuids or --emails is required")
|
|
79
79
|
.requiredOption("--action <action>", "Permission action (string, required)")
|
|
80
80
|
.requiredOption("--resource-uuid <uuid>", "Resource UUID to grant/deny access to (string, required)")
|
|
81
|
-
.requiredOption("--effect <
|
|
81
|
+
.requiredOption("--effect <allow|deny>", "Permission effect")
|
|
82
82
|
.addHelpText("after", `
|
|
83
83
|
Examples:
|
|
84
84
|
$ cargo-ai workspaceManagement user upsert-permission --emails alice@example.com --action read --resource-uuid 550e8400-... --effect allow
|
|
@@ -106,7 +106,7 @@ Examples:
|
|
|
106
106
|
.description("Remove a previously granted/denied user permission")
|
|
107
107
|
.requiredOption("--user-uuid <uuid>", "User UUID (string, required)")
|
|
108
108
|
.requiredOption("--resource-uuid <uuid>", "Resource UUID (string, required)")
|
|
109
|
-
.requiredOption("--effect <
|
|
109
|
+
.requiredOption("--effect <allow|deny>", "Permission effect to remove")
|
|
110
110
|
.addHelpText("after", `
|
|
111
111
|
Example:
|
|
112
112
|
$ cargo-ai workspaceManagement user remove-permission --user-uuid 550e8400-... --resource-uuid 660e8400-... --effect allow`)
|
|
@@ -7,7 +7,7 @@ export function registerWorkspacesCommands(parent, getApi) {
|
|
|
7
7
|
workspaces
|
|
8
8
|
.command("list")
|
|
9
9
|
.description("List all workspaces accessible to the current user")
|
|
10
|
-
.option("--refresh [
|
|
10
|
+
.option("--refresh [true|false]", "Bypass any token cache and re-fetch from the server (useful after permission changes)", parseBooleanOption)
|
|
11
11
|
.addHelpText("after", `
|
|
12
12
|
Examples:
|
|
13
13
|
$ cargo-ai workspaceManagement workspaces list
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"booleanOption.d.ts","sourceRoot":"","sources":["../../src/utils/booleanOption.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"booleanOption.d.ts","sourceRoot":"","sources":["../../src/utils/booleanOption.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,kBAAkB,UAAW,MAAM,GAAG,OAAO,KAAG,OAY5D,CAAC;AAMF,eAAO,MAAM,kBAAkB,aACnB,OAAO,GAAG,SAAS,YACnB,OAAO,GAAG,SAAS;cACN,MAAM;cAAY,MAAM;MAC9C,OAAO,GAAG,SAkBZ,CAAC"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { InvalidArgumentError } from "commander";
|
|
2
|
-
// Boolean flags are declared as `--flag [
|
|
3
|
-
// form people actually reach for, `--flag false`, are accepted. Commander
|
|
4
|
-
// this parser the literal `true` when the flag is passed bare, and the raw
|
|
5
|
-
// string when a value follows it.
|
|
2
|
+
// Boolean flags are declared as `--flag [true|false]` so that both `--flag` and
|
|
3
|
+
// the form people actually reach for, `--flag false`, are accepted. Commander
|
|
4
|
+
// hands this parser the literal `true` when the flag is passed bare, and the raw
|
|
5
|
+
// string when a value follows it. Spelling the two values out in the placeholder
|
|
6
|
+
// is what puts them in `--help` and turns the flag into a menu in the palette.
|
|
6
7
|
//
|
|
7
8
|
// Declaring them as bare flags instead is a trap: `--flag false` parses as the
|
|
8
9
|
// flag plus a stray `false`, so the caller gets the opposite of what they typed.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cargo-ai/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.74",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"homepage": "https://getcargo.ai",
|
|
@@ -64,9 +64,9 @@
|
|
|
64
64
|
"format:check": "prettier --check ."
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@cargo-ai/api": "^1.0.
|
|
67
|
+
"@cargo-ai/api": "^1.0.71",
|
|
68
68
|
"@cargo-ai/app-sdk": "^1.0.9",
|
|
69
|
-
"@cargo-ai/cdk": "^1.0.
|
|
69
|
+
"@cargo-ai/cdk": "^1.0.60",
|
|
70
70
|
"@cargo-ai/types": "^1.0.66",
|
|
71
71
|
"@cargo-ai/worker-sdk": "^1.0.17",
|
|
72
72
|
"@modelcontextprotocol/sdk": "1.29.0",
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Renders every credits-based action as a pricing table.
|
|
3
|
-
*
|
|
4
|
-
* The catalog is the only place pricing lives, and it moves — providers get
|
|
5
|
-
* added, actions get repriced, tiers get split. Anything that copies those
|
|
6
|
-
* numbers by hand goes stale silently, so the table is generated rather than
|
|
7
|
-
* maintained.
|
|
8
|
-
*
|
|
9
|
-
* Sourced from `orchestration action list` (without a limit), which spans
|
|
10
|
-
* connector and native actions in a single call. Natives are a small set but
|
|
11
|
-
* not a free one — `sendEmail` is 0.1, `modelAsk` 0.5, `fileSearch` 0.02/1k
|
|
12
|
-
* tokens — and a table built from connectors alone silently omits them while
|
|
13
|
-
* claiming to be complete.
|
|
14
|
-
*/
|
|
15
|
-
/**
|
|
16
|
-
* Shape returned by `orchestration action list` for each matching action.
|
|
17
|
-
*/
|
|
18
|
-
export type ListActionMatch = {
|
|
19
|
-
name: string;
|
|
20
|
-
description?: string;
|
|
21
|
-
score: number;
|
|
22
|
-
action: {
|
|
23
|
-
kind: string;
|
|
24
|
-
integrationSlug?: string;
|
|
25
|
-
actionSlug?: string;
|
|
26
|
-
};
|
|
27
|
-
integrationName?: string;
|
|
28
|
-
category?: string;
|
|
29
|
-
credits?: CreditsCost[];
|
|
30
|
-
};
|
|
31
|
-
export type CreditsCost = {
|
|
32
|
-
type?: string;
|
|
33
|
-
cost?: number;
|
|
34
|
-
unit?: string;
|
|
35
|
-
unitsCount?: number;
|
|
36
|
-
fixedCost?: number;
|
|
37
|
-
config?: {
|
|
38
|
-
jsonSchema?: JsonSchema;
|
|
39
|
-
};
|
|
40
|
-
};
|
|
41
|
-
type JsonSchema = {
|
|
42
|
-
type?: string;
|
|
43
|
-
const?: unknown;
|
|
44
|
-
enum?: unknown[];
|
|
45
|
-
minItems?: number;
|
|
46
|
-
maxItems?: number;
|
|
47
|
-
properties?: Record<string, JsonSchema>;
|
|
48
|
-
required?: string[];
|
|
49
|
-
};
|
|
50
|
-
export type CatalogAction = {
|
|
51
|
-
name?: string;
|
|
52
|
-
description?: string;
|
|
53
|
-
credits?: {
|
|
54
|
-
costs?: CreditsCost[];
|
|
55
|
-
};
|
|
56
|
-
};
|
|
57
|
-
export type CatalogIntegration = {
|
|
58
|
-
slug: string;
|
|
59
|
-
name: string;
|
|
60
|
-
category?: string;
|
|
61
|
-
actions?: Record<string, CatalogAction>;
|
|
62
|
-
};
|
|
63
|
-
export type CostVariant = {
|
|
64
|
-
/** Config that selects this price, e.g. `model=gpt-5-nano`. */
|
|
65
|
-
when: string;
|
|
66
|
-
/** Rendered price, e.g. `0.4 + 0.006 / 1k token`. */
|
|
67
|
-
price: string;
|
|
68
|
-
};
|
|
69
|
-
export type CostRow = {
|
|
70
|
-
integrationSlug: string;
|
|
71
|
-
integrationName: string;
|
|
72
|
-
category: string | undefined;
|
|
73
|
-
actionSlug: string;
|
|
74
|
-
name: string | undefined;
|
|
75
|
-
description: string | undefined;
|
|
76
|
-
/** Cheapest and dearest per-unit price, in credits. */
|
|
77
|
-
minCost: number;
|
|
78
|
-
maxCost: number;
|
|
79
|
-
/**
|
|
80
|
-
* What one call at the cheapest config costs — per-unit price plus any flat
|
|
81
|
-
* component. The sort key, so a cheap-looking per-item rate with a base
|
|
82
|
-
* charge doesn't outrank a genuinely cheaper flat action.
|
|
83
|
-
*/
|
|
84
|
-
sortCost: number;
|
|
85
|
-
/** Single price, or `min–max` when config picks between several. */
|
|
86
|
-
price: string;
|
|
87
|
-
/** Config fields that move the price; empty when there is only one. */
|
|
88
|
-
variesBy: string[];
|
|
89
|
-
variants: CostVariant[];
|
|
90
|
-
};
|
|
91
|
-
export type CostTableSummary = {
|
|
92
|
-
integrations: number;
|
|
93
|
-
integrationsWithActions: number;
|
|
94
|
-
actions: number;
|
|
95
|
-
creditsBasedActions: number;
|
|
96
|
-
freeActions: number;
|
|
97
|
-
};
|
|
98
|
-
/**
|
|
99
|
-
* Natives have no integration of their own. `native` cannot collide with a real
|
|
100
|
-
* integration slug, and it is what `kind` an action object needs to run one:
|
|
101
|
-
* `{"kind":"native","actionSlug":"sendEmail"}`.
|
|
102
|
-
*/
|
|
103
|
-
export declare const NATIVE_PROVIDER_SLUG = "native";
|
|
104
|
-
export declare function asNativeCatalogIntegration(actions: Record<string, CatalogAction> | undefined): CatalogIntegration;
|
|
105
|
-
/**
|
|
106
|
-
* Groups the flat action list returned by `orchestration action list` into the
|
|
107
|
-
* integration-grouped shape that `buildCostRows` and `summarize` expect.
|
|
108
|
-
*/
|
|
109
|
-
export declare function groupActionsByIntegration(actions: ListActionMatch[]): CatalogIntegration[];
|
|
110
|
-
export declare function buildCostRows(integrations: CatalogIntegration[]): CostRow[];
|
|
111
|
-
export declare function summarize(integrations: CatalogIntegration[]): CostTableSummary;
|
|
112
|
-
export type RenderCostTableOptions = {
|
|
113
|
-
generatedAt: string;
|
|
114
|
-
filter?: {
|
|
115
|
-
category?: string;
|
|
116
|
-
integration?: string;
|
|
117
|
-
};
|
|
118
|
-
};
|
|
119
|
-
export declare function renderCostTable(rows: CostRow[], summary: CostTableSummary, opts: RenderCostTableOptions): string;
|
|
120
|
-
export {};
|
|
121
|
-
//# sourceMappingURL=costTable.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"costTable.d.ts","sourceRoot":"","sources":["../../../src/commands/orchestration/costTable.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,363 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Renders every credits-based action as a pricing table.
|
|
3
|
-
*
|
|
4
|
-
* The catalog is the only place pricing lives, and it moves — providers get
|
|
5
|
-
* added, actions get repriced, tiers get split. Anything that copies those
|
|
6
|
-
* numbers by hand goes stale silently, so the table is generated rather than
|
|
7
|
-
* maintained.
|
|
8
|
-
*
|
|
9
|
-
* Sourced from `orchestration action list` (without a limit), which spans
|
|
10
|
-
* connector and native actions in a single call. Natives are a small set but
|
|
11
|
-
* not a free one — `sendEmail` is 0.1, `modelAsk` 0.5, `fileSearch` 0.02/1k
|
|
12
|
-
* tokens — and a table built from connectors alone silently omits them while
|
|
13
|
-
* claiming to be complete.
|
|
14
|
-
*/
|
|
15
|
-
const DESCRIPTION_MAX_LENGTH = 120;
|
|
16
|
-
/**
|
|
17
|
-
* Natives have no integration of their own. `native` cannot collide with a real
|
|
18
|
-
* integration slug, and it is what `kind` an action object needs to run one:
|
|
19
|
-
* `{"kind":"native","actionSlug":"sendEmail"}`.
|
|
20
|
-
*/
|
|
21
|
-
export const NATIVE_PROVIDER_SLUG = "native";
|
|
22
|
-
export function asNativeCatalogIntegration(actions) {
|
|
23
|
-
return {
|
|
24
|
-
slug: NATIVE_PROVIDER_SLUG,
|
|
25
|
-
name: "Cargo native",
|
|
26
|
-
category: "platform",
|
|
27
|
-
actions: actions ?? {},
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Groups the flat action list returned by `orchestration action list` into the
|
|
32
|
-
* integration-grouped shape that `buildCostRows` and `summarize` expect.
|
|
33
|
-
*/
|
|
34
|
-
export function groupActionsByIntegration(actions) {
|
|
35
|
-
const integrationMap = new Map();
|
|
36
|
-
for (const match of actions) {
|
|
37
|
-
const actionKind = match.action.kind;
|
|
38
|
-
const actionSlug = match.action.actionSlug;
|
|
39
|
-
if (actionSlug === undefined) {
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
let slug;
|
|
43
|
-
let name;
|
|
44
|
-
let category;
|
|
45
|
-
if (actionKind === "native") {
|
|
46
|
-
slug = NATIVE_PROVIDER_SLUG;
|
|
47
|
-
name = "Cargo native";
|
|
48
|
-
category = "platform";
|
|
49
|
-
}
|
|
50
|
-
else if (actionKind === "connector") {
|
|
51
|
-
slug =
|
|
52
|
-
match.action.integrationSlug !== undefined
|
|
53
|
-
? match.action.integrationSlug
|
|
54
|
-
: "";
|
|
55
|
-
name = match.integrationName !== undefined ? match.integrationName : slug;
|
|
56
|
-
category = match.category;
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
let integration = integrationMap.get(slug);
|
|
62
|
-
if (integration === undefined) {
|
|
63
|
-
integration = { slug, name, category, actions: {} };
|
|
64
|
-
integrationMap.set(slug, integration);
|
|
65
|
-
}
|
|
66
|
-
if (integration.actions === undefined) {
|
|
67
|
-
integration.actions = {};
|
|
68
|
-
}
|
|
69
|
-
integration.actions[actionSlug] = {
|
|
70
|
-
name: match.name,
|
|
71
|
-
description: match.description,
|
|
72
|
-
credits: match.credits !== undefined ? { costs: match.credits } : undefined,
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
return Array.from(integrationMap.values());
|
|
76
|
-
}
|
|
77
|
-
export function buildCostRows(integrations) {
|
|
78
|
-
const rows = [];
|
|
79
|
-
for (const integration of integrations) {
|
|
80
|
-
for (const [actionSlug, action] of Object.entries(integration.actions ?? {})) {
|
|
81
|
-
const costs = action.credits?.costs;
|
|
82
|
-
const [first] = costs ?? [];
|
|
83
|
-
if (costs === undefined || first === undefined) {
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
const amounts = costs.map((cost) => cost.cost ?? 0);
|
|
87
|
-
const effective = costs.map((cost) => (cost.cost ?? 0) + (cost.fixedCost ?? 0));
|
|
88
|
-
const variants = costs.map((cost) => ({
|
|
89
|
-
when: describeSelector(cost.config?.jsonSchema),
|
|
90
|
-
price: renderPrice(cost),
|
|
91
|
-
}));
|
|
92
|
-
const minCost = Math.min(...amounts);
|
|
93
|
-
const maxCost = Math.max(...amounts);
|
|
94
|
-
rows.push({
|
|
95
|
-
integrationSlug: integration.slug,
|
|
96
|
-
integrationName: integration.name,
|
|
97
|
-
category: integration.category,
|
|
98
|
-
actionSlug,
|
|
99
|
-
name: action.name,
|
|
100
|
-
description: truncate(action.description),
|
|
101
|
-
minCost,
|
|
102
|
-
maxCost,
|
|
103
|
-
sortCost: Math.min(...effective),
|
|
104
|
-
price: costs.length === 1
|
|
105
|
-
? renderPrice(first)
|
|
106
|
-
: renderRange(costs, minCost, maxCost),
|
|
107
|
-
variesBy: costs.length === 1 ? [] : selectorFields(costs),
|
|
108
|
-
variants: costs.length === 1 ? [] : variants,
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
return rows.sort((a, b) => a.sortCost - b.sortCost ||
|
|
113
|
-
a.maxCost - b.maxCost ||
|
|
114
|
-
a.integrationSlug.localeCompare(b.integrationSlug) ||
|
|
115
|
-
a.actionSlug.localeCompare(b.actionSlug));
|
|
116
|
-
}
|
|
117
|
-
export function summarize(integrations) {
|
|
118
|
-
let actions = 0;
|
|
119
|
-
let creditsBasedActions = 0;
|
|
120
|
-
let integrationsWithActions = 0;
|
|
121
|
-
for (const integration of integrations) {
|
|
122
|
-
const entries = Object.values(integration.actions ?? {});
|
|
123
|
-
// The native pseudo-integration is a carrier for platform actions, not a
|
|
124
|
-
// 139th integration. Its actions count; it does not.
|
|
125
|
-
const isNative = integration.slug === NATIVE_PROVIDER_SLUG;
|
|
126
|
-
if (entries.length > 0 && isNative === false) {
|
|
127
|
-
integrationsWithActions += 1;
|
|
128
|
-
}
|
|
129
|
-
actions += entries.length;
|
|
130
|
-
for (const action of entries) {
|
|
131
|
-
if ((action.credits?.costs ?? []).length > 0) {
|
|
132
|
-
creditsBasedActions += 1;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
return {
|
|
137
|
-
integrations: integrations.filter((integration) => {
|
|
138
|
-
return integration.slug !== NATIVE_PROVIDER_SLUG;
|
|
139
|
-
}).length,
|
|
140
|
-
integrationsWithActions,
|
|
141
|
-
actions,
|
|
142
|
-
creditsBasedActions,
|
|
143
|
-
freeActions: actions - creditsBasedActions,
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
export function renderCostTable(rows, summary, opts) {
|
|
147
|
-
const lines = [];
|
|
148
|
-
const filter = opts.filter;
|
|
149
|
-
const isFiltered = filter !== undefined &&
|
|
150
|
-
(filter.category !== undefined || filter.integration !== undefined);
|
|
151
|
-
lines.push("# Credits cost table");
|
|
152
|
-
lines.push("");
|
|
153
|
-
if (isFiltered) {
|
|
154
|
-
const filterDesc = filter.category !== undefined && filter.integration !== undefined
|
|
155
|
-
? `category \`${filter.category}\` and integration \`${filter.integration}\``
|
|
156
|
-
: filter.category !== undefined
|
|
157
|
-
? `category \`${filter.category}\``
|
|
158
|
-
: `integration \`${filter.integration}\``;
|
|
159
|
-
lines.push(`Filtered by ${filterDesc}: ${String(summary.creditsBasedActions)} credits-based actions ` +
|
|
160
|
-
`out of ${String(summary.actions)} total across ${String(summary.integrationsWithActions)} of ` +
|
|
161
|
-
`${String(summary.integrations)} integrations, sorted by cost. ` +
|
|
162
|
-
`The other ${String(summary.freeActions)} actions in this subset cost no credits. ` +
|
|
163
|
-
"Run without filters for the full catalog, including Cargo's native actions.");
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
lines.push(`Every credits-based action Cargo can run — ${String(summary.creditsBasedActions)} of the ` +
|
|
167
|
-
`${String(summary.actions)} actions exposed by ${String(summary.integrationsWithActions)} of the catalog's ` +
|
|
168
|
-
`${String(summary.integrations)} integrations, plus Cargo's own native actions — sorted by cost. The other ${String(summary.freeActions)} actions ` +
|
|
169
|
-
"(CRM writes, sequencer pushes, Slack sends, …) cost no credits; list them with " +
|
|
170
|
-
"`cargo-ai connection integration get <slug>`.");
|
|
171
|
-
}
|
|
172
|
-
lines.push("");
|
|
173
|
-
if (isFiltered === false) {
|
|
174
|
-
lines.push("Rows whose provider is `native` are Cargo's own platform actions, run as " +
|
|
175
|
-
'`{"kind":"native","actionSlug":"<action>"}` with no integration; every other row ' +
|
|
176
|
-
'runs as `{"kind":"connector","integrationSlug":"<provider>","actionSlug":"<action>"}`.');
|
|
177
|
-
lines.push("");
|
|
178
|
-
}
|
|
179
|
-
lines.push("**Auto-generated. Do not edit by hand** — regenerate with " +
|
|
180
|
-
"`cargo-ai orchestration action cost-table --raw > cargo-gtm/references/credits-cost-table.md`.");
|
|
181
|
-
lines.push("");
|
|
182
|
-
lines.push(`Generated: ${opts.generatedAt}`);
|
|
183
|
-
lines.push("");
|
|
184
|
-
lines.push("| Cost | Provider | Category | Action | Description |");
|
|
185
|
-
lines.push("|---|---|---|---|---|");
|
|
186
|
-
for (const row of rows) {
|
|
187
|
-
lines.push(`| ${row.price} | \`${row.integrationSlug}\` | ${row.category ?? "—"} | ` +
|
|
188
|
-
`\`${row.actionSlug}\` | ${escapeCell(row.description ?? "")} |`);
|
|
189
|
-
}
|
|
190
|
-
const variable = rows.filter((row) => row.variants.length > 0);
|
|
191
|
-
if (variable.length > 0) {
|
|
192
|
-
lines.push("");
|
|
193
|
-
lines.push("## Actions whose price depends on config");
|
|
194
|
-
lines.push("");
|
|
195
|
-
lines.push("These bill differently depending on how the node is configured, so the range above is not a quote. " +
|
|
196
|
-
"Pick the row that matches the config you are about to run.");
|
|
197
|
-
lines.push("");
|
|
198
|
-
for (const row of variable) {
|
|
199
|
-
lines.push(`### \`${row.integrationSlug}.${row.actionSlug}\` — varies by ${row.variesBy
|
|
200
|
-
.map((field) => `\`${field}\``)
|
|
201
|
-
.join(", ")}`);
|
|
202
|
-
lines.push("");
|
|
203
|
-
lines.push("| Config | Cost |");
|
|
204
|
-
lines.push("|---|---|");
|
|
205
|
-
for (const variant of dedupeVariants(row.variants)) {
|
|
206
|
-
lines.push(`| ${escapeCell(variant.when)} | ${variant.price} |`);
|
|
207
|
-
}
|
|
208
|
-
lines.push("");
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
return `${lines.join("\n").trimEnd()}\n`;
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* One cost entry as a price expression.
|
|
215
|
-
*
|
|
216
|
-
* `fixed` bills per call, `unit` bills per unit consumed, and `package` bills
|
|
217
|
-
* per block of units on top of a flat call cost — an LLM step that charges a
|
|
218
|
-
* base plus a rate per 1k tokens is the common case.
|
|
219
|
-
*/
|
|
220
|
-
function renderPrice(cost) {
|
|
221
|
-
const amount = formatAmount(cost.cost ?? 0);
|
|
222
|
-
if (cost.type === "unit") {
|
|
223
|
-
const metered = cost.unit === undefined ? amount : `${amount} / ${cost.unit}`;
|
|
224
|
-
// A per-item rate can sit on top of a flat charge per call — dropping that
|
|
225
|
-
// base is how a 0.175 + 0.025/item search gets quoted as 0.025.
|
|
226
|
-
return cost.fixedCost === undefined || cost.fixedCost === 0
|
|
227
|
-
? metered
|
|
228
|
-
: `${formatAmount(cost.fixedCost)} + ${metered}`;
|
|
229
|
-
}
|
|
230
|
-
if (cost.type === "package") {
|
|
231
|
-
const block = formatUnits(cost.unitsCount, cost.unit);
|
|
232
|
-
const metered = block === undefined ? amount : `${amount} / ${block}`;
|
|
233
|
-
return cost.fixedCost === undefined || cost.fixedCost === 0
|
|
234
|
-
? metered
|
|
235
|
-
: `${formatAmount(cost.fixedCost)} + ${metered}`;
|
|
236
|
-
}
|
|
237
|
-
return amount;
|
|
238
|
-
}
|
|
239
|
-
function renderRange(costs, minCost, maxCost) {
|
|
240
|
-
const range = minCost === maxCost
|
|
241
|
-
? formatAmount(minCost)
|
|
242
|
-
: `${formatAmount(minCost)}–${formatAmount(maxCost)}`;
|
|
243
|
-
const first = costs[0];
|
|
244
|
-
const unit = first !== undefined ? first.unit : undefined;
|
|
245
|
-
const unitsCount = first !== undefined ? first.unitsCount : undefined;
|
|
246
|
-
const packageBlock = formatUnits(unitsCount, unit);
|
|
247
|
-
const metered = costs.some((cost) => cost.type === "package")
|
|
248
|
-
? packageBlock !== undefined
|
|
249
|
-
? `${range} / ${packageBlock}`
|
|
250
|
-
: range
|
|
251
|
-
: costs.every((cost) => cost.type === "unit") && unit !== undefined
|
|
252
|
-
? `${range} / ${unit}`
|
|
253
|
-
: range;
|
|
254
|
-
const hasBase = costs.some((cost) => cost.fixedCost !== undefined && cost.fixedCost !== 0);
|
|
255
|
-
return hasBase ? `${metered} + base` : metered;
|
|
256
|
-
}
|
|
257
|
-
/**
|
|
258
|
-
* The config fields a cost entry keys off, as dotted paths — the answer to
|
|
259
|
-
* "what do I change to land on a different price".
|
|
260
|
-
*/
|
|
261
|
-
function selectorPaths(schema, prefix = "") {
|
|
262
|
-
if (schema?.properties === undefined) {
|
|
263
|
-
return [];
|
|
264
|
-
}
|
|
265
|
-
const paths = [];
|
|
266
|
-
for (const [key, property] of Object.entries(schema.properties)) {
|
|
267
|
-
const path = prefix === "" ? key : `${prefix}.${key}`;
|
|
268
|
-
const nested = selectorPaths(property, path);
|
|
269
|
-
if (nested.length > 0) {
|
|
270
|
-
paths.push(...nested);
|
|
271
|
-
}
|
|
272
|
-
else {
|
|
273
|
-
paths.push(path);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
return paths;
|
|
277
|
-
}
|
|
278
|
-
function selectorFields(costs) {
|
|
279
|
-
const fields = new Set();
|
|
280
|
-
for (const cost of costs) {
|
|
281
|
-
for (const path of selectorPaths(cost.config?.jsonSchema)) {
|
|
282
|
-
fields.add(path);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
return [...fields];
|
|
286
|
-
}
|
|
287
|
-
/** A cost entry's selector as `field=value` pairs, e.g. `model=gpt-5-nano`. */
|
|
288
|
-
function describeSelector(schema) {
|
|
289
|
-
const pairs = selectorPairs(schema);
|
|
290
|
-
return pairs.length === 0 ? "any config" : pairs.join(", ");
|
|
291
|
-
}
|
|
292
|
-
function selectorPairs(schema, prefix = "") {
|
|
293
|
-
if (schema?.properties === undefined) {
|
|
294
|
-
return [];
|
|
295
|
-
}
|
|
296
|
-
const pairs = [];
|
|
297
|
-
for (const [key, property] of Object.entries(schema.properties)) {
|
|
298
|
-
const path = prefix === "" ? key : `${prefix}.${key}`;
|
|
299
|
-
const nested = selectorPairs(property, path);
|
|
300
|
-
if (nested.length > 0) {
|
|
301
|
-
pairs.push(...nested);
|
|
302
|
-
continue;
|
|
303
|
-
}
|
|
304
|
-
pairs.push(`${path}${describeConstraint(property)}`);
|
|
305
|
-
}
|
|
306
|
-
return pairs;
|
|
307
|
-
}
|
|
308
|
-
function describeConstraint(schema) {
|
|
309
|
-
if (schema.const !== undefined) {
|
|
310
|
-
return `=${String(schema.const)}`;
|
|
311
|
-
}
|
|
312
|
-
if (schema.enum !== undefined) {
|
|
313
|
-
return `∈ ${schema.enum.map((value) => String(value)).join("|")}`;
|
|
314
|
-
}
|
|
315
|
-
if (schema.maxItems === 0) {
|
|
316
|
-
return " empty";
|
|
317
|
-
}
|
|
318
|
-
if (schema.minItems !== undefined && schema.minItems > 0) {
|
|
319
|
-
return " set";
|
|
320
|
-
}
|
|
321
|
-
return " (any)";
|
|
322
|
-
}
|
|
323
|
-
/**
|
|
324
|
-
* Catalogs sometimes carry the same price twice under selectors that differ
|
|
325
|
-
* only in a field the reader cannot act on; collapsing them keeps the variant
|
|
326
|
-
* table readable.
|
|
327
|
-
*/
|
|
328
|
-
function dedupeVariants(variants) {
|
|
329
|
-
const seen = new Set();
|
|
330
|
-
const kept = [];
|
|
331
|
-
for (const variant of variants) {
|
|
332
|
-
const key = `${variant.when}|${variant.price}`;
|
|
333
|
-
if (seen.has(key) === true) {
|
|
334
|
-
continue;
|
|
335
|
-
}
|
|
336
|
-
seen.add(key);
|
|
337
|
-
kept.push(variant);
|
|
338
|
-
}
|
|
339
|
-
return kept;
|
|
340
|
-
}
|
|
341
|
-
function formatUnits(unitsCount, unit) {
|
|
342
|
-
if (unit === undefined) {
|
|
343
|
-
return undefined;
|
|
344
|
-
}
|
|
345
|
-
if (unitsCount === undefined || unitsCount === 1) {
|
|
346
|
-
return unit;
|
|
347
|
-
}
|
|
348
|
-
return unitsCount % 1000 === 0
|
|
349
|
-
? `${String(unitsCount / 1000)}k ${unit}`
|
|
350
|
-
: `${String(unitsCount)} ${unit}`;
|
|
351
|
-
}
|
|
352
|
-
function formatAmount(value) {
|
|
353
|
-
return String(Number(value.toFixed(6)));
|
|
354
|
-
}
|
|
355
|
-
function truncate(value) {
|
|
356
|
-
if (value === undefined || value.length <= DESCRIPTION_MAX_LENGTH) {
|
|
357
|
-
return value;
|
|
358
|
-
}
|
|
359
|
-
return `${value.slice(0, DESCRIPTION_MAX_LENGTH).trimEnd()}…`;
|
|
360
|
-
}
|
|
361
|
-
function escapeCell(value) {
|
|
362
|
-
return value.replace(/\r?\n/g, " ").replace(/\|/g, "\\|");
|
|
363
|
-
}
|