@adonis-agora/agent 0.48.0 → 0.50.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/CHANGELOG.md +29 -0
- package/dist/providers/agent_provider.d.ts.map +1 -1
- package/dist/providers/agent_provider.js +225 -46
- package/dist/providers/agent_provider.js.map +1 -1
- package/dist/providers/dashboard_provider.js +1 -1
- package/dist/providers/dashboard_provider.js.map +1 -1
- package/dist/src/agent-loop.d.ts +18 -0
- package/dist/src/agent-loop.d.ts.map +1 -1
- package/dist/src/agent-loop.js +52 -8
- package/dist/src/agent-loop.js.map +1 -1
- package/dist/src/agent-service.d.ts +129 -9
- package/dist/src/agent-service.d.ts.map +1 -1
- package/dist/src/agent-service.js +284 -8
- package/dist/src/agent-service.js.map +1 -1
- package/dist/src/chat-queue-service.d.ts +153 -0
- package/dist/src/chat-queue-service.d.ts.map +1 -0
- package/dist/src/chat-queue-service.js +360 -0
- package/dist/src/chat-queue-service.js.map +1 -0
- package/dist/src/client/chat-client.d.ts +52 -0
- package/dist/src/client/chat-client.d.ts.map +1 -1
- package/dist/src/client/chat-client.js +51 -2
- package/dist/src/client/chat-client.js.map +1 -1
- package/dist/src/client/index.d.ts +1 -1
- package/dist/src/client/index.d.ts.map +1 -1
- package/dist/src/client/index.js +1 -1
- package/dist/src/client/index.js.map +1 -1
- package/dist/src/client/sse.d.ts +5 -0
- package/dist/src/client/sse.d.ts.map +1 -1
- package/dist/src/client/sse.js +5 -1
- package/dist/src/client/sse.js.map +1 -1
- package/dist/src/define_config.d.ts +3 -1
- package/dist/src/define_config.d.ts.map +1 -1
- package/dist/src/define_config.js.map +1 -1
- package/dist/src/durable/agent-run-context.d.ts +6 -0
- package/dist/src/durable/agent-run-context.d.ts.map +1 -1
- package/dist/src/durable/agent-run-context.js.map +1 -1
- package/dist/src/durable/agent-run-workflow.d.ts.map +1 -1
- package/dist/src/durable/agent-run-workflow.js +94 -6
- package/dist/src/durable/agent-run-workflow.js.map +1 -1
- package/dist/src/durable/durable-agent-runner.d.ts +19 -3
- package/dist/src/durable/durable-agent-runner.d.ts.map +1 -1
- package/dist/src/durable/durable-agent-runner.js +62 -3
- package/dist/src/durable/durable-agent-runner.js.map +1 -1
- package/dist/src/elicitation.d.ts +12 -0
- package/dist/src/elicitation.d.ts.map +1 -1
- package/dist/src/elicitation.js +9 -1
- package/dist/src/elicitation.js.map +1 -1
- package/dist/src/index.d.ts +8 -5
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -4
- package/dist/src/index.js.map +1 -1
- package/dist/src/react/use-agent-chat.d.ts.map +1 -1
- package/dist/src/react/use-agent-chat.js +15 -1
- package/dist/src/react/use-agent-chat.js.map +1 -1
- package/dist/src/runners/inline-agent-runner.d.ts +30 -6
- package/dist/src/runners/inline-agent-runner.d.ts.map +1 -1
- package/dist/src/runners/inline-agent-runner.js +117 -21
- package/dist/src/runners/inline-agent-runner.js.map +1 -1
- package/dist/src/spi/agent-runner.d.ts +20 -1
- package/dist/src/spi/agent-runner.d.ts.map +1 -1
- package/dist/src/spi/chat-queue.d.ts +133 -0
- package/dist/src/spi/chat-queue.d.ts.map +1 -0
- package/dist/src/spi/chat-queue.js +48 -0
- package/dist/src/spi/chat-queue.js.map +1 -0
- package/dist/src/spi/model-catalog.d.ts +13 -0
- package/dist/src/spi/model-catalog.d.ts.map +1 -1
- package/dist/src/spi/model-catalog.js.map +1 -1
- package/dist/src/spi/quota-provider.d.ts +30 -1
- package/dist/src/spi/quota-provider.d.ts.map +1 -1
- package/dist/src/spi/quota-provider.js +34 -1
- package/dist/src/spi/quota-provider.js.map +1 -1
- package/dist/src/stores/ledger-quota-provider.d.ts +10 -1
- package/dist/src/stores/ledger-quota-provider.d.ts.map +1 -1
- package/dist/src/stores/ledger-quota-provider.js +14 -3
- package/dist/src/stores/ledger-quota-provider.js.map +1 -1
- package/dist/src/stores/lucid-schema.d.ts +8 -6
- package/dist/src/stores/lucid-schema.d.ts.map +1 -1
- package/dist/src/stores/lucid-schema.js +34 -7
- package/dist/src/stores/lucid-schema.js.map +1 -1
- package/dist/src/stores/lucid.d.ts +23 -1
- package/dist/src/stores/lucid.d.ts.map +1 -1
- package/dist/src/stores/lucid.js +192 -0
- package/dist/src/stores/lucid.js.map +1 -1
- package/dist/src/stream-events.d.ts +17 -0
- package/dist/src/stream-events.d.ts.map +1 -1
- package/dist/src/testing/chat-queue-store-contract.d.ts +26 -0
- package/dist/src/testing/chat-queue-store-contract.d.ts.map +1 -0
- package/dist/src/testing/chat-queue-store-contract.js +162 -0
- package/dist/src/testing/chat-queue-store-contract.js.map +1 -0
- package/dist/src/testing/in-memory-store.d.ts +20 -1
- package/dist/src/testing/in-memory-store.d.ts.map +1 -1
- package/dist/src/testing/in-memory-store.js +125 -0
- package/dist/src/testing/in-memory-store.js.map +1 -1
- package/dist/src/testing/index.d.ts +1 -0
- package/dist/src/testing/index.d.ts.map +1 -1
- package/dist/src/testing/index.js +1 -0
- package/dist/src/testing/index.js.map +1 -1
- package/dist/src/tool-presentation.d.ts +5 -0
- package/dist/src/tool-presentation.d.ts.map +1 -1
- package/dist/src/tool-presentation.js +5 -1
- package/dist/src/tool-presentation.js.map +1 -1
- package/dist/src/types.d.ts +25 -1
- package/dist/src/types.d.ts.map +1 -1
- package/dist/stubs/database/migrations/create_agent_tables.stub +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import type { Actor, MessageAttachment, PageContext } from '../types.js';
|
|
2
|
+
import { type AgentStore } from './agent-store.js';
|
|
3
|
+
/**
|
|
4
|
+
* Why a thread's queue stopped draining. A paused queue keeps its messages; nothing starts until
|
|
5
|
+
* someone resumes it (`POST <base>/threads/:id/queue/resume`, `chat.queue.resume()`).
|
|
6
|
+
*
|
|
7
|
+
* - `run_failed` the turn before it failed — the next message would likely fail the same way,
|
|
8
|
+
* and the person should see the error before more of their messages are spent.
|
|
9
|
+
* - `cancelled` someone pressed Stop. Stop means stop: the queue does not start behind it.
|
|
10
|
+
* An interrupt (`mode: 'interrupt'`) is the exception — its message starts.
|
|
11
|
+
* - `quota_exceeded` the next message's actor is over budget; resuming later retries the check.
|
|
12
|
+
* - `start_failed` the next message could not be started (the runner refused it).
|
|
13
|
+
*/
|
|
14
|
+
export type QueuePauseReason = 'run_failed' | 'cancelled' | 'quota_exceeded' | 'start_failed';
|
|
15
|
+
export interface QueuePause {
|
|
16
|
+
reason: QueuePauseReason;
|
|
17
|
+
/** Human-facing detail (the failure, the quota window), when there is one. */
|
|
18
|
+
message?: string;
|
|
19
|
+
/** ISO-8601 instant the queue paused. */
|
|
20
|
+
at: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A message a person sent while a turn was still running on the thread, waiting its turn. It is not
|
|
24
|
+
* part of the transcript until it starts: the loop appends it as the turn's user message, exactly as
|
|
25
|
+
* if it had been sent then. Everything a send carries is captured at enqueue time, resolved and
|
|
26
|
+
* checked there (agent, model, attachments), so a queued message starts with no request around it.
|
|
27
|
+
*/
|
|
28
|
+
export interface QueuedMessage {
|
|
29
|
+
id: string;
|
|
30
|
+
threadId: string;
|
|
31
|
+
/** Who queued it. The turn it starts runs as this actor. */
|
|
32
|
+
actor: Actor;
|
|
33
|
+
content: string;
|
|
34
|
+
attachments?: MessageAttachment[];
|
|
35
|
+
agentName?: string;
|
|
36
|
+
model?: string;
|
|
37
|
+
pageContext?: PageContext;
|
|
38
|
+
/**
|
|
39
|
+
* Queued by an interrupt (`POST chat { mode: 'interrupt' }`): the running turn was cancelled to
|
|
40
|
+
* make room for it, so the cancel starts it instead of pausing the queue.
|
|
41
|
+
*/
|
|
42
|
+
interrupt?: boolean;
|
|
43
|
+
createdAt: string;
|
|
44
|
+
updatedAt: string;
|
|
45
|
+
}
|
|
46
|
+
/** A queued message as the wire shows it — {@link QueuedMessage} without the actor or thread. */
|
|
47
|
+
export interface QueuedMessageView {
|
|
48
|
+
id: string;
|
|
49
|
+
content: string;
|
|
50
|
+
attachments?: MessageAttachment[];
|
|
51
|
+
agentName?: string;
|
|
52
|
+
model?: string;
|
|
53
|
+
interrupt?: boolean;
|
|
54
|
+
createdAt: string;
|
|
55
|
+
updatedAt: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* A thread's queue: its waiting messages in the order they will run, and whether it is draining.
|
|
59
|
+
* What `GET <base>/threads/:id/queue` answers, what `ThreadDetail.queue` carries, and what every
|
|
60
|
+
* `queue` stream frame snapshots.
|
|
61
|
+
*/
|
|
62
|
+
export interface ChatQueueState {
|
|
63
|
+
items: QueuedMessageView[];
|
|
64
|
+
paused: QueuePause | null;
|
|
65
|
+
}
|
|
66
|
+
export interface EnqueueMessageInput {
|
|
67
|
+
threadId: string;
|
|
68
|
+
actor: Actor;
|
|
69
|
+
content: string;
|
|
70
|
+
attachments?: MessageAttachment[];
|
|
71
|
+
agentName?: string;
|
|
72
|
+
model?: string;
|
|
73
|
+
pageContext?: PageContext;
|
|
74
|
+
interrupt?: boolean;
|
|
75
|
+
/** `'tail'` (default) runs it after everything already waiting; `'head'` runs it next. */
|
|
76
|
+
at?: 'tail' | 'head';
|
|
77
|
+
}
|
|
78
|
+
/** What `PATCH <base>/queue/:messageId` may change. An omitted key leaves the field as it is. */
|
|
79
|
+
export interface QueuedMessagePatch {
|
|
80
|
+
content?: string;
|
|
81
|
+
/** `null` drops every attachment. */
|
|
82
|
+
attachments?: MessageAttachment[] | null;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* A store that can hold a thread's queue of waiting messages, and admit ONE run per thread at a time.
|
|
86
|
+
*
|
|
87
|
+
* Probed STRUCTURALLY ({@link isChatQueueStore}), like `ThreadTurnReader`: a store that predates it
|
|
88
|
+
* keeps the old behaviour (a send on a busy thread starts a second, concurrent run). All members or
|
|
89
|
+
* none — a queue without the admission primitives cannot be drained safely across processes.
|
|
90
|
+
*
|
|
91
|
+
* Admission is the thread's active run (`activeRunId` on a thread read), compare-and-set:
|
|
92
|
+
* - {@link claimActiveStream} sets it to `runId` only when it is free, already `runId` (a retried
|
|
93
|
+
* claim is idempotent), or held by `replacing` (a handoff from the run that is settling, or a
|
|
94
|
+
* takeover from a holder the runner reports dead). Exactly one of two racing claims wins.
|
|
95
|
+
* - {@link releaseActiveStream} clears it only when `runId` still holds it — so a run that settles
|
|
96
|
+
* after it handed the thread to the next one cannot clear the next one's claim.
|
|
97
|
+
*/
|
|
98
|
+
export interface ChatQueueStore {
|
|
99
|
+
enqueueMessage(input: EnqueueMessageInput): Promise<QueuedMessage>;
|
|
100
|
+
/** The thread's waiting messages, in run order (the head first). */
|
|
101
|
+
listQueue(threadId: string): Promise<QueuedMessage[]>;
|
|
102
|
+
getQueuedMessage(id: string): Promise<QueuedMessage | null>;
|
|
103
|
+
/** `null` when there is no such message (it started, or was removed). */
|
|
104
|
+
updateQueuedMessage(id: string, patch: QueuedMessagePatch): Promise<QueuedMessage | null>;
|
|
105
|
+
/** Move a message to `index` (clamped) in its thread's run order. `false` when it is gone. */
|
|
106
|
+
moveQueuedMessage(id: string, index: number): Promise<boolean>;
|
|
107
|
+
/**
|
|
108
|
+
* Remove a message. `false` when it was already gone — which is also how a drain learns that the
|
|
109
|
+
* head it was about to start was deleted under it, so it must be a real conditional delete.
|
|
110
|
+
*/
|
|
111
|
+
removeQueuedMessage(id: string): Promise<boolean>;
|
|
112
|
+
/** Remove every waiting message on the thread; answers how many there were. */
|
|
113
|
+
clearQueue(threadId: string): Promise<number>;
|
|
114
|
+
queuePause(threadId: string): Promise<QueuePause | null>;
|
|
115
|
+
setQueuePause(threadId: string, pause: QueuePause | null): Promise<void>;
|
|
116
|
+
/** The run currently holding the thread, or `null`. */
|
|
117
|
+
activeRunForThread(threadId: string): Promise<string | null>;
|
|
118
|
+
claimActiveStream(threadId: string, runId: string, options?: {
|
|
119
|
+
replacing?: string;
|
|
120
|
+
}): Promise<boolean>;
|
|
121
|
+
releaseActiveStream(threadId: string, runId: string): Promise<boolean>;
|
|
122
|
+
}
|
|
123
|
+
/** Whether `store` implements every {@link ChatQueueStore} member. */
|
|
124
|
+
export declare function isChatQueueStore(store: AgentStore): store is AgentStore & ChatQueueStore;
|
|
125
|
+
/**
|
|
126
|
+
* Release the thread `runId` was streaming — conditionally when the store can compare, so a run
|
|
127
|
+
* that already handed the thread to the next queued turn does not clear that turn's claim; the old
|
|
128
|
+
* unconditional clear on a store that cannot.
|
|
129
|
+
*/
|
|
130
|
+
export declare function releaseThreadRun(store: AgentStore, threadId: string, runId: string): Promise<void>;
|
|
131
|
+
/** The wire view of a queued message. */
|
|
132
|
+
export declare function queuedMessageView(message: QueuedMessage): QueuedMessageView;
|
|
133
|
+
//# sourceMappingURL=chat-queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-queue.d.ts","sourceRoot":"","sources":["../../../src/spi/chat-queue.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { clearActiveRun } from './agent-store.js';
|
|
2
|
+
const CHAT_QUEUE_METHODS = [
|
|
3
|
+
'enqueueMessage',
|
|
4
|
+
'listQueue',
|
|
5
|
+
'getQueuedMessage',
|
|
6
|
+
'updateQueuedMessage',
|
|
7
|
+
'moveQueuedMessage',
|
|
8
|
+
'removeQueuedMessage',
|
|
9
|
+
'clearQueue',
|
|
10
|
+
'queuePause',
|
|
11
|
+
'setQueuePause',
|
|
12
|
+
'activeRunForThread',
|
|
13
|
+
'claimActiveStream',
|
|
14
|
+
'releaseActiveStream',
|
|
15
|
+
];
|
|
16
|
+
/** Whether `store` implements every {@link ChatQueueStore} member. */
|
|
17
|
+
export function isChatQueueStore(store) {
|
|
18
|
+
const candidate = store;
|
|
19
|
+
return CHAT_QUEUE_METHODS.every((method) => typeof candidate[method] === 'function');
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Release the thread `runId` was streaming — conditionally when the store can compare, so a run
|
|
23
|
+
* that already handed the thread to the next queued turn does not clear that turn's claim; the old
|
|
24
|
+
* unconditional clear on a store that cannot.
|
|
25
|
+
*/
|
|
26
|
+
export async function releaseThreadRun(store, threadId, runId) {
|
|
27
|
+
if (isChatQueueStore(store)) {
|
|
28
|
+
await store.releaseActiveStream(threadId, runId);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
await clearActiveRun(store, threadId, runId);
|
|
32
|
+
}
|
|
33
|
+
/** The wire view of a queued message. */
|
|
34
|
+
export function queuedMessageView(message) {
|
|
35
|
+
return {
|
|
36
|
+
id: message.id,
|
|
37
|
+
content: message.content,
|
|
38
|
+
...(message.attachments !== undefined && message.attachments.length > 0
|
|
39
|
+
? { attachments: message.attachments }
|
|
40
|
+
: {}),
|
|
41
|
+
...(message.agentName !== undefined ? { agentName: message.agentName } : {}),
|
|
42
|
+
...(message.model !== undefined ? { model: message.model } : {}),
|
|
43
|
+
...(message.interrupt === true ? { interrupt: true } : {}),
|
|
44
|
+
createdAt: message.createdAt,
|
|
45
|
+
updatedAt: message.updatedAt,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=chat-queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-queue.js","sourceRoot":"","sources":["../../../src/spi/chat-queue.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAuInE,MAAM,kBAAkB,GAAG;IACzB,gBAAgB;IAChB,WAAW;IACX,kBAAkB;IAClB,qBAAqB;IACrB,mBAAmB;IACnB,qBAAqB;IACrB,YAAY;IACZ,YAAY;IACZ,eAAe;IACf,oBAAoB;IACpB,mBAAmB;IACnB,qBAAqB;CAC+B,CAAC;AAEvD,sEAAsE;AACtE,MAAM,UAAU,gBAAgB,CAAC,KAAiB;IAChD,MAAM,SAAS,GAAG,KAA2C,CAAC;IAC9D,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,SAAS,CAAC,MAAM,CAAC,KAAK,UAAU,CAAC,CAAC;AACvF,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAAiB,EACjB,QAAgB,EAChB,KAAa;IAEb,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,KAAK,CAAC,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACjD,OAAO;IACT,CAAC;IACD,MAAM,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;AAC/C,CAAC;AAED,yCAAyC;AACzC,MAAM,UAAU,iBAAiB,CAAC,OAAsB;IACtD,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,GAAG,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;YACrE,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE;YACtC,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5E,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;KAC7B,CAAC;AACJ,CAAC"}
|
|
@@ -21,9 +21,22 @@ export interface ModelCatalogProviderGroup {
|
|
|
21
21
|
label: string;
|
|
22
22
|
models: ModelCatalogEntry[];
|
|
23
23
|
}
|
|
24
|
+
/** The agent always runs on one model: the picker shows it and offers no choice. */
|
|
25
|
+
export interface ModelCatalogLock {
|
|
26
|
+
/** The catalog id every turn runs on. */
|
|
27
|
+
model: string;
|
|
28
|
+
/** Why, in words a picker can show ("This assistant always uses GPT-5"). */
|
|
29
|
+
reason?: string;
|
|
30
|
+
}
|
|
24
31
|
/** What `GET <base>/models` answers. */
|
|
25
32
|
export interface ModelCatalogView {
|
|
26
33
|
providers: ModelCatalogProviderGroup[];
|
|
34
|
+
/**
|
|
35
|
+
* Present when the agent is locked to one model. Every turn runs on `locked.model` — a send's own
|
|
36
|
+
* `model` and a thread's pin included — and a send naming another model is refused (`400`). List
|
|
37
|
+
* the other models as unavailable too, so an older client that ignores the lock cannot pick them.
|
|
38
|
+
*/
|
|
39
|
+
locked?: ModelCatalogLock;
|
|
27
40
|
/** The model a turn runs on when nobody picked one; `null` when the provider decides. */
|
|
28
41
|
default: string | null;
|
|
29
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-catalog.d.ts","sourceRoot":"","sources":["../../../src/spi/model-catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,qBAAqB,CAAC;AAExE,mCAAmC;AACnC,MAAM,WAAW,iBAAiB;IAChC,oGAAoG;IACpG,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gGAAgG;IAChG,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,wGAAwG;IACxG,SAAS,EAAE,OAAO,CAAC;IACnB,yDAAyD;IACzD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yDAAyD;IACzD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,0DAA0D;AAC1D,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,iBAAiB,EAAE,CAAC;CAC7B;AAED,wCAAwC;AACxC,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,yBAAyB,EAAE,CAAC;IACvC,yFAAyF;IACzF,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,KAAK,CAAC;IACb,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,KAAK,EAAE,iBAAiB,GAAG,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC9E;AAED,qFAAqF;AACrF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,YAAY,CAEvE;AAED,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,gBAAgB,GAAG,YAAY,CAInF;AAED,sDAAsD;AACtD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,gBAAgB,EACtB,EAAE,EAAE,MAAM,GACT,iBAAiB,GAAG,SAAS,CAM/B;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,CAIvF;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF"}
|
|
1
|
+
{"version":3,"file":"model-catalog.d.ts","sourceRoot":"","sources":["../../../src/spi/model-catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,qBAAqB,CAAC;AAExE,mCAAmC;AACnC,MAAM,WAAW,iBAAiB;IAChC,oGAAoG;IACpG,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gGAAgG;IAChG,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,wGAAwG;IACxG,SAAS,EAAE,OAAO,CAAC;IACnB,yDAAyD;IACzD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yDAAyD;IACzD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,0DAA0D;AAC1D,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,iBAAiB,EAAE,CAAC;CAC7B;AAED,oFAAoF;AACpF,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wCAAwC;AACxC,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,yBAAyB,EAAE,CAAC;IACvC;;;;OAIG;IACH,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,yFAAyF;IACzF,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,KAAK,CAAC;IACb,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,KAAK,EAAE,iBAAiB,GAAG,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC9E;AAED,qFAAqF;AACrF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,YAAY,CAEvE;AAED,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,gBAAgB,GAAG,YAAY,CAInF;AAED,sDAAsD;AACtD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,gBAAgB,EACtB,EAAE,EAAE,MAAM,GACT,iBAAiB,GAAG,SAAS,CAM/B;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,CAIvF;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-catalog.js","sourceRoot":"","sources":["../../../src/spi/model-catalog.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"model-catalog.js","sourceRoot":"","sources":["../../../src/spi/model-catalog.ts"],"names":[],"mappings":"AAkEA,qFAAqF;AACrF,MAAM,UAAU,kBAAkB,CAAC,IAAsB;IACvD,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC;AAC9B,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,cAAc,CAAC,KAAsC;IACnE,OAAO,OAAQ,KAAsB,CAAC,IAAI,KAAK,UAAU;QACvD,CAAC,CAAE,KAAsB;QACzB,CAAC,CAAC,kBAAkB,CAAC,KAAyB,CAAC,CAAC;AACpD,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,gBAAgB,CAC9B,IAAsB,EACtB,EAAU;IAEV,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5D,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;IACxC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAuB,EAAE,KAAa;IACtE,OAAO;QACL,OAAO,EAAE,CAAC,IAAmB,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,CAAC;KACvE,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF"}
|
|
@@ -4,7 +4,11 @@ export type QuotaPeriod = 'day' | 'month';
|
|
|
4
4
|
/** One budget window: what was spent in it, and the ceiling when there is one. */
|
|
5
5
|
export interface QuotaWindow {
|
|
6
6
|
period: QuotaPeriod;
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Tokens used in the window. Absent → the budget does not count tokens (a USD-only spend cap, such
|
|
9
|
+
* as an AI gateway's) — never a fabricated `0`.
|
|
10
|
+
*/
|
|
11
|
+
usedTokens?: number;
|
|
8
12
|
/** Absent → no token ceiling on this window. */
|
|
9
13
|
limitTokens?: number;
|
|
10
14
|
usedUsd: number;
|
|
@@ -12,6 +16,11 @@ export interface QuotaWindow {
|
|
|
12
16
|
limitUsd?: number;
|
|
13
17
|
/** ISO-8601 instant the window starts over (next UTC midnight, first of next month). */
|
|
14
18
|
resetsAt?: string;
|
|
19
|
+
/**
|
|
20
|
+
* The soft limit: the share of a ceiling (`0..1`, e.g. `0.8`) past which a client should warn
|
|
21
|
+
* that the budget is running out. Absent → no warning for this window.
|
|
22
|
+
*/
|
|
23
|
+
warnAt?: number;
|
|
15
24
|
}
|
|
16
25
|
/** Which window stopped the actor, when one did. */
|
|
17
26
|
export interface QuotaBlock {
|
|
@@ -19,11 +28,24 @@ export interface QuotaBlock {
|
|
|
19
28
|
/** Words a client can show ("Monthly AI budget reached"). */
|
|
20
29
|
reason?: string;
|
|
21
30
|
}
|
|
31
|
+
/** A window past its soft limit ({@link QuotaWindow.warnAt}) but not exhausted. */
|
|
32
|
+
export interface QuotaWarning {
|
|
33
|
+
period: QuotaPeriod;
|
|
34
|
+
/** How much of the window's ceiling is used, `0..1` (the larger of spend and tokens). */
|
|
35
|
+
ratio: number;
|
|
36
|
+
/** Words a client can show ("80% of your monthly AI budget used"). */
|
|
37
|
+
reason?: string;
|
|
38
|
+
}
|
|
22
39
|
/** What `GET <base>/quota` answers. */
|
|
23
40
|
export interface QuotaReport {
|
|
24
41
|
windows: QuotaWindow[];
|
|
25
42
|
/** Present when a window is exhausted — a send will be refused until it resets. */
|
|
26
43
|
blocked?: QuotaBlock;
|
|
44
|
+
/**
|
|
45
|
+
* Present when a window crossed its `warnAt` and none is exhausted — the fullest one. A client
|
|
46
|
+
* may also derive it from the windows ({@link quotaWarning}); the server's wins.
|
|
47
|
+
*/
|
|
48
|
+
warning?: QuotaWarning;
|
|
27
49
|
}
|
|
28
50
|
export interface QuotaQuery {
|
|
29
51
|
actor: Actor;
|
|
@@ -44,6 +66,13 @@ export interface QuotaProvider {
|
|
|
44
66
|
}
|
|
45
67
|
/** The first window whose token or spend ceiling is reached, as a {@link QuotaBlock}. */
|
|
46
68
|
export declare function exhaustedWindow(windows: readonly QuotaWindow[]): QuotaBlock | undefined;
|
|
69
|
+
/** How much of `window`'s ceilings is used, `0..1+` (the larger of spend and tokens), or `null`. */
|
|
70
|
+
export declare function quotaUsedRatio(window: QuotaWindow): number | null;
|
|
71
|
+
/**
|
|
72
|
+
* The fullest window past its `warnAt`, as a {@link QuotaWarning} — `undefined` when none is, or
|
|
73
|
+
* when one is exhausted (that is `blocked`, not a warning).
|
|
74
|
+
*/
|
|
75
|
+
export declare function quotaWarning(windows: readonly QuotaWindow[]): QuotaWarning | undefined;
|
|
47
76
|
/** The UTC day range (`YYYY-MM-DD`, inclusive) and reset instant of `period` around `now`. */
|
|
48
77
|
export declare function quotaPeriodRange(period: QuotaPeriod, now: Date): {
|
|
49
78
|
fromDay: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quota-provider.d.ts","sourceRoot":"","sources":["../../../src/spi/quota-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,mDAAmD;AACnD,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,OAAO,CAAC;AAE1C,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"quota-provider.d.ts","sourceRoot":"","sources":["../../../src/spi/quota-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,mDAAmD;AACnD,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,OAAO,CAAC;AAE1C,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,WAAW,CAAC;IACpB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wFAAwF;IACxF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,oDAAoD;AACpD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,WAAW,CAAC;IACpB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,mFAAmF;AACnF,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,WAAW,CAAC;IACpB,yFAAyF;IACzF,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,uCAAuC;AACvC,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,mFAAmF;IACnF,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB;;;OAGG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,KAAK,CAAC;IACb,kDAAkD;IAClD,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CACjD;AAED,yFAAyF;AACzF,wBAAgB,eAAe,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,UAAU,GAAG,SAAS,CAavF;AAED,oGAAoG;AACpG,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAajE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,YAAY,GAAG,SAAS,CAYtF;AAED,8FAA8F;AAC9F,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,WAAW,EACnB,GAAG,EAAE,IAAI,GACR;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAetD;AAED,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAMtE;AAED,mGAAmG;AACnG,qBAAa,iBAAkB,SAAQ,KAAK;IAExC,QAAQ,CAAC,MAAM,EAAE,WAAW;IAD9B,YACW,MAAM,EAAE,WAAW,EAC5B,OAAO,EAAE,MAAM,EAIhB;CACF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** The first window whose token or spend ceiling is reached, as a {@link QuotaBlock}. */
|
|
2
2
|
export function exhaustedWindow(windows) {
|
|
3
3
|
for (const window of windows) {
|
|
4
|
-
const tokensOut = window.limitTokens !== undefined && window.usedTokens >= window.limitTokens;
|
|
4
|
+
const tokensOut = window.limitTokens !== undefined && (window.usedTokens ?? 0) >= window.limitTokens;
|
|
5
5
|
const spendOut = window.limitUsd !== undefined && window.usedUsd >= window.limitUsd;
|
|
6
6
|
if (tokensOut || spendOut) {
|
|
7
7
|
return {
|
|
@@ -12,6 +12,39 @@ export function exhaustedWindow(windows) {
|
|
|
12
12
|
}
|
|
13
13
|
return undefined;
|
|
14
14
|
}
|
|
15
|
+
/** How much of `window`'s ceilings is used, `0..1+` (the larger of spend and tokens), or `null`. */
|
|
16
|
+
export function quotaUsedRatio(window) {
|
|
17
|
+
const ratios = [];
|
|
18
|
+
if (window.limitUsd !== undefined && window.limitUsd > 0) {
|
|
19
|
+
ratios.push(window.usedUsd / window.limitUsd);
|
|
20
|
+
}
|
|
21
|
+
if (window.limitTokens !== undefined &&
|
|
22
|
+
window.limitTokens > 0 &&
|
|
23
|
+
window.usedTokens !== undefined) {
|
|
24
|
+
ratios.push(window.usedTokens / window.limitTokens);
|
|
25
|
+
}
|
|
26
|
+
return ratios.length === 0 ? null : Math.max(...ratios);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The fullest window past its `warnAt`, as a {@link QuotaWarning} — `undefined` when none is, or
|
|
30
|
+
* when one is exhausted (that is `blocked`, not a warning).
|
|
31
|
+
*/
|
|
32
|
+
export function quotaWarning(windows) {
|
|
33
|
+
if (exhaustedWindow(windows) !== undefined)
|
|
34
|
+
return undefined;
|
|
35
|
+
let fullest;
|
|
36
|
+
for (const window of windows) {
|
|
37
|
+
if (window.warnAt === undefined)
|
|
38
|
+
continue;
|
|
39
|
+
const ratio = quotaUsedRatio(window);
|
|
40
|
+
if (ratio === null || ratio < window.warnAt)
|
|
41
|
+
continue;
|
|
42
|
+
if (fullest === undefined || ratio > fullest.ratio) {
|
|
43
|
+
fullest = { period: window.period, ratio };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return fullest;
|
|
47
|
+
}
|
|
15
48
|
/** The UTC day range (`YYYY-MM-DD`, inclusive) and reset instant of `period` around `now`. */
|
|
16
49
|
export function quotaPeriodRange(period, now) {
|
|
17
50
|
const year = now.getUTCFullYear();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quota-provider.js","sourceRoot":"","sources":["../../../src/spi/quota-provider.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"quota-provider.js","sourceRoot":"","sources":["../../../src/spi/quota-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,14 @@ export interface QuotaLimits {
|
|
|
11
11
|
day?: QuotaWindowLimits;
|
|
12
12
|
month?: QuotaWindowLimits;
|
|
13
13
|
}
|
|
14
|
+
/** {@link LedgerQuotaProvider}'s tuning beyond the ceilings. */
|
|
15
|
+
export interface LedgerQuotaOptions {
|
|
16
|
+
/**
|
|
17
|
+
* The soft limit: the share of a ceiling (`0..1`) past which the report carries a `warning`.
|
|
18
|
+
* Stamped on every window that has a ceiling. Omit → no warnings.
|
|
19
|
+
*/
|
|
20
|
+
warnAt?: number;
|
|
21
|
+
}
|
|
14
22
|
/**
|
|
15
23
|
* A {@link QuotaProvider} over the usage ledger: a day window (tokens from `quotaToday`, spend from
|
|
16
24
|
* `usageBetween` when the store has it), and a month window when the store implements
|
|
@@ -24,7 +32,8 @@ export declare class LedgerQuotaProvider implements QuotaProvider {
|
|
|
24
32
|
private readonly store;
|
|
25
33
|
private readonly quota?;
|
|
26
34
|
private readonly limits;
|
|
27
|
-
|
|
35
|
+
private readonly options;
|
|
36
|
+
constructor(store: AgentStore, quota?: QuotaStore | undefined, limits?: QuotaLimits, options?: LedgerQuotaOptions);
|
|
28
37
|
report(query: QuotaQuery): Promise<QuotaReport>;
|
|
29
38
|
private dayWindow;
|
|
30
39
|
private window;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ledger-quota-provider.d.ts","sourceRoot":"","sources":["../../../src/stores/ledger-quota-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,WAAW,
|
|
1
|
+
{"version":3,"file":"ledger-quota-provider.d.ts","sourceRoot":"","sources":["../../../src/stores/ledger-quota-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,WAAW,EAIjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,wDAAwD;AACxD,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,gEAAgE;AAChE,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,iBAAiB,CAAC;IACxB,KAAK,CAAC,EAAE,iBAAiB,CAAC;CAC3B;AAED,gEAAgE;AAChE,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,qBAAa,mBAAoB,YAAW,aAAa;IAErD,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,YACmB,KAAK,EAAE,UAAU,EACjB,KAAK,CAAC,EAAE,UAAU,YAAA,EAClB,MAAM,GAAE,WAAgB,EACxB,OAAO,GAAE,kBAAuB,EAC/C;IAEE,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAgBpD;YAEa,SAAS;IAavB,OAAO,CAAC,MAAM;CAoBf"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { exhaustedWindow, quotaPeriodRange, } from '../spi/quota-provider.js';
|
|
1
|
+
import { exhaustedWindow, quotaPeriodRange, quotaWarning, } from '../spi/quota-provider.js';
|
|
2
2
|
/**
|
|
3
3
|
* A {@link QuotaProvider} over the usage ledger: a day window (tokens from `quotaToday`, spend from
|
|
4
4
|
* `usageBetween` when the store has it), and a month window when the store implements
|
|
@@ -12,10 +12,12 @@ export class LedgerQuotaProvider {
|
|
|
12
12
|
store;
|
|
13
13
|
quota;
|
|
14
14
|
limits;
|
|
15
|
-
|
|
15
|
+
options;
|
|
16
|
+
constructor(store, quota, limits = {}, options = {}) {
|
|
16
17
|
this.store = store;
|
|
17
18
|
this.quota = quota;
|
|
18
19
|
this.limits = limits;
|
|
20
|
+
this.options = options;
|
|
19
21
|
}
|
|
20
22
|
async report(query) {
|
|
21
23
|
const now = query.now ?? new Date();
|
|
@@ -27,7 +29,12 @@ export class LedgerQuotaProvider {
|
|
|
27
29
|
windows.push(this.window('month', used.usedTokens, used.costUsd, range.resetsAt));
|
|
28
30
|
}
|
|
29
31
|
const blocked = exhaustedWindow(windows);
|
|
30
|
-
|
|
32
|
+
const warning = quotaWarning(windows);
|
|
33
|
+
return {
|
|
34
|
+
windows,
|
|
35
|
+
...(blocked !== undefined ? { blocked } : {}),
|
|
36
|
+
...(warning !== undefined ? { warning } : {}),
|
|
37
|
+
};
|
|
31
38
|
}
|
|
32
39
|
async dayWindow(actorRef, now) {
|
|
33
40
|
const range = quotaPeriodRange('day', now);
|
|
@@ -49,6 +56,10 @@ export class LedgerQuotaProvider {
|
|
|
49
56
|
usedUsd,
|
|
50
57
|
...(limits.usd !== undefined ? { limitUsd: limits.usd } : {}),
|
|
51
58
|
resetsAt,
|
|
59
|
+
...(this.options.warnAt !== undefined &&
|
|
60
|
+
(limits.tokens !== undefined || limits.usd !== undefined)
|
|
61
|
+
? { warnAt: this.options.warnAt }
|
|
62
|
+
: {}),
|
|
52
63
|
};
|
|
53
64
|
}
|
|
54
65
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ledger-quota-provider.js","sourceRoot":"","sources":["../../../src/stores/ledger-quota-provider.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EAMf,gBAAgB,
|
|
1
|
+
{"version":3,"file":"ledger-quota-provider.js","sourceRoot":"","sources":["../../../src/stores/ledger-quota-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { LucidRawRunner } from './lucid.js';
|
|
2
2
|
/**
|
|
3
|
-
* The
|
|
3
|
+
* The seven agent table names. They match the cross-adapter snake_case contract the reference Drizzle
|
|
4
4
|
* store uses, so a dashboard or migration can point at any adapter and see the same physical schema.
|
|
5
5
|
*/
|
|
6
6
|
export declare const AGENT_TABLES: {
|
|
@@ -10,9 +10,11 @@ export declare const AGENT_TABLES: {
|
|
|
10
10
|
readonly tokenUsage: 'agent_token_usage';
|
|
11
11
|
readonly modelPricing: 'agent_model_pricing';
|
|
12
12
|
readonly runs: 'agent_run';
|
|
13
|
+
/** Messages sent while a turn was running, waiting to run after it (the chat queue). */
|
|
14
|
+
readonly queuedMessages: 'agent_queued_message';
|
|
13
15
|
};
|
|
14
16
|
/**
|
|
15
|
-
* `CREATE TABLE IF NOT EXISTS` DDL for the
|
|
17
|
+
* `CREATE TABLE IF NOT EXISTS` DDL for the seven agent tables plus their indexes, one statement per
|
|
16
18
|
* array element so each can be issued through Lucid's `rawQuery`. Portable across SQLite / Postgres /
|
|
17
19
|
* MySQL: quoted identifiers, epoch-ms `BIGINT` timestamps, `INTEGER` booleans (0/1) and `TEXT` JSON
|
|
18
20
|
* columns — no dialect-only types. A real deployment should prefer the bundled migration stub so the
|
|
@@ -29,7 +31,7 @@ export declare const AGENT_TABLES: {
|
|
|
29
31
|
*/
|
|
30
32
|
export declare function createTableStatements(): string[];
|
|
31
33
|
/**
|
|
32
|
-
* Idempotently provision the
|
|
34
|
+
* Idempotently provision the seven agent tables through Lucid's async raw runner (`CREATE TABLE IF
|
|
33
35
|
* NOT EXISTS`), then additively repair a database that predates run tracking by ALTERing in the
|
|
34
36
|
* `run_id` columns its three older tables are missing.
|
|
35
37
|
*
|
|
@@ -46,15 +48,15 @@ export declare function createTableStatements(): string[];
|
|
|
46
48
|
*/
|
|
47
49
|
export declare function createAgentTables(db: LucidRawRunner): Promise<string[]>;
|
|
48
50
|
/**
|
|
49
|
-
* `DROP TABLE IF EXISTS` for the
|
|
51
|
+
* `DROP TABLE IF EXISTS` for the seven agent tables, in reverse dependency order so a dialect that
|
|
50
52
|
* enforces the `REFERENCES` clauses never refuses a drop for a child that still exists. The mirror of
|
|
51
53
|
* {@link createAgentTables}, and what the published migration's `down()` calls.
|
|
52
54
|
*/
|
|
53
55
|
export declare function dropTableStatements(): string[];
|
|
54
|
-
/** Drop the
|
|
56
|
+
/** Drop the seven agent tables. Destructive and irreversible — this erases every thread and every ledger row. */
|
|
55
57
|
export declare function dropAgentTables(db: LucidRawRunner): Promise<void>;
|
|
56
58
|
/**
|
|
57
|
-
* Idempotently ensure the
|
|
59
|
+
* Idempotently ensure the seven agent tables exist, memoized per db client. This is what the stores
|
|
58
60
|
* call on first use when `autoCreateTables` is on (the default) — whichever store touches the
|
|
59
61
|
* connection first provisions the shared schema, so pricing seeds and governance reads work even
|
|
60
62
|
* before the first agent run.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lucid-schema.d.ts","sourceRoot":"","sources":["../../../src/stores/lucid-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;;GAGG;AACH,eAAO,MAAM,YAAY;aACvB,OAAO,EAAE,cAAc;aACvB,QAAQ,EAAE,eAAe;aACzB,SAAS,EAAE,iBAAiB;aAC5B,UAAU,EAAE,mBAAmB;aAC/B,YAAY,EAAE,qBAAqB;aACnC,IAAI,EAAE,WAAW;
|
|
1
|
+
{"version":3,"file":"lucid-schema.d.ts","sourceRoot":"","sources":["../../../src/stores/lucid-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;;GAGG;AACH,eAAO,MAAM,YAAY;aACvB,OAAO,EAAE,cAAc;aACvB,QAAQ,EAAE,eAAe;aACzB,SAAS,EAAE,iBAAiB;aAC5B,UAAU,EAAE,mBAAmB;aAC/B,YAAY,EAAE,qBAAqB;aACnC,IAAI,EAAE,WAAW;IACjB,wFAAwF;aACxF,cAAc,EAAE,sBAAsB;CAC9B,CAAC;AAEX;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CA6HhD;AAoDD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA6B7E;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,EAAE,CAW9C;AAED,iHAAiH;AACjH,wBAAsB,eAAe,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAIvE;AAWD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAanE"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The
|
|
2
|
+
* The seven agent table names. They match the cross-adapter snake_case contract the reference Drizzle
|
|
3
3
|
* store uses, so a dashboard or migration can point at any adapter and see the same physical schema.
|
|
4
4
|
*/
|
|
5
5
|
export const AGENT_TABLES = {
|
|
@@ -9,9 +9,11 @@ export const AGENT_TABLES = {
|
|
|
9
9
|
tokenUsage: 'agent_token_usage',
|
|
10
10
|
modelPricing: 'agent_model_pricing',
|
|
11
11
|
runs: 'agent_run',
|
|
12
|
+
/** Messages sent while a turn was running, waiting to run after it (the chat queue). */
|
|
13
|
+
queuedMessages: 'agent_queued_message',
|
|
12
14
|
};
|
|
13
15
|
/**
|
|
14
|
-
* `CREATE TABLE IF NOT EXISTS` DDL for the
|
|
16
|
+
* `CREATE TABLE IF NOT EXISTS` DDL for the seven agent tables plus their indexes, one statement per
|
|
15
17
|
* array element so each can be issued through Lucid's `rawQuery`. Portable across SQLite / Postgres /
|
|
16
18
|
* MySQL: quoted identifiers, epoch-ms `BIGINT` timestamps, `INTEGER` booleans (0/1) and `TEXT` JSON
|
|
17
19
|
* columns — no dialect-only types. A real deployment should prefer the bundled migration stub so the
|
|
@@ -41,6 +43,7 @@ export function createTableStatements() {
|
|
|
41
43
|
"summary_message_count" INTEGER NOT NULL DEFAULT 0,
|
|
42
44
|
"active_stream_id" VARCHAR(255) NULL,
|
|
43
45
|
"model" VARCHAR(255) NULL,
|
|
46
|
+
"queue_pause" TEXT NULL,
|
|
44
47
|
"created_at" BIGINT NOT NULL,
|
|
45
48
|
"updated_at" BIGINT NOT NULL,
|
|
46
49
|
"deleted_at" BIGINT NULL
|
|
@@ -134,6 +137,21 @@ export function createTableStatements() {
|
|
|
134
137
|
`CREATE INDEX IF NOT EXISTS "${t.runs}_started_idx" ON "${t.runs}" ("started_at")`,
|
|
135
138
|
`CREATE INDEX IF NOT EXISTS "${t.runs}_actor_started_idx" ON "${t.runs}" ("actor_ref", "started_at")`,
|
|
136
139
|
`CREATE INDEX IF NOT EXISTS "${t.runs}_status_started_idx" ON "${t.runs}" ("status", "started_at")`,
|
|
140
|
+
`CREATE TABLE IF NOT EXISTS "${t.queuedMessages}" (
|
|
141
|
+
"id" VARCHAR(255) PRIMARY KEY NOT NULL,
|
|
142
|
+
"thread_id" VARCHAR(255) NOT NULL REFERENCES "${t.threads}" ("id") ON DELETE CASCADE,
|
|
143
|
+
"actor" TEXT NOT NULL,
|
|
144
|
+
"content" TEXT NOT NULL,
|
|
145
|
+
"attachments" TEXT NULL,
|
|
146
|
+
"agent_name" VARCHAR(255) NULL,
|
|
147
|
+
"model" VARCHAR(255) NULL,
|
|
148
|
+
"page_context" TEXT NULL,
|
|
149
|
+
"interrupt" INTEGER NOT NULL DEFAULT 0,
|
|
150
|
+
"position" INTEGER NOT NULL,
|
|
151
|
+
"created_at" BIGINT NOT NULL,
|
|
152
|
+
"updated_at" BIGINT NOT NULL
|
|
153
|
+
)`,
|
|
154
|
+
`CREATE INDEX IF NOT EXISTS "${t.queuedMessages}_thread_position_idx" ON "${t.queuedMessages}" ("thread_id", "position")`,
|
|
137
155
|
];
|
|
138
156
|
}
|
|
139
157
|
/**
|
|
@@ -160,6 +178,7 @@ const ADDITIVE_COLUMNS = [
|
|
|
160
178
|
{ table: AGENT_TABLES.messages, column: 'ui', type: 'TEXT NULL' },
|
|
161
179
|
{ table: AGENT_TABLES.messages, column: 'feedback', type: 'TEXT NULL' },
|
|
162
180
|
{ table: AGENT_TABLES.threads, column: 'model', type: 'VARCHAR(255) NULL' },
|
|
181
|
+
{ table: AGENT_TABLES.threads, column: 'queue_pause', type: 'TEXT NULL' },
|
|
163
182
|
{ table: AGENT_TABLES.toolCalls, column: 'approver', type: 'VARCHAR(255) NULL' },
|
|
164
183
|
{ table: AGENT_TABLES.toolCalls, column: 'expires_at', type: 'BIGINT NULL' },
|
|
165
184
|
{ table: AGENT_TABLES.toolCalls, column: 'remember', type: 'INTEGER NULL' },
|
|
@@ -184,7 +203,7 @@ async function hasColumn(db, table, column) {
|
|
|
184
203
|
}
|
|
185
204
|
}
|
|
186
205
|
/**
|
|
187
|
-
* Idempotently provision the
|
|
206
|
+
* Idempotently provision the seven agent tables through Lucid's async raw runner (`CREATE TABLE IF
|
|
188
207
|
* NOT EXISTS`), then additively repair a database that predates run tracking by ALTERing in the
|
|
189
208
|
* `run_id` columns its three older tables are missing.
|
|
190
209
|
*
|
|
@@ -230,15 +249,23 @@ export async function createAgentTables(db) {
|
|
|
230
249
|
return repairs;
|
|
231
250
|
}
|
|
232
251
|
/**
|
|
233
|
-
* `DROP TABLE IF EXISTS` for the
|
|
252
|
+
* `DROP TABLE IF EXISTS` for the seven agent tables, in reverse dependency order so a dialect that
|
|
234
253
|
* enforces the `REFERENCES` clauses never refuses a drop for a child that still exists. The mirror of
|
|
235
254
|
* {@link createAgentTables}, and what the published migration's `down()` calls.
|
|
236
255
|
*/
|
|
237
256
|
export function dropTableStatements() {
|
|
238
257
|
const t = AGENT_TABLES;
|
|
239
|
-
return [
|
|
258
|
+
return [
|
|
259
|
+
t.queuedMessages,
|
|
260
|
+
t.runs,
|
|
261
|
+
t.tokenUsage,
|
|
262
|
+
t.toolCalls,
|
|
263
|
+
t.messages,
|
|
264
|
+
t.modelPricing,
|
|
265
|
+
t.threads,
|
|
266
|
+
].map((table) => `DROP TABLE IF EXISTS "${table}"`);
|
|
240
267
|
}
|
|
241
|
-
/** Drop the
|
|
268
|
+
/** Drop the seven agent tables. Destructive and irreversible — this erases every thread and every ledger row. */
|
|
242
269
|
export async function dropAgentTables(db) {
|
|
243
270
|
for (const stmt of dropTableStatements()) {
|
|
244
271
|
await db.rawQuery(stmt);
|
|
@@ -253,7 +280,7 @@ export async function dropAgentTables(db) {
|
|
|
253
280
|
*/
|
|
254
281
|
const provisioned = new WeakMap();
|
|
255
282
|
/**
|
|
256
|
-
* Idempotently ensure the
|
|
283
|
+
* Idempotently ensure the seven agent tables exist, memoized per db client. This is what the stores
|
|
257
284
|
* call on first use when `autoCreateTables` is on (the default) — whichever store touches the
|
|
258
285
|
* connection first provisions the shared schema, so pricing seeds and governance reads work even
|
|
259
286
|
* before the first agent run.
|