@genesislcap/ai-assistant 15.15.0 → 15.15.1-alpha-793fc09.0
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 +238 -0
- package/dist/ai-assistant.d.ts +56 -0
- package/dist/chat-driver.cjs +51 -0
- package/dist/chat-driver.cjs.map +2 -2
- package/dist/chat-driver.mjs +51 -0
- package/dist/chat-driver.mjs.map +2 -2
- package/dist/custom-elements.json +88 -1
- package/dist/dts/components/ai-driver/ai-driver.d.ts +10 -0
- package/dist/dts/components/ai-driver/ai-driver.d.ts.map +1 -1
- package/dist/dts/components/chat-driver/chat-driver.d.ts +28 -0
- package/dist/dts/components/chat-driver/chat-driver.d.ts.map +1 -1
- package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.d.ts +10 -0
- package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.d.ts.map +1 -1
- package/dist/dts/components/orchestrating-driver/orchestrating-driver.cost.test.d.ts +2 -0
- package/dist/dts/components/orchestrating-driver/orchestrating-driver.cost.test.d.ts.map +1 -0
- package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts +3 -0
- package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts.map +1 -1
- package/dist/dts/main/file-attachments.test.d.ts +2 -0
- package/dist/dts/main/file-attachments.test.d.ts.map +1 -0
- package/dist/dts/main/main.d.ts +11 -0
- package/dist/dts/main/main.d.ts.map +1 -1
- package/dist/dts/main/main.template.d.ts.map +1 -1
- package/dist/dts/react.d.ts +1 -0
- package/dist/dts/state/debug-event-log.d.ts +1 -1
- package/dist/dts/state/debug-event-log.d.ts.map +1 -1
- package/dist/esm/components/chat-driver/chat-driver.js +43 -0
- package/dist/esm/components/chat-driver/chat-driver.test.js +66 -0
- package/dist/esm/components/chat-interaction-wrapper/chat-interaction-wrapper.js +18 -0
- package/dist/esm/components/orchestrating-driver/orchestrating-driver.cost.test.js +46 -0
- package/dist/esm/components/orchestrating-driver/orchestrating-driver.js +5 -0
- package/dist/esm/main/file-attachments.test.js +58 -0
- package/dist/esm/main/main.js +42 -5
- package/dist/esm/main/main.template.js +1 -0
- package/dist/esm/state/debug-event-log.js +2 -0
- package/dist/react.cjs +6 -1
- package/dist/react.mjs +6 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +17 -17
- package/src/components/ai-driver/ai-driver.ts +10 -0
- package/src/components/chat-driver/chat-driver.test.ts +82 -0
- package/src/components/chat-driver/chat-driver.ts +45 -0
- package/src/components/chat-interaction-wrapper/chat-interaction-wrapper.ts +24 -0
- package/src/components/orchestrating-driver/orchestrating-driver.cost.test.ts +73 -0
- package/src/components/orchestrating-driver/orchestrating-driver.ts +6 -0
- package/src/main/file-attachments.test.ts +70 -0
- package/src/main/main.template.ts +1 -0
- package/src/main/main.ts +41 -6
- package/src/state/debug-event-log.ts +3 -0
|
@@ -3205,6 +3205,67 @@
|
|
|
3205
3205
|
],
|
|
3206
3206
|
"name": "primeRestoredAgentState"
|
|
3207
3207
|
},
|
|
3208
|
+
{
|
|
3209
|
+
"kind": "MethodSignature",
|
|
3210
|
+
"canonicalReference": "@genesislcap/ai-assistant!AiDriver#recordExternalCost:member(1)",
|
|
3211
|
+
"docComment": "/**\n * Record external spend against an interaction that has ALREADY resolved.\n *\n * For widgets that resolve early — so the assistant stops waiting — and then keep doing paid work on the user's behalf. Reports a positive DELTA; repeated calls sum. Returns false when the message is no longer in history.\n *\n * @beta\n */\n",
|
|
3212
|
+
"excerptTokens": [
|
|
3213
|
+
{
|
|
3214
|
+
"kind": "Content",
|
|
3215
|
+
"text": "recordExternalCost?(interactionId: "
|
|
3216
|
+
},
|
|
3217
|
+
{
|
|
3218
|
+
"kind": "Content",
|
|
3219
|
+
"text": "string"
|
|
3220
|
+
},
|
|
3221
|
+
{
|
|
3222
|
+
"kind": "Content",
|
|
3223
|
+
"text": ", costUsd: "
|
|
3224
|
+
},
|
|
3225
|
+
{
|
|
3226
|
+
"kind": "Content",
|
|
3227
|
+
"text": "number"
|
|
3228
|
+
},
|
|
3229
|
+
{
|
|
3230
|
+
"kind": "Content",
|
|
3231
|
+
"text": "): "
|
|
3232
|
+
},
|
|
3233
|
+
{
|
|
3234
|
+
"kind": "Content",
|
|
3235
|
+
"text": "boolean"
|
|
3236
|
+
},
|
|
3237
|
+
{
|
|
3238
|
+
"kind": "Content",
|
|
3239
|
+
"text": ";"
|
|
3240
|
+
}
|
|
3241
|
+
],
|
|
3242
|
+
"isOptional": true,
|
|
3243
|
+
"returnTypeTokenRange": {
|
|
3244
|
+
"startIndex": 5,
|
|
3245
|
+
"endIndex": 6
|
|
3246
|
+
},
|
|
3247
|
+
"releaseTag": "Beta",
|
|
3248
|
+
"overloadIndex": 1,
|
|
3249
|
+
"parameters": [
|
|
3250
|
+
{
|
|
3251
|
+
"parameterName": "interactionId",
|
|
3252
|
+
"parameterTypeTokenRange": {
|
|
3253
|
+
"startIndex": 1,
|
|
3254
|
+
"endIndex": 2
|
|
3255
|
+
},
|
|
3256
|
+
"isOptional": false
|
|
3257
|
+
},
|
|
3258
|
+
{
|
|
3259
|
+
"parameterName": "costUsd",
|
|
3260
|
+
"parameterTypeTokenRange": {
|
|
3261
|
+
"startIndex": 3,
|
|
3262
|
+
"endIndex": 4
|
|
3263
|
+
},
|
|
3264
|
+
"isOptional": false
|
|
3265
|
+
}
|
|
3266
|
+
],
|
|
3267
|
+
"name": "recordExternalCost"
|
|
3268
|
+
},
|
|
3208
3269
|
{
|
|
3209
3270
|
"kind": "MethodSignature",
|
|
3210
3271
|
"canonicalReference": "@genesislcap/ai-assistant!AiDriver#resolveInteraction:member(1)",
|
|
@@ -5265,6 +5326,70 @@
|
|
|
5265
5326
|
"isAbstract": false,
|
|
5266
5327
|
"name": "markAsSubAgent"
|
|
5267
5328
|
},
|
|
5329
|
+
{
|
|
5330
|
+
"kind": "Method",
|
|
5331
|
+
"canonicalReference": "@genesislcap/ai-assistant!ChatDriver#recordExternalCost:member(1)",
|
|
5332
|
+
"docComment": "/**\n * Add external (non-LLM) spend to an interaction's message AFTER it has resolved.\n *\n * **Why this exists separately from `resolveInteraction`.** A widget's spend reaches the session total only through `InteractionResult.costUsd`, which is read exactly once — `resolveInteraction` does its whole job inside `if (interaction)` and then deletes the entry from `pendingInteractions`. That is correct for the resolution itself, but it assumes a widget stops costing money when it resolves, and several deliberately do not: a widget that resolves EARLY so the assistant stops waiting (options shown, a preview rendered) may stay interactive for minutes afterwards and do more paid work on the user's behalf. Re-emitting `interaction-completed` does not help — with the interaction gone from the map the call is a silent no-op — so that spend had nowhere to go and was simply missing from the figure shown to the user.\n *\n * Additive by design: the caller reports a DELTA, not a running total, so repeated calls sum. It touches only `externalCostUsd`; the recorded `interaction.resolved` payload is left exactly as the resolution wrote it, because this is not a second resolution and must not read like one.\n *\n * Deliberately does NOT require the interaction to be pending, does not resurrect it, and has no loading/turn side effects — this is bookkeeping about a turn that already happened.\n *\n * @param interactionId - the interaction whose message owns the spend.\n *\n * @param costUsd - a positive delta in USD. Non-finite, zero and negative values are ignored.\n *\n * @returns `true` when the spend was recorded; `false` when the message is no longer in history (trimmed or condensed away), which is a real outcome the caller may want to log rather than a failure to throw on.\n *\n * @beta\n */\n",
|
|
5333
|
+
"excerptTokens": [
|
|
5334
|
+
{
|
|
5335
|
+
"kind": "Content",
|
|
5336
|
+
"text": "recordExternalCost(interactionId: "
|
|
5337
|
+
},
|
|
5338
|
+
{
|
|
5339
|
+
"kind": "Content",
|
|
5340
|
+
"text": "string"
|
|
5341
|
+
},
|
|
5342
|
+
{
|
|
5343
|
+
"kind": "Content",
|
|
5344
|
+
"text": ", costUsd: "
|
|
5345
|
+
},
|
|
5346
|
+
{
|
|
5347
|
+
"kind": "Content",
|
|
5348
|
+
"text": "number"
|
|
5349
|
+
},
|
|
5350
|
+
{
|
|
5351
|
+
"kind": "Content",
|
|
5352
|
+
"text": "): "
|
|
5353
|
+
},
|
|
5354
|
+
{
|
|
5355
|
+
"kind": "Content",
|
|
5356
|
+
"text": "boolean"
|
|
5357
|
+
},
|
|
5358
|
+
{
|
|
5359
|
+
"kind": "Content",
|
|
5360
|
+
"text": ";"
|
|
5361
|
+
}
|
|
5362
|
+
],
|
|
5363
|
+
"isStatic": false,
|
|
5364
|
+
"returnTypeTokenRange": {
|
|
5365
|
+
"startIndex": 5,
|
|
5366
|
+
"endIndex": 6
|
|
5367
|
+
},
|
|
5368
|
+
"releaseTag": "Beta",
|
|
5369
|
+
"isProtected": false,
|
|
5370
|
+
"overloadIndex": 1,
|
|
5371
|
+
"parameters": [
|
|
5372
|
+
{
|
|
5373
|
+
"parameterName": "interactionId",
|
|
5374
|
+
"parameterTypeTokenRange": {
|
|
5375
|
+
"startIndex": 1,
|
|
5376
|
+
"endIndex": 2
|
|
5377
|
+
},
|
|
5378
|
+
"isOptional": false
|
|
5379
|
+
},
|
|
5380
|
+
{
|
|
5381
|
+
"parameterName": "costUsd",
|
|
5382
|
+
"parameterTypeTokenRange": {
|
|
5383
|
+
"startIndex": 3,
|
|
5384
|
+
"endIndex": 4
|
|
5385
|
+
},
|
|
5386
|
+
"isOptional": false
|
|
5387
|
+
}
|
|
5388
|
+
],
|
|
5389
|
+
"isOptional": false,
|
|
5390
|
+
"isAbstract": false,
|
|
5391
|
+
"name": "recordExternalCost"
|
|
5392
|
+
},
|
|
5268
5393
|
{
|
|
5269
5394
|
"kind": "Method",
|
|
5270
5395
|
"canonicalReference": "@genesislcap/ai-assistant!ChatDriver#reportBudgetExhausted:member(1)",
|
|
@@ -9077,6 +9202,55 @@
|
|
|
9077
9202
|
"isAbstract": false,
|
|
9078
9203
|
"name": "handleInteractionCompleted"
|
|
9079
9204
|
},
|
|
9205
|
+
{
|
|
9206
|
+
"kind": "Method",
|
|
9207
|
+
"canonicalReference": "@genesislcap/ai-assistant!FoundationAiAssistant#handleInteractionCost:member(1)",
|
|
9208
|
+
"docComment": "/**\n * A widget reporting spend it incurred AFTER resolving.\n *\n * Note what this deliberately does NOT do: no `startLoadingTimer()`. This is bookkeeping about a turn that already finished, so it must be invisible — showing a spinner would tell the user the assistant is working when nothing is pending.\n */\n",
|
|
9209
|
+
"excerptTokens": [
|
|
9210
|
+
{
|
|
9211
|
+
"kind": "Content",
|
|
9212
|
+
"text": "handleInteractionCost(e: "
|
|
9213
|
+
},
|
|
9214
|
+
{
|
|
9215
|
+
"kind": "Reference",
|
|
9216
|
+
"text": "Event",
|
|
9217
|
+
"canonicalReference": "!Event:interface"
|
|
9218
|
+
},
|
|
9219
|
+
{
|
|
9220
|
+
"kind": "Content",
|
|
9221
|
+
"text": "): "
|
|
9222
|
+
},
|
|
9223
|
+
{
|
|
9224
|
+
"kind": "Content",
|
|
9225
|
+
"text": "void"
|
|
9226
|
+
},
|
|
9227
|
+
{
|
|
9228
|
+
"kind": "Content",
|
|
9229
|
+
"text": ";"
|
|
9230
|
+
}
|
|
9231
|
+
],
|
|
9232
|
+
"isStatic": false,
|
|
9233
|
+
"returnTypeTokenRange": {
|
|
9234
|
+
"startIndex": 3,
|
|
9235
|
+
"endIndex": 4
|
|
9236
|
+
},
|
|
9237
|
+
"releaseTag": "Beta",
|
|
9238
|
+
"isProtected": false,
|
|
9239
|
+
"overloadIndex": 1,
|
|
9240
|
+
"parameters": [
|
|
9241
|
+
{
|
|
9242
|
+
"parameterName": "e",
|
|
9243
|
+
"parameterTypeTokenRange": {
|
|
9244
|
+
"startIndex": 1,
|
|
9245
|
+
"endIndex": 2
|
|
9246
|
+
},
|
|
9247
|
+
"isOptional": false
|
|
9248
|
+
}
|
|
9249
|
+
],
|
|
9250
|
+
"isOptional": false,
|
|
9251
|
+
"isAbstract": false,
|
|
9252
|
+
"name": "handleInteractionCost"
|
|
9253
|
+
},
|
|
9080
9254
|
{
|
|
9081
9255
|
"kind": "Method",
|
|
9082
9256
|
"canonicalReference": "@genesislcap/ai-assistant!FoundationAiAssistant#handlePopout:member(1)",
|
|
@@ -14889,6 +15063,70 @@
|
|
|
14889
15063
|
"isAbstract": false,
|
|
14890
15064
|
"name": "primeRestoredAgentState"
|
|
14891
15065
|
},
|
|
15066
|
+
{
|
|
15067
|
+
"kind": "Method",
|
|
15068
|
+
"canonicalReference": "@genesislcap/ai-assistant!OrchestratingDriver#recordExternalCost:member(1)",
|
|
15069
|
+
"docComment": "/**\n * Delegated for the same reason as `resolveInteraction`: the history that owns the interaction — and therefore the cost — lives on the wrapped driver, not here.\n */\n",
|
|
15070
|
+
"excerptTokens": [
|
|
15071
|
+
{
|
|
15072
|
+
"kind": "Content",
|
|
15073
|
+
"text": "recordExternalCost(interactionId: "
|
|
15074
|
+
},
|
|
15075
|
+
{
|
|
15076
|
+
"kind": "Content",
|
|
15077
|
+
"text": "string"
|
|
15078
|
+
},
|
|
15079
|
+
{
|
|
15080
|
+
"kind": "Content",
|
|
15081
|
+
"text": ", costUsd: "
|
|
15082
|
+
},
|
|
15083
|
+
{
|
|
15084
|
+
"kind": "Content",
|
|
15085
|
+
"text": "number"
|
|
15086
|
+
},
|
|
15087
|
+
{
|
|
15088
|
+
"kind": "Content",
|
|
15089
|
+
"text": "): "
|
|
15090
|
+
},
|
|
15091
|
+
{
|
|
15092
|
+
"kind": "Content",
|
|
15093
|
+
"text": "boolean"
|
|
15094
|
+
},
|
|
15095
|
+
{
|
|
15096
|
+
"kind": "Content",
|
|
15097
|
+
"text": ";"
|
|
15098
|
+
}
|
|
15099
|
+
],
|
|
15100
|
+
"isStatic": false,
|
|
15101
|
+
"returnTypeTokenRange": {
|
|
15102
|
+
"startIndex": 5,
|
|
15103
|
+
"endIndex": 6
|
|
15104
|
+
},
|
|
15105
|
+
"releaseTag": "Beta",
|
|
15106
|
+
"isProtected": false,
|
|
15107
|
+
"overloadIndex": 1,
|
|
15108
|
+
"parameters": [
|
|
15109
|
+
{
|
|
15110
|
+
"parameterName": "interactionId",
|
|
15111
|
+
"parameterTypeTokenRange": {
|
|
15112
|
+
"startIndex": 1,
|
|
15113
|
+
"endIndex": 2
|
|
15114
|
+
},
|
|
15115
|
+
"isOptional": false
|
|
15116
|
+
},
|
|
15117
|
+
{
|
|
15118
|
+
"parameterName": "costUsd",
|
|
15119
|
+
"parameterTypeTokenRange": {
|
|
15120
|
+
"startIndex": 3,
|
|
15121
|
+
"endIndex": 4
|
|
15122
|
+
},
|
|
15123
|
+
"isOptional": false
|
|
15124
|
+
}
|
|
15125
|
+
],
|
|
15126
|
+
"isOptional": false,
|
|
15127
|
+
"isAbstract": false,
|
|
15128
|
+
"name": "recordExternalCost"
|
|
15129
|
+
},
|
|
14892
15130
|
{
|
|
14893
15131
|
"kind": "Method",
|
|
14894
15132
|
"canonicalReference": "@genesislcap/ai-assistant!OrchestratingDriver#resolveInteraction:member(1)",
|
package/dist/ai-assistant.d.ts
CHANGED
|
@@ -597,6 +597,16 @@ export declare interface AiDriver extends EventTarget {
|
|
|
597
597
|
* Resolve a pending blocking interaction with the given result.
|
|
598
598
|
*/
|
|
599
599
|
resolveInteraction(interactionId: string, result: unknown): void;
|
|
600
|
+
/**
|
|
601
|
+
* Record external spend against an interaction that has ALREADY resolved.
|
|
602
|
+
*
|
|
603
|
+
* For widgets that resolve early — so the assistant stops waiting — and then keep doing paid work
|
|
604
|
+
* on the user's behalf. Reports a positive DELTA; repeated calls sum. Returns false when the
|
|
605
|
+
* message is no longer in history.
|
|
606
|
+
*
|
|
607
|
+
* @beta
|
|
608
|
+
*/
|
|
609
|
+
recordExternalCost?(interactionId: string, costUsd: number): boolean;
|
|
600
610
|
/**
|
|
601
611
|
* The live {@link InteractionContext} for a pending interaction (GENC-1390), or
|
|
602
612
|
* `undefined` if the interaction is resolved/evicted or the driver owns no
|
|
@@ -1858,6 +1868,34 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
|
|
|
1858
1868
|
* bubble and/or shows the "Assistant" label.
|
|
1859
1869
|
*/
|
|
1860
1870
|
requestInteraction<T>(componentName: string, data: any, options?: InteractionRequestOptions): Promise<T>;
|
|
1871
|
+
/**
|
|
1872
|
+
* Add external (non-LLM) spend to an interaction's message AFTER it has resolved.
|
|
1873
|
+
*
|
|
1874
|
+
* **Why this exists separately from `resolveInteraction`.** A widget's spend reaches the session
|
|
1875
|
+
* total only through `InteractionResult.costUsd`, which is read exactly once — `resolveInteraction`
|
|
1876
|
+
* does its whole job inside `if (interaction)` and then deletes the entry from
|
|
1877
|
+
* `pendingInteractions`. That is correct for the resolution itself, but it assumes a widget stops
|
|
1878
|
+
* costing money when it resolves, and several deliberately do not: a widget that resolves EARLY so
|
|
1879
|
+
* the assistant stops waiting (options shown, a preview rendered) may stay interactive for minutes
|
|
1880
|
+
* afterwards and do more paid work on the user's behalf. Re-emitting `interaction-completed` does
|
|
1881
|
+
* not help — with the interaction gone from the map the call is a silent no-op — so that spend had
|
|
1882
|
+
* nowhere to go and was simply missing from the figure shown to the user.
|
|
1883
|
+
*
|
|
1884
|
+
* Additive by design: the caller reports a DELTA, not a running total, so repeated calls sum. It
|
|
1885
|
+
* touches only `externalCostUsd`; the recorded `interaction.resolved` payload is left exactly as
|
|
1886
|
+
* the resolution wrote it, because this is not a second resolution and must not read like one.
|
|
1887
|
+
*
|
|
1888
|
+
* Deliberately does NOT require the interaction to be pending, does not resurrect it, and has no
|
|
1889
|
+
* loading/turn side effects — this is bookkeeping about a turn that already happened.
|
|
1890
|
+
*
|
|
1891
|
+
* @param interactionId the interaction whose message owns the spend.
|
|
1892
|
+
* @param costUsd a positive delta in USD. Non-finite, zero and negative values are ignored.
|
|
1893
|
+
* @returns `true` when the spend was recorded; `false` when the message is no longer in history
|
|
1894
|
+
* (trimmed or condensed away), which is a real outcome the caller may want to log rather than a
|
|
1895
|
+
* failure to throw on.
|
|
1896
|
+
* @beta
|
|
1897
|
+
*/
|
|
1898
|
+
recordExternalCost(interactionId: string, costUsd: number): boolean;
|
|
1861
1899
|
/**
|
|
1862
1900
|
* Resolve a pending interaction. The wrapper component calls this on completion.
|
|
1863
1901
|
* Marks the interaction message as resolved so it renders read-only on re-render.
|
|
@@ -2057,6 +2095,10 @@ declare type ChatInteractionEventsMap = {
|
|
|
2057
2095
|
'interaction-completed': InteractionResult<unknown> & {
|
|
2058
2096
|
interactionId: string;
|
|
2059
2097
|
};
|
|
2098
|
+
'interaction-cost': {
|
|
2099
|
+
interactionId: string;
|
|
2100
|
+
costUsd: number;
|
|
2101
|
+
};
|
|
2060
2102
|
};
|
|
2061
2103
|
|
|
2062
2104
|
export { ChatThinkingPolicy }
|
|
@@ -3914,6 +3956,9 @@ export declare class FoundationAiAssistant extends GenesisElement {
|
|
|
3914
3956
|
removeAttachmentError(message: string): void;
|
|
3915
3957
|
private isAcceptedFile;
|
|
3916
3958
|
private readFileAsText;
|
|
3959
|
+
/** The base64 payload of a file, without any `data:` prefix — the raw form
|
|
3960
|
+
* `ChatImageAttachment.data` specifies (transports add their own framing). */
|
|
3961
|
+
private readFileAsBase64;
|
|
3917
3962
|
private processFiles;
|
|
3918
3963
|
private loadSelectedFiles;
|
|
3919
3964
|
handleSendClick(): void;
|
|
@@ -3960,6 +4005,14 @@ export declare class FoundationAiAssistant extends GenesisElement {
|
|
|
3960
4005
|
private send;
|
|
3961
4006
|
onChatHeaderMouseDown(e: MouseEvent): void;
|
|
3962
4007
|
handleInteractionCompleted(e: Event): void;
|
|
4008
|
+
/**
|
|
4009
|
+
* A widget reporting spend it incurred AFTER resolving.
|
|
4010
|
+
*
|
|
4011
|
+
* Note what this deliberately does NOT do: no `startLoadingTimer()`. This is bookkeeping about a
|
|
4012
|
+
* turn that already finished, so it must be invisible — showing a spinner would tell the user the
|
|
4013
|
+
* assistant is working when nothing is pending.
|
|
4014
|
+
*/
|
|
4015
|
+
handleInteractionCost(e: Event): void;
|
|
3963
4016
|
/**
|
|
3964
4017
|
* The live {@link InteractionContext} for a pending interaction (GENC-1390).
|
|
3965
4018
|
* `AiChatInteractionWrapper` pierces this across the shadow boundary to build the
|
|
@@ -4294,6 +4347,9 @@ export declare class OrchestratingDriver extends EventTarget implements AiDriver
|
|
|
4294
4347
|
budgetExhaustedMessage?: string;
|
|
4295
4348
|
});
|
|
4296
4349
|
resolveInteraction(interactionId: string, result: unknown): void;
|
|
4350
|
+
/** Delegated for the same reason as `resolveInteraction`: the history that owns the
|
|
4351
|
+
* interaction — and therefore the cost — lives on the wrapped driver, not here. */
|
|
4352
|
+
recordExternalCost(interactionId: string, costUsd: number): boolean;
|
|
4297
4353
|
getInteractionContext(interactionId: string): InteractionContext | undefined;
|
|
4298
4354
|
isBusy(): boolean;
|
|
4299
4355
|
/** Currently active provider name from the underlying ChatDriver. */
|
package/dist/chat-driver.cjs
CHANGED
|
@@ -3582,6 +3582,8 @@ var META_EVENT_IMPORTANCE = {
|
|
|
3582
3582
|
"provider.selected": "normal",
|
|
3583
3583
|
"interaction.requested": "normal",
|
|
3584
3584
|
"interaction.resolved": "normal",
|
|
3585
|
+
// Bookkeeping about an already-finished turn; interesting when reconciling a session total.
|
|
3586
|
+
"interaction.external-cost": "normal",
|
|
3585
3587
|
"external-diagnostics.folded": "normal",
|
|
3586
3588
|
"session.cleared": "normal",
|
|
3587
3589
|
"session.switched": "low",
|
|
@@ -5067,6 +5069,50 @@ Output format (strict):
|
|
|
5067
5069
|
});
|
|
5068
5070
|
});
|
|
5069
5071
|
}
|
|
5072
|
+
/**
|
|
5073
|
+
* Add external (non-LLM) spend to an interaction's message AFTER it has resolved.
|
|
5074
|
+
*
|
|
5075
|
+
* **Why this exists separately from `resolveInteraction`.** A widget's spend reaches the session
|
|
5076
|
+
* total only through `InteractionResult.costUsd`, which is read exactly once — `resolveInteraction`
|
|
5077
|
+
* does its whole job inside `if (interaction)` and then deletes the entry from
|
|
5078
|
+
* `pendingInteractions`. That is correct for the resolution itself, but it assumes a widget stops
|
|
5079
|
+
* costing money when it resolves, and several deliberately do not: a widget that resolves EARLY so
|
|
5080
|
+
* the assistant stops waiting (options shown, a preview rendered) may stay interactive for minutes
|
|
5081
|
+
* afterwards and do more paid work on the user's behalf. Re-emitting `interaction-completed` does
|
|
5082
|
+
* not help — with the interaction gone from the map the call is a silent no-op — so that spend had
|
|
5083
|
+
* nowhere to go and was simply missing from the figure shown to the user.
|
|
5084
|
+
*
|
|
5085
|
+
* Additive by design: the caller reports a DELTA, not a running total, so repeated calls sum. It
|
|
5086
|
+
* touches only `externalCostUsd`; the recorded `interaction.resolved` payload is left exactly as
|
|
5087
|
+
* the resolution wrote it, because this is not a second resolution and must not read like one.
|
|
5088
|
+
*
|
|
5089
|
+
* Deliberately does NOT require the interaction to be pending, does not resurrect it, and has no
|
|
5090
|
+
* loading/turn side effects — this is bookkeeping about a turn that already happened.
|
|
5091
|
+
*
|
|
5092
|
+
* @param interactionId the interaction whose message owns the spend.
|
|
5093
|
+
* @param costUsd a positive delta in USD. Non-finite, zero and negative values are ignored.
|
|
5094
|
+
* @returns `true` when the spend was recorded; `false` when the message is no longer in history
|
|
5095
|
+
* (trimmed or condensed away), which is a real outcome the caller may want to log rather than a
|
|
5096
|
+
* failure to throw on.
|
|
5097
|
+
* @beta
|
|
5098
|
+
*/
|
|
5099
|
+
recordExternalCost(interactionId, costUsd) {
|
|
5100
|
+
if (!interactionId) return false;
|
|
5101
|
+
if (typeof costUsd !== "number" || !Number.isFinite(costUsd) || costUsd <= 0) return false;
|
|
5102
|
+
const idx = this.history.findIndex((m) => m.interaction?.interactionId === interactionId);
|
|
5103
|
+
if (idx === -1) return false;
|
|
5104
|
+
this.history[idx] = {
|
|
5105
|
+
...this.history[idx],
|
|
5106
|
+
externalCostUsd: (this.history[idx].externalCostUsd ?? 0) + costUsd
|
|
5107
|
+
};
|
|
5108
|
+
recordMetaEvent(this.sessionKey, "interaction.external-cost", { interactionId, costUsd });
|
|
5109
|
+
this.dispatchEvent(
|
|
5110
|
+
new CustomEvent("history-updated", {
|
|
5111
|
+
detail: this.history
|
|
5112
|
+
})
|
|
5113
|
+
);
|
|
5114
|
+
return true;
|
|
5115
|
+
}
|
|
5070
5116
|
/**
|
|
5071
5117
|
* Resolve a pending interaction. The wrapper component calls this on completion.
|
|
5072
5118
|
* Marks the interaction message as resolved so it renders read-only on re-render.
|
|
@@ -6510,6 +6556,11 @@ var OrchestratingDriver = class extends EventTarget {
|
|
|
6510
6556
|
resolveInteraction(interactionId, result) {
|
|
6511
6557
|
this.chatDriver.resolveInteraction(interactionId, result);
|
|
6512
6558
|
}
|
|
6559
|
+
/** Delegated for the same reason as `resolveInteraction`: the history that owns the
|
|
6560
|
+
* interaction — and therefore the cost — lives on the wrapped driver, not here. */
|
|
6561
|
+
recordExternalCost(interactionId, costUsd) {
|
|
6562
|
+
return this.chatDriver.recordExternalCost(interactionId, costUsd);
|
|
6563
|
+
}
|
|
6513
6564
|
getInteractionContext(interactionId) {
|
|
6514
6565
|
return this.chatDriver.getInteractionContext(interactionId);
|
|
6515
6566
|
}
|