@genesislcap/ai-assistant 14.444.1 → 14.445.1
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/dist/ai-assistant.api.json +312 -41
- package/dist/ai-assistant.d.ts +105 -8
- package/dist/dts/components/ai-driver/ai-driver.d.ts +7 -0
- package/dist/dts/components/ai-driver/ai-driver.d.ts.map +1 -1
- package/dist/dts/components/chat-driver/chat-driver.d.ts +37 -3
- package/dist/dts/components/chat-driver/chat-driver.d.ts.map +1 -1
- package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts +5 -3
- package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts.map +1 -1
- package/dist/dts/config/config.d.ts +31 -0
- package/dist/dts/config/config.d.ts.map +1 -1
- package/dist/dts/config/define-stateful-agent.d.ts +9 -0
- package/dist/dts/config/define-stateful-agent.d.ts.map +1 -1
- package/dist/dts/config/validate-providers.d.ts +25 -0
- package/dist/dts/config/validate-providers.d.ts.map +1 -0
- package/dist/dts/config/validate-providers.test.d.ts +2 -0
- package/dist/dts/config/validate-providers.test.d.ts.map +1 -0
- package/dist/dts/main/main.d.ts +17 -5
- package/dist/dts/main/main.d.ts.map +1 -1
- package/dist/dts/main/main.styles.d.ts.map +1 -1
- package/dist/dts/main/main.template.d.ts.map +1 -1
- package/dist/dts/state/ai-assistant-slice.d.ts +14 -1
- package/dist/dts/state/ai-assistant-slice.d.ts.map +1 -1
- package/dist/dts/state/session-store.d.ts +2 -0
- package/dist/dts/state/session-store.d.ts.map +1 -1
- package/dist/dts/utils/sum-costs.d.ts +13 -0
- package/dist/dts/utils/sum-costs.d.ts.map +1 -0
- package/dist/dts/utils/sum-costs.test.d.ts +2 -0
- package/dist/dts/utils/sum-costs.test.d.ts.map +1 -0
- package/dist/esm/components/chat-driver/chat-driver.js +93 -15
- package/dist/esm/components/orchestrating-driver/orchestrating-driver.js +23 -4
- package/dist/esm/config/define-stateful-agent.js +12 -0
- package/dist/esm/config/validate-providers.js +47 -0
- package/dist/esm/config/validate-providers.test.js +100 -0
- package/dist/esm/main/main.js +76 -21
- package/dist/esm/main/main.styles.js +52 -0
- package/dist/esm/main/main.template.js +36 -1
- package/dist/esm/state/ai-assistant-slice.js +8 -0
- package/dist/esm/utils/sum-costs.js +23 -0
- package/dist/esm/utils/sum-costs.test.js +88 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/docs/migration-GENC-1262.md +219 -0
- package/package.json +16 -16
- package/src/components/ai-driver/ai-driver.ts +8 -0
- package/src/components/chat-driver/chat-driver.ts +107 -14
- package/src/components/orchestrating-driver/orchestrating-driver.ts +29 -4
- package/src/config/config.ts +32 -0
- package/src/config/define-stateful-agent.ts +28 -0
- package/src/config/validate-providers.test.ts +148 -0
- package/src/config/validate-providers.ts +58 -0
- package/src/main/main.styles.ts +52 -0
- package/src/main/main.template.ts +50 -2
- package/src/main/main.ts +69 -14
- package/src/state/ai-assistant-slice.ts +24 -1
- package/src/utils/sum-costs.test.ts +108 -0
- package/src/utils/sum-costs.ts +22 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { ChatMessage } from '@genesislcap/foundation-ai';
|
|
2
|
+
import { assert, createLogicSuite } from '@genesislcap/foundation-testing';
|
|
3
|
+
import { sumCosts } from './sum-costs';
|
|
4
|
+
|
|
5
|
+
const userMsg = (overrides: Partial<ChatMessage> = {}): ChatMessage => ({
|
|
6
|
+
role: 'user',
|
|
7
|
+
content: '',
|
|
8
|
+
...overrides,
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
const assistantMsg = (overrides: Partial<ChatMessage> = {}): ChatMessage => ({
|
|
12
|
+
role: 'assistant',
|
|
13
|
+
content: '',
|
|
14
|
+
...overrides,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const suite = createLogicSuite('sumCosts');
|
|
18
|
+
|
|
19
|
+
suite('returns 0 for an empty message list', () => {
|
|
20
|
+
assert.is(sumCosts([]), 0);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
suite('returns 0 when no message carries cost (e.g. all from a no-usage provider)', () => {
|
|
24
|
+
assert.is(sumCosts([userMsg(), assistantMsg({ content: 'hi' })]), 0);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
suite('sums top-level message costs', () => {
|
|
28
|
+
// Use integer-cents arithmetic to avoid float-equality flake; the production
|
|
29
|
+
// path only ever adds floats here, so any rounding lives in display, not sum.
|
|
30
|
+
const cost = sumCosts([
|
|
31
|
+
assistantMsg({ cost: 0.5 }),
|
|
32
|
+
assistantMsg({ cost: 1.5 }),
|
|
33
|
+
userMsg(), // no cost — ignored
|
|
34
|
+
]);
|
|
35
|
+
assert.is(cost, 2);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
suite('includes sub-agent trace costs attached to a tool call', () => {
|
|
39
|
+
const parentToolCallMsg = assistantMsg({
|
|
40
|
+
cost: 0.1,
|
|
41
|
+
toolCalls: [
|
|
42
|
+
{
|
|
43
|
+
id: 'tc1',
|
|
44
|
+
name: 'spawn_sub',
|
|
45
|
+
args: {},
|
|
46
|
+
subAgentTrace: [assistantMsg({ cost: 0.5 }), assistantMsg({ cost: 0.4 })],
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
});
|
|
50
|
+
// 0.1 (parent) + 0.5 + 0.4 (sub) = 1.0
|
|
51
|
+
assert.is(sumCosts([parentToolCallMsg]), 1);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
suite('recurses into nested sub-agent traces', () => {
|
|
55
|
+
const innerTrace: ChatMessage[] = [assistantMsg({ cost: 0.25 })];
|
|
56
|
+
const middleTrace: ChatMessage[] = [
|
|
57
|
+
assistantMsg({
|
|
58
|
+
cost: 0.5,
|
|
59
|
+
toolCalls: [{ id: 'inner', name: 'spawn_inner', args: {}, subAgentTrace: innerTrace }],
|
|
60
|
+
}),
|
|
61
|
+
];
|
|
62
|
+
const top = assistantMsg({
|
|
63
|
+
cost: 1,
|
|
64
|
+
toolCalls: [{ id: 'middle', name: 'spawn_middle', args: {}, subAgentTrace: middleTrace }],
|
|
65
|
+
});
|
|
66
|
+
// 1 + 0.5 + 0.25 = 1.75
|
|
67
|
+
assert.is(sumCosts([top]), 1.75);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
suite('handles a mix of tool calls with and without subAgentTrace', () => {
|
|
71
|
+
const cost = sumCosts([
|
|
72
|
+
assistantMsg({
|
|
73
|
+
cost: 1,
|
|
74
|
+
toolCalls: [
|
|
75
|
+
{ id: 'a', name: 'plain_tool', args: {} }, // no trace — skipped
|
|
76
|
+
{
|
|
77
|
+
id: 'b',
|
|
78
|
+
name: 'sub_tool',
|
|
79
|
+
args: {},
|
|
80
|
+
subAgentTrace: [assistantMsg({ cost: 2 })],
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
}),
|
|
84
|
+
]);
|
|
85
|
+
assert.is(cost, 3);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
suite('ignores missing cost fields inside an otherwise-populated trace', () => {
|
|
89
|
+
const cost = sumCosts([
|
|
90
|
+
assistantMsg({
|
|
91
|
+
toolCalls: [
|
|
92
|
+
{
|
|
93
|
+
id: 'tc',
|
|
94
|
+
name: 'sub',
|
|
95
|
+
args: {},
|
|
96
|
+
subAgentTrace: [
|
|
97
|
+
userMsg(), // role=user, no cost
|
|
98
|
+
assistantMsg({ content: 'partial', cost: 0.3 }),
|
|
99
|
+
assistantMsg({ content: 'unbilled' }), // no cost field
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
}),
|
|
104
|
+
]);
|
|
105
|
+
assert.is(cost, 0.3);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
suite.run();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ChatMessage } from '@genesislcap/foundation-ai';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Sum the `cost` field across a message list, recursing into each tool call's
|
|
5
|
+
* `subAgentTrace` so LLM calls made by sub-agents (potentially on a different
|
|
6
|
+
* provider with different rates) contribute to the total.
|
|
7
|
+
*
|
|
8
|
+
* Returns 0 when no messages carry a cost — providers that don't report usage
|
|
9
|
+
* metadata (e.g. Chrome built-in) are skipped silently.
|
|
10
|
+
*
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export function sumCosts(messages: readonly ChatMessage[]): number {
|
|
14
|
+
let total = 0;
|
|
15
|
+
for (const m of messages) {
|
|
16
|
+
if (m.cost != null) total += m.cost;
|
|
17
|
+
for (const tc of m.toolCalls ?? []) {
|
|
18
|
+
if (tc.subAgentTrace) total += sumCosts(tc.subAgentTrace);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return total;
|
|
22
|
+
}
|