@cargo-ai/cli 1.0.104 → 1.0.106
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/build/commands/ai/message.js +2 -2
- package/build/commands/ask/harness/create.d.ts.map +1 -1
- package/build/commands/ask/harness/create.js +22 -18
- package/build/commands/ask/harness/release.d.ts +2 -4
- package/build/commands/ask/harness/release.d.ts.map +1 -1
- package/build/commands/ask/harness/release.js +3 -2
- package/build/commands/ask/harness/turn.d.ts +2 -15
- package/build/commands/ask/harness/turn.d.ts.map +1 -1
- package/build/commands/ask/harness/turn.js +15 -23
- package/build/commands/ask/harness/usage.d.ts +11 -5
- package/build/commands/ask/harness/usage.d.ts.map +1 -1
- package/build/commands/ask/harness/usage.js +13 -6
- package/package.json +6 -6
|
@@ -28,8 +28,8 @@ export function registerMessageCommands(parent, getApi) {
|
|
|
28
28
|
.option("--integration-slug <slug>", "Integration slug (string)")
|
|
29
29
|
.option("--connector-uuid <uuid>", "Connector UUID (string)")
|
|
30
30
|
.option("--language-model-slug <slug>", "Language model slug (string)")
|
|
31
|
-
.option("--harness-slug <slug>", `Coding-agent runtime: ${AiUtils.harnessSlugs.join(", ")}. When omitted,
|
|
32
|
-
.option("--repository <json>", "Git workspace for a coding harness (JSON object: connectorUuid, repository as owner/name, defaultBranch, rootDirectory, env)")
|
|
31
|
+
.option("--harness-slug <slug>", `Coding-agent runtime for the auto-created chat: ${AiUtils.harnessSlugs.join(", ")}. Rejected with --chat-uuid. When omitted, the agent's pinned release decides.`)
|
|
32
|
+
.option("--repository <json>", "Git workspace for a coding harness, on the auto-created chat (JSON object: connectorUuid, repository as owner/name, defaultBranch, rootDirectory, env). Rejected with --chat-uuid.")
|
|
33
33
|
.option("--output <json>", 'Output format for the assistant message (JSON object, e.g. \'{"type":"text"}\' or \'{"type":"jsonSchema","jsonSchema":{...}}\'). Defaults to text when omitted.')
|
|
34
34
|
.option("--wait-until-finished [true|false]", "Poll the assistant message until finished before returning (defaults to true when passed bare)", parseBooleanOption)
|
|
35
35
|
.option("--polling-interval <ms>", "Polling interval in milliseconds, used with --wait-until-finished (integer, default: 5000)", "5000")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../../src/commands/ask/harness/create.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../../src/commands/ask/harness/create.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC;AAIxC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAuB3C,OAAO,EAEL,KAAK,kBAAkB,EAKxB,MAAM,WAAW,CAAC;AAGnB,MAAM,MAAM,YAAY,GAAG;IACzB,YAAY,EAAE,CACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,kBAAkB,KACzB,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB;;;;OAIG;IACH,iBAAiB,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAC5C,sEAAsE;IACtE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B,CAAC;AAcF,wBAAsB,kBAAkB,CAAC,KAAK,EAAE;IAC9C,GAAG,EAAE,GAAG,CAAC;IACT;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,uBAAuB,EAAE,OAAO,CAAC;CAClC,GAAG,OAAO,CAAC,YAAY,CAAC,CA4UxB"}
|
|
@@ -82,13 +82,10 @@ export async function createLocalHarness(input) {
|
|
|
82
82
|
}),
|
|
83
83
|
},
|
|
84
84
|
id: "cargo-ai-ask",
|
|
85
|
-
sandbox: withGetPortEndpoint(createLocalSandbox({ cwd: workspace.sandboxCwd })),
|
|
86
85
|
sandboxConfig: workspace.workDir === undefined ? {} : { workDir: workspace.workDir },
|
|
87
86
|
instructions: localHarnessInstructions(input.dir, release),
|
|
88
87
|
skills: localHarnessSkills(input.dir),
|
|
89
88
|
model: input.languageModelSlug,
|
|
90
|
-
// Nested @ai-sdk/harness ships its own @ai-sdk/provider-utils, so its
|
|
91
|
-
// ToolSet does not unify with this package's. Runtime shape is the same.
|
|
92
89
|
tools: hostTools,
|
|
93
90
|
permissionMode: "allow-reads",
|
|
94
91
|
...(ASK_TIMING_ENABLED === false
|
|
@@ -96,14 +93,27 @@ export async function createLocalHarness(input) {
|
|
|
96
93
|
: { debug: { enabled: true }, onLog: reportHarnessDiagnostic }),
|
|
97
94
|
});
|
|
98
95
|
setupPhase("harness agent constructed");
|
|
99
|
-
//
|
|
100
|
-
//
|
|
101
|
-
const
|
|
96
|
+
// Ours rather than the agent's, so ours to stop: the bridge and Claude Code
|
|
97
|
+
// run inside it.
|
|
98
|
+
const sandboxSession = await withGetPortEndpoint(createLocalSandbox({ cwd: workspace.sandboxCwd })).createSession();
|
|
99
|
+
const stopSandbox = () => Promise.resolve(sandboxSession.stop()).catch(() => undefined);
|
|
100
|
+
let session;
|
|
101
|
+
try {
|
|
102
|
+
// Local sandbox cannot broker credentials via request transforms; the
|
|
103
|
+
// harness always warns. Keep that off the Ask tree (stderr mid-reply).
|
|
104
|
+
session = await withMutedCredentialBrokerWarning(() => harnessAgent.createSession({ sandboxSession }));
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
await stopSandbox();
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
102
110
|
setupPhase("harness session created");
|
|
103
111
|
// Consumed by the first prompt: this session has never seen the chat, so it
|
|
104
112
|
// is told the story once rather than on every question.
|
|
105
113
|
let pendingHistory = input.history;
|
|
106
114
|
let proxyLastUsedAtMs;
|
|
115
|
+
// Carried from turn to turn: see `LocalTurnAccumulator.reportedCostUsd`.
|
|
116
|
+
let reportedCostUsd = 0;
|
|
107
117
|
// Approvals the previous turn asked about and never answered — a turn
|
|
108
118
|
// cancelled at the confirmation prompt leaves one here.
|
|
109
119
|
const unanswered = [];
|
|
@@ -127,17 +137,9 @@ export async function createLocalHarness(input) {
|
|
|
127
137
|
// user who walked away from the prompt is "no" — carrying the
|
|
128
138
|
// question into a turn they did not ask for would be worse.
|
|
129
139
|
const denials = unanswered.map((approval) => ({
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
approved: false,
|
|
134
|
-
},
|
|
135
|
-
toolCall: {
|
|
136
|
-
type: "tool-call",
|
|
137
|
-
toolCallId: approval.toolCallId,
|
|
138
|
-
toolName: approval.toolName,
|
|
139
|
-
input: approval.input,
|
|
140
|
-
},
|
|
140
|
+
type: "tool-approval-response",
|
|
141
|
+
approvalId: approval.approvalId,
|
|
142
|
+
approved: false,
|
|
141
143
|
}));
|
|
142
144
|
unanswered.length = 0;
|
|
143
145
|
// The drain gets its own controller so the timeout can stop it rather
|
|
@@ -181,7 +183,7 @@ export async function createLocalHarness(input) {
|
|
|
181
183
|
}
|
|
182
184
|
turnPhase("unfinished previous turn drained");
|
|
183
185
|
}
|
|
184
|
-
const accumulator = createTurnAccumulator();
|
|
186
|
+
const accumulator = createTurnAccumulator(reportedCostUsd);
|
|
185
187
|
let answer;
|
|
186
188
|
askUserQuestionAsk.current =
|
|
187
189
|
options === undefined ? undefined : options.onUserQuestion;
|
|
@@ -251,6 +253,7 @@ export async function createLocalHarness(input) {
|
|
|
251
253
|
}
|
|
252
254
|
finally {
|
|
253
255
|
askUserQuestionAsk.current = undefined;
|
|
256
|
+
reportedCostUsd = accumulator.reportedCostUsd;
|
|
254
257
|
}
|
|
255
258
|
if (didReachAnthropic(accumulator.usage) === true) {
|
|
256
259
|
proxyLastUsedAtMs = Date.now();
|
|
@@ -292,6 +295,7 @@ export async function createLocalHarness(input) {
|
|
|
292
295
|
// this call exists to prevent, but a teardown already stuck is no more
|
|
293
296
|
// likely to finish while the user waits on it.
|
|
294
297
|
await settleWithin(session.destroy().catch(() => undefined), SESSION_DESTROY_TIMEOUT_MS);
|
|
298
|
+
await settleWithin(stopSandbox(), SESSION_DESTROY_TIMEOUT_MS);
|
|
295
299
|
},
|
|
296
300
|
};
|
|
297
301
|
}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import type { Ai, Orchestration } from "@cargo-ai/api";
|
|
2
|
+
import { jsonSchema } from "ai";
|
|
2
3
|
import type { Api } from "../../../api.js";
|
|
3
4
|
/** Mount prefix so agent MCP tools can be auto-approved without widening user MCP. */
|
|
4
5
|
export declare const CARGO_AGENT_MCP_NAME_PREFIX = "cargoagent_";
|
|
5
6
|
type HostTool = {
|
|
6
7
|
description?: string;
|
|
7
|
-
inputSchema:
|
|
8
|
-
type: "object";
|
|
9
|
-
additionalProperties: true;
|
|
10
|
-
};
|
|
8
|
+
inputSchema: ReturnType<typeof jsonSchema>;
|
|
11
9
|
execute: (data: unknown) => Promise<unknown>;
|
|
12
10
|
};
|
|
13
11
|
export declare function buildReleaseInstructionAppendix(release: Ai.Release): string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../../../../src/commands/ask/harness/release.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../../../../src/commands/ask/harness/release.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAEhC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAE3C,sFAAsF;AACtF,eAAO,MAAM,2BAA2B,gBAAgB,CAAC;AAEzD,KAAK,QAAQ,GAAG;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;IAC3C,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9C,CAAC;AAEF,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,EAAE,CAAC,OAAO,GAClB,MAAM,GAAG,SAAS,CAwCpB;AAED,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,EAAE,CAAC,SAAS,EAAE,GACzB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiBzB;AAED,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,EAAE,CAAC,MAAM,EAAE,GACnB,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CA4B1B;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,EAAE,CAAC,MAAM,GAChB,aAAa,CAAC,GAAG,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAgClD"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { jsonSchema } from "ai";
|
|
1
2
|
/** Mount prefix so agent MCP tools can be auto-approved without widening user MCP. */
|
|
2
3
|
export const CARGO_AGENT_MCP_NAME_PREFIX = "cargoagent_";
|
|
3
4
|
export function buildReleaseInstructionAppendix(release) {
|
|
@@ -46,10 +47,10 @@ export function buildReleaseHostTools(api, actions) {
|
|
|
46
47
|
for (const action of actions) {
|
|
47
48
|
tools[action.slug] = {
|
|
48
49
|
description: action.description,
|
|
49
|
-
inputSchema: {
|
|
50
|
+
inputSchema: jsonSchema({
|
|
50
51
|
type: "object",
|
|
51
52
|
additionalProperties: true,
|
|
52
|
-
},
|
|
53
|
+
}),
|
|
53
54
|
execute: async (data) => {
|
|
54
55
|
try {
|
|
55
56
|
return await api.orchestration.action.execute({
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ToolApprovalResponse } from "ai";
|
|
1
2
|
import { type LocalTurnAccumulator } from "./usage.js";
|
|
2
3
|
/**
|
|
3
4
|
* A built-in tool Claude Code wants to run that `permissionMode` does not
|
|
@@ -70,24 +71,10 @@ export type StreamLike = {
|
|
|
70
71
|
fullStream: AsyncIterable<unknown>;
|
|
71
72
|
text: PromiseLike<string>;
|
|
72
73
|
};
|
|
73
|
-
export type ApprovalContinuation = {
|
|
74
|
-
approvalResponse: {
|
|
75
|
-
type: "tool-approval-response";
|
|
76
|
-
approvalId: string;
|
|
77
|
-
approved: boolean;
|
|
78
|
-
reason?: string;
|
|
79
|
-
};
|
|
80
|
-
toolCall: {
|
|
81
|
-
type: "tool-call";
|
|
82
|
-
toolCallId: string;
|
|
83
|
-
toolName: string;
|
|
84
|
-
input: unknown;
|
|
85
|
-
};
|
|
86
|
-
};
|
|
87
74
|
/** The two harness calls a turn needs. Split out so tests can fake them. */
|
|
88
75
|
export type TurnDriver = {
|
|
89
76
|
start: () => Promise<StreamLike>;
|
|
90
|
-
continueWithApprovals: (continuations: readonly
|
|
77
|
+
continueWithApprovals: (continuations: readonly ToolApprovalResponse[]) => Promise<StreamLike>;
|
|
91
78
|
};
|
|
92
79
|
/**
|
|
93
80
|
* Run one turn to completion, answering approval requests along the way.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"turn.d.ts","sourceRoot":"","sources":["../../../../src/commands/ask/harness/turn.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"turn.d.ts","sourceRoot":"","sources":["../../../../src/commands/ask/harness/turn.ts"],"names":[],"mappings":"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"}
|
|
@@ -59,7 +59,7 @@ export async function runPromptTurn(input) {
|
|
|
59
59
|
const handlers = input.handlers === undefined ? {} : input.handlers;
|
|
60
60
|
const onApproval = handlers.onApproval;
|
|
61
61
|
const accumulator = input.accumulator === undefined
|
|
62
|
-
? createTurnAccumulator()
|
|
62
|
+
? createTurnAccumulator(0)
|
|
63
63
|
: input.accumulator;
|
|
64
64
|
const stallTimeoutMs = input.stallTimeoutMs === undefined
|
|
65
65
|
? TURN_STALL_TIMEOUT_MS
|
|
@@ -81,7 +81,7 @@ export async function runPromptTurn(input) {
|
|
|
81
81
|
handlers,
|
|
82
82
|
assistantChunks,
|
|
83
83
|
toolCalls,
|
|
84
|
-
|
|
84
|
+
accumulator,
|
|
85
85
|
turnState,
|
|
86
86
|
stallTimeoutMs,
|
|
87
87
|
toolStallTimeoutMs,
|
|
@@ -132,24 +132,16 @@ export async function runPromptTurn(input) {
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
continuations.push({
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
: undefined,
|
|
146
|
-
},
|
|
147
|
-
toolCall: {
|
|
148
|
-
type: "tool-call",
|
|
149
|
-
toolCallId: approval.toolCallId,
|
|
150
|
-
toolName: approval.toolName,
|
|
151
|
-
input: approval.input,
|
|
152
|
-
},
|
|
135
|
+
type: "tool-approval-response",
|
|
136
|
+
approvalId: approval.approvalId,
|
|
137
|
+
approved,
|
|
138
|
+
// Told why, so it does something else rather than asking again
|
|
139
|
+
// until the approval-round cap ends the turn.
|
|
140
|
+
reason: question !== undefined
|
|
141
|
+
? question.reason
|
|
142
|
+
: denied === true
|
|
143
|
+
? DENIED_TOOL_REASON
|
|
144
|
+
: undefined,
|
|
153
145
|
});
|
|
154
146
|
}
|
|
155
147
|
retractAbandonedCalls(turnState.announced, handlers.onActivity);
|
|
@@ -495,9 +487,9 @@ async function consumeTurn(input) {
|
|
|
495
487
|
}
|
|
496
488
|
if (part["type"] === "finish") {
|
|
497
489
|
// One suspended turn is several streams, each ending with its own
|
|
498
|
-
// `finish`
|
|
499
|
-
//
|
|
500
|
-
addTurnUsage(input.
|
|
490
|
+
// `finish` — all of them count. Per-step parts are ignored so the same
|
|
491
|
+
// tokens are not counted twice.
|
|
492
|
+
addTurnUsage(input.accumulator, part);
|
|
501
493
|
continue;
|
|
502
494
|
}
|
|
503
495
|
if (part["type"] === "tool-approval-request") {
|
|
@@ -21,9 +21,13 @@ export type LocalTurnUsage = {
|
|
|
21
21
|
export type LocalTurnAccumulator = {
|
|
22
22
|
chunks: string[];
|
|
23
23
|
usage: LocalTurnUsage;
|
|
24
|
+
/**
|
|
25
|
+
* Claude Code's last running cost for the session. It counts every turn so
|
|
26
|
+
* far, so a turn starts from the previous turn's and bills what it added.
|
|
27
|
+
*/
|
|
28
|
+
reportedCostUsd: number;
|
|
24
29
|
};
|
|
25
|
-
|
|
26
|
-
export declare function createTurnAccumulator(): LocalTurnAccumulator;
|
|
30
|
+
export declare function createTurnAccumulator(lastReportedCostUsd: number): LocalTurnAccumulator;
|
|
27
31
|
/**
|
|
28
32
|
* Whether the turn got as far as Anthropic. `costUsd` and `totalTokens` are
|
|
29
33
|
* reported independently by the harness, so either alone means it did.
|
|
@@ -31,10 +35,12 @@ export declare function createTurnAccumulator(): LocalTurnAccumulator;
|
|
|
31
35
|
export declare function didReachAnthropic(usage: LocalTurnUsage): boolean;
|
|
32
36
|
/**
|
|
33
37
|
* Add one stream's `finish` totals to the turn. `totalUsage` is the AI SDK
|
|
34
|
-
* shape
|
|
35
|
-
*
|
|
38
|
+
* shape and counts that stream alone. `costUsd`, under `harnessMetadata`, is a
|
|
39
|
+
* running total, so the turn takes what it added since the last report; a
|
|
40
|
+
* total below that belongs to a new session, and counts in full. The turn's
|
|
41
|
+
* cost is stored on the ingested message.
|
|
36
42
|
*/
|
|
37
|
-
export declare function addTurnUsage(
|
|
43
|
+
export declare function addTurnUsage(accumulator: LocalTurnAccumulator, part: Record<string, unknown>): void;
|
|
38
44
|
/**
|
|
39
45
|
* What Claude Code says the turn cost, off the `finish` part.
|
|
40
46
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../../../../src/commands/ask/harness/usage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../../../../src/commands/ask/harness/usage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,cAAc,CAAC;IACtB;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,wBAAgB,qBAAqB,CACnC,mBAAmB,EAAE,MAAM,GAC1B,oBAAoB,CActB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAEhE;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,WAAW,EAAE,oBAAoB,EACjC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,IAAI,CAwCN;AAQD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,MAAM,GAAG,SAAS,CA0BpB"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
export function createTurnAccumulator() {
|
|
1
|
+
export function createTurnAccumulator(lastReportedCostUsd) {
|
|
3
2
|
return {
|
|
4
3
|
chunks: [],
|
|
4
|
+
reportedCostUsd: lastReportedCostUsd,
|
|
5
5
|
usage: {
|
|
6
6
|
costUsd: 0,
|
|
7
7
|
totalTokens: 0,
|
|
@@ -22,13 +22,20 @@ export function didReachAnthropic(usage) {
|
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
24
|
* Add one stream's `finish` totals to the turn. `totalUsage` is the AI SDK
|
|
25
|
-
* shape
|
|
26
|
-
*
|
|
25
|
+
* shape and counts that stream alone. `costUsd`, under `harnessMetadata`, is a
|
|
26
|
+
* running total, so the turn takes what it added since the last report; a
|
|
27
|
+
* total below that belongs to a new session, and counts in full. The turn's
|
|
28
|
+
* cost is stored on the ingested message.
|
|
27
29
|
*/
|
|
28
|
-
export function addTurnUsage(
|
|
30
|
+
export function addTurnUsage(accumulator, part) {
|
|
31
|
+
const usage = accumulator.usage;
|
|
29
32
|
const costUsd = readClaudeCodeCostUsd(part);
|
|
30
33
|
if (costUsd !== undefined) {
|
|
31
|
-
usage.costUsd +=
|
|
34
|
+
usage.costUsd +=
|
|
35
|
+
costUsd >= accumulator.reportedCostUsd
|
|
36
|
+
? costUsd - accumulator.reportedCostUsd
|
|
37
|
+
: costUsd;
|
|
38
|
+
accumulator.reportedCostUsd = costUsd;
|
|
32
39
|
}
|
|
33
40
|
const totalUsage = part["totalUsage"];
|
|
34
41
|
if (typeof totalUsage !== "object" || totalUsage === null) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cargo-ai/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.106",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"homepage": "https://getcargo.ai",
|
|
@@ -65,16 +65,16 @@
|
|
|
65
65
|
"format:check": "prettier --check ."
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@ai-sdk/harness": "^1.0.
|
|
69
|
-
"@ai-sdk/harness-claude-code": "^1.0.
|
|
68
|
+
"@ai-sdk/harness": "^1.0.144",
|
|
69
|
+
"@ai-sdk/harness-claude-code": "^1.0.148",
|
|
70
70
|
"@cargo-ai/api": "^1.0.87",
|
|
71
71
|
"@cargo-ai/app-sdk": "^1.0.11",
|
|
72
72
|
"@cargo-ai/cdk": "^1.0.99",
|
|
73
|
-
"@cargo-ai/types": "^1.0.
|
|
73
|
+
"@cargo-ai/types": "^1.0.90",
|
|
74
74
|
"@cargo-ai/utils": "^1.0.32",
|
|
75
75
|
"@cargo-ai/worker-sdk": "^1.0.20",
|
|
76
|
-
"@modelcontextprotocol/sdk": "1.31.0",
|
|
77
|
-
"ai": "^7.0.
|
|
76
|
+
"@modelcontextprotocol/sdk": "^1.31.0",
|
|
77
|
+
"ai": "^7.0.133",
|
|
78
78
|
"ai-sdk-sandbox-local": "^0.1.2",
|
|
79
79
|
"commander": "^12.1.0",
|
|
80
80
|
"tsx": "^4.19.2",
|