@msm-core/mini 0.5.0 → 0.5.2
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/CHANGELOG.md +25 -0
- package/dist/brain/gemini.js +19 -18
- package/dist/brain/pricing.js +1 -0
- package/dist/brain/tool-context.d.ts +3 -0
- package/dist/brain/tool-context.js +1 -0
- package/dist/core/types.d.ts +5 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,31 @@ Follows [Semantic Versioning](https://semver.org/).
|
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
+
## [0.5.2] — 2026-07-01
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **The Gemini brain now reports token usage + cost on the tool-call path.** It
|
|
13
|
+
previously returned a bare `{ orchestration }` there (only the text path carried
|
|
14
|
+
usage/cost), so the loop's `costCapPerTask` accrued $0 on exactly the iterations
|
|
15
|
+
that dominate an agentic run — the cost cap never fired on the primary provider.
|
|
16
|
+
Both paths now compute usage + cost once, via the shared pricing table
|
|
17
|
+
(`computeCostUsd`) instead of hardcoded Flash rates, so non-Flash models bill
|
|
18
|
+
correctly. Locked with `tests/gemini-usage.test.ts`.
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- Pricing table entry for `gemini-2.5-pro` (Pro agents previously had no cost tracking).
|
|
23
|
+
|
|
24
|
+
## [0.5.1] — 2026-06-30
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- **Array tool-parameters.** `ToolParameter.items` is now forwarded to every
|
|
29
|
+
provider (Gemini included), so an array-typed tool parameter (e.g. a list of
|
|
30
|
+
template variables) is described to the model instead of being dropped — which
|
|
31
|
+
had caused arrays to 400 on Gemini.
|
|
32
|
+
|
|
8
33
|
## [0.5.0] — 2026-06-30
|
|
9
34
|
|
|
10
35
|
Brain-parity + guard-integrity release from the 2026-06 SDK audit (H1, H2, H10, M1).
|
package/dist/brain/gemini.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { withRetry } from "./retry.js";
|
|
6
6
|
import { foldToolResults } from "./tool-context.js";
|
|
7
|
+
import { computeCostUsd } from "./pricing.js";
|
|
7
8
|
export function createGeminiBrain(opts) {
|
|
8
9
|
const model = opts.model ?? "gemini-2.5-flash";
|
|
9
10
|
return {
|
|
@@ -41,6 +42,7 @@ export function createGeminiBrain(opts) {
|
|
|
41
42
|
type: v.type.toUpperCase(),
|
|
42
43
|
description: v.description,
|
|
43
44
|
...(v.enum ? { enum: v.enum } : {}),
|
|
45
|
+
...(v.items ? { items: { type: v.items.type.toUpperCase() } } : {}),
|
|
44
46
|
},
|
|
45
47
|
])),
|
|
46
48
|
required: Object.entries(t.parameters)
|
|
@@ -61,6 +63,20 @@ export function createGeminiBrain(opts) {
|
|
|
61
63
|
const result = await withRetry(() => geminiModel.generateContent(request, input.signal ? { signal: input.signal } : {}), input.signal ? { signal: input.signal } : {});
|
|
62
64
|
const response = result.response;
|
|
63
65
|
const parts = response?.candidates?.[0]?.content?.parts ?? [];
|
|
66
|
+
// Token usage + cost — computed ONCE and returned on BOTH the tool-call and text
|
|
67
|
+
// paths. Most iterations of an agentic run are tool calls, so omitting usage/cost
|
|
68
|
+
// there (as before) left the loop's cost cap seeing $0 and never firing. Price via
|
|
69
|
+
// the shared table (not hardcoded Flash rates) so gemini-2.5-pro bills correctly.
|
|
70
|
+
const usageMeta = response?.usageMetadata;
|
|
71
|
+
const inputTokens = usageMeta?.promptTokenCount;
|
|
72
|
+
const outputTokens = usageMeta?.candidatesTokenCount;
|
|
73
|
+
const usage = inputTokens !== undefined || outputTokens !== undefined
|
|
74
|
+
? {
|
|
75
|
+
...(inputTokens !== undefined ? { inputTokens } : {}),
|
|
76
|
+
...(outputTokens !== undefined ? { outputTokens } : {}),
|
|
77
|
+
}
|
|
78
|
+
: undefined;
|
|
79
|
+
const costUsd = computeCostUsd(model, inputTokens, outputTokens);
|
|
64
80
|
// Check for function call
|
|
65
81
|
const fnCallPart = parts.find((p) => "functionCall" in p && p.functionCall);
|
|
66
82
|
if (fnCallPart &&
|
|
@@ -73,31 +89,16 @@ export function createGeminiBrain(opts) {
|
|
|
73
89
|
tool_name: fc.name,
|
|
74
90
|
tool_params: fc.args,
|
|
75
91
|
};
|
|
76
|
-
return { orchestration };
|
|
92
|
+
return { orchestration, costUsd, ...(usage ? { usage } : {}) };
|
|
77
93
|
}
|
|
78
94
|
// Text response
|
|
79
95
|
const textPart = parts.find((p) => "text" in p && typeof p.text === "string");
|
|
80
96
|
const text = textPart && "text" in textPart ? textPart.text : "";
|
|
81
|
-
// Token usage
|
|
82
|
-
const usage = response?.usageMetadata;
|
|
83
|
-
const inputTokens = usage?.promptTokenCount;
|
|
84
|
-
const outputTokens = usage?.candidatesTokenCount;
|
|
85
97
|
return {
|
|
86
98
|
generation: { response_text: text },
|
|
87
99
|
orchestration: { action: "respond", confidence: 0.95 },
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
? (usage.promptTokenCount ?? 0) * 0.000_000_075 +
|
|
91
|
-
(usage.candidatesTokenCount ?? 0) * 0.0000003
|
|
92
|
-
: 0,
|
|
93
|
-
...(inputTokens !== undefined || outputTokens !== undefined
|
|
94
|
-
? {
|
|
95
|
-
usage: {
|
|
96
|
-
...(inputTokens !== undefined ? { inputTokens } : {}),
|
|
97
|
-
...(outputTokens !== undefined ? { outputTokens } : {}),
|
|
98
|
-
},
|
|
99
|
-
}
|
|
100
|
-
: {}),
|
|
100
|
+
costUsd,
|
|
101
|
+
...(usage ? { usage } : {}),
|
|
101
102
|
};
|
|
102
103
|
},
|
|
103
104
|
};
|
package/dist/brain/pricing.js
CHANGED
|
@@ -24,6 +24,7 @@ export const PRICE_PER_MILLION = {
|
|
|
24
24
|
"gpt-4o": { input: 2.5, output: 10 },
|
|
25
25
|
// Google Gemini (public pricing)
|
|
26
26
|
"gemini-2.5-flash": { input: 0.075, output: 0.3 },
|
|
27
|
+
"gemini-2.5-pro": { input: 1.25, output: 10 },
|
|
27
28
|
};
|
|
28
29
|
/**
|
|
29
30
|
* Cost in USD for one call. Returns 0 when the model is unknown or usage is
|
package/dist/core/types.d.ts
CHANGED
|
@@ -90,6 +90,11 @@ export interface ToolParameter {
|
|
|
90
90
|
required?: boolean;
|
|
91
91
|
enum?: string[];
|
|
92
92
|
default?: unknown;
|
|
93
|
+
/** Element type for `type: "array"` params. Required by Gemini's function-calling
|
|
94
|
+
* schema (an array without `items` is rejected); forwarded to every provider. */
|
|
95
|
+
items?: {
|
|
96
|
+
type: "string" | "number" | "boolean" | "object";
|
|
97
|
+
};
|
|
93
98
|
}
|
|
94
99
|
/** Input the loop hands to every brain call */
|
|
95
100
|
export interface BrainRunInput {
|