@driftengine/ai 3.61.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/LICENSE +202 -0
- package/NOTICE +9 -0
- package/README.md +103 -0
- package/dist/adapters/local.d.ts +29 -0
- package/dist/adapters/local.js +24 -0
- package/dist/adapters/proxy.d.ts +28 -0
- package/dist/adapters/proxy.js +138 -0
- package/dist/bridges/authority.d.ts +153 -0
- package/dist/bridges/authority.js +179 -0
- package/dist/bridges/navigation.d.ts +100 -0
- package/dist/bridges/navigation.js +139 -0
- package/dist/budget/budget.d.ts +34 -0
- package/dist/budget/budget.js +57 -0
- package/dist/command/apply.d.ts +24 -0
- package/dist/command/apply.js +40 -0
- package/dist/command/log.d.ts +55 -0
- package/dist/command/log.js +50 -0
- package/dist/context/assemble.d.ts +48 -0
- package/dist/context/assemble.js +55 -0
- package/dist/context/continuation.d.ts +14 -0
- package/dist/context/continuation.js +36 -0
- package/dist/describe/manifest.d.ts +70 -0
- package/dist/describe/manifest.js +99 -0
- package/dist/entities/context.d.ts +52 -0
- package/dist/entities/context.js +83 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.js +40 -0
- package/dist/policy/types.d.ts +55 -0
- package/dist/policy/types.js +26 -0
- package/dist/policy/utility.d.ts +18 -0
- package/dist/policy/utility.js +47 -0
- package/dist/provider/create.d.ts +16 -0
- package/dist/provider/create.js +57 -0
- package/dist/provider/latency.d.ts +27 -0
- package/dist/provider/latency.js +52 -0
- package/dist/provider/types.d.ts +90 -0
- package/dist/provider/types.js +8 -0
- package/dist/realtime/session.d.ts +35 -0
- package/dist/realtime/session.js +34 -0
- package/dist/session/agent.d.ts +217 -0
- package/dist/session/agent.js +506 -0
- package/dist/session/replay.d.ts +32 -0
- package/dist/session/replay.js +81 -0
- package/dist/session/states.d.ts +28 -0
- package/dist/session/states.js +33 -0
- package/dist/session/usage.d.ts +43 -0
- package/dist/session/usage.js +38 -0
- package/dist/testing/deterministic.d.ts +65 -0
- package/dist/testing/deterministic.js +150 -0
- package/dist/tools/policy.d.ts +47 -0
- package/dist/tools/policy.js +84 -0
- package/dist/tools/registry.d.ts +69 -0
- package/dist/tools/registry.js +75 -0
- package/dist/tools/validate.d.ts +24 -0
- package/dist/tools/validate.js +80 -0
- package/package.json +59 -0
- package/src/adapters/local.ts +64 -0
- package/src/adapters/proxy.ts +187 -0
- package/src/bridges/authority.ts +244 -0
- package/src/bridges/navigation.ts +207 -0
- package/src/budget/budget.ts +73 -0
- package/src/command/apply.ts +52 -0
- package/src/command/log.ts +81 -0
- package/src/context/assemble.ts +104 -0
- package/src/context/continuation.ts +39 -0
- package/src/describe/manifest.ts +148 -0
- package/src/entities/context.ts +112 -0
- package/src/index.ts +94 -0
- package/src/policy/types.ts +70 -0
- package/src/policy/utility.ts +53 -0
- package/src/provider/create.ts +70 -0
- package/src/provider/latency.ts +57 -0
- package/src/provider/types.ts +96 -0
- package/src/realtime/session.ts +63 -0
- package/src/session/agent.ts +622 -0
- package/src/session/replay.ts +96 -0
- package/src/session/states.ts +63 -0
- package/src/session/usage.ts +66 -0
- package/src/testing/deterministic.ts +204 -0
- package/src/tools/policy.ts +114 -0
- package/src/tools/registry.ts +122 -0
- package/src/tools/validate.ts +92 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import type { AiProvider } from '../provider/types.ts';
|
|
2
|
+
import type { AgentPolicy, Intent } from '../policy/types.ts';
|
|
3
|
+
import type { Budget } from '../budget/budget.ts';
|
|
4
|
+
import type { ToolRegistry } from '../tools/registry.ts';
|
|
5
|
+
import type { CommandLog } from '../command/log.ts';
|
|
6
|
+
import type { AiUsage } from './usage.ts';
|
|
7
|
+
import type { AgentState } from './states.ts';
|
|
8
|
+
export interface AgentSessionOptions<W = unknown> {
|
|
9
|
+
readonly agentId: string;
|
|
10
|
+
readonly policy: AgentPolicy;
|
|
11
|
+
/** Absent is a supported configuration, not a degraded one. The floor is enough. */
|
|
12
|
+
readonly provider?: AiProvider;
|
|
13
|
+
readonly budget?: Budget;
|
|
14
|
+
readonly model?: string;
|
|
15
|
+
/** Tools, and the admission guards they declared. Absent admits everything. */
|
|
16
|
+
readonly tools?: ToolRegistry<W>;
|
|
17
|
+
/** The consumer's world, handed to a guard unchanged. */
|
|
18
|
+
readonly world?: W;
|
|
19
|
+
/**
|
|
20
|
+
* What an observation arriving while a request is out does.
|
|
21
|
+
*
|
|
22
|
+
* `queue` and `replace pending` are deliberately absent. Both described what to do
|
|
23
|
+
* with a *second* request, and there is never one — the state machine has no edge
|
|
24
|
+
* on which it could be issued.
|
|
25
|
+
*/
|
|
26
|
+
readonly whileBusy?: WhileBusy;
|
|
27
|
+
readonly maxPendingObservations?: number;
|
|
28
|
+
readonly dedupeWindowMs?: number;
|
|
29
|
+
/** Where accepted model commands are recorded, so a run can be replayed exactly. */
|
|
30
|
+
readonly log?: CommandLog;
|
|
31
|
+
/**
|
|
32
|
+
* A ceiling on how long any one intent may hold the slot, in milliseconds.
|
|
33
|
+
*
|
|
34
|
+
* An intent with an unknown extent ends when the consumer says so, which is the
|
|
35
|
+
* contract — the consumer is the thing that knows whether the walk finished. But a
|
|
36
|
+
* consumer that forgets leaves the agent on one intent forever, which is the blocked
|
|
37
|
+
* agent arriving through the back door.
|
|
38
|
+
*
|
|
39
|
+
* Off by default, because a default here would be a guess about behaviours this
|
|
40
|
+
* package cannot see, and a wrong one would cut short a legitimately long action.
|
|
41
|
+
* *What it costs when set:* a genuinely long intent is reclaimed by the floor.
|
|
42
|
+
* *What would make it wrong:* a consumer whose intents legitimately outlast any
|
|
43
|
+
* figure worth writing down, which should set nothing and call `complete`.
|
|
44
|
+
*/
|
|
45
|
+
readonly maxIntentMs?: number;
|
|
46
|
+
/**
|
|
47
|
+
* A second, faster provider asked only when something interrupts.
|
|
48
|
+
*
|
|
49
|
+
* §46's tiering: a small or local model answers "something happened, react now" in
|
|
50
|
+
* well under the strong model's latency, while the strong one is still composing the
|
|
51
|
+
* next intent. Additive — absent, preemption behaves exactly as it does without it.
|
|
52
|
+
*
|
|
53
|
+
* *What it costs:* a second provider to configure and a second bill. *What would
|
|
54
|
+
* make it wrong:* an interrupt model slow enough that the floor beats it to the
|
|
55
|
+
* answer, at which point it is buying nothing the floor did not already give.
|
|
56
|
+
*/
|
|
57
|
+
readonly interruptProvider?: AiProvider;
|
|
58
|
+
}
|
|
59
|
+
export type WhileBusy = 'coalesce' | 'preempt' | 'drop';
|
|
60
|
+
export interface Observation {
|
|
61
|
+
readonly id: string;
|
|
62
|
+
readonly priority: number;
|
|
63
|
+
readonly text: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* One agent: a floor that always runs, and one slot holding what comes next.
|
|
67
|
+
*
|
|
68
|
+
* **The current slot is never empty.** When an intent finishes, the buffer drains into
|
|
69
|
+
* it; when the buffer is empty, the policy floor supplies. An agent with no provider
|
|
70
|
+
* configured behaves exactly as one whose provider is slow — less cleverly, and
|
|
71
|
+
* without ever standing still.
|
|
72
|
+
*
|
|
73
|
+
* `tick` is the whole surface a consumer needs inside its fixed step. It returns the
|
|
74
|
+
* intent to execute and never returns null.
|
|
75
|
+
*/
|
|
76
|
+
export declare class AgentSession<W = unknown> {
|
|
77
|
+
readonly agentId: string;
|
|
78
|
+
private readonly policy;
|
|
79
|
+
private readonly provider;
|
|
80
|
+
private readonly budget;
|
|
81
|
+
private readonly model;
|
|
82
|
+
private readonly tools;
|
|
83
|
+
private readonly whileBusy;
|
|
84
|
+
private readonly observations;
|
|
85
|
+
private readonly log;
|
|
86
|
+
private readonly maxIntentMs;
|
|
87
|
+
private readonly interruptProvider;
|
|
88
|
+
private readonly world;
|
|
89
|
+
private readonly latency;
|
|
90
|
+
private readonly usageState;
|
|
91
|
+
private agentState;
|
|
92
|
+
private currentIntent;
|
|
93
|
+
private bufferedIntent;
|
|
94
|
+
private startedAtMs;
|
|
95
|
+
private disposedReason;
|
|
96
|
+
private inFlight;
|
|
97
|
+
private inFlightAt;
|
|
98
|
+
/** When the pending response's request went out, or -1 when nothing has landed. */
|
|
99
|
+
private landedAtMs;
|
|
100
|
+
private discarded;
|
|
101
|
+
private issuedAtTick;
|
|
102
|
+
private inFlightGeneration;
|
|
103
|
+
private readonly context;
|
|
104
|
+
constructor(options: AgentSessionOptions<W>);
|
|
105
|
+
/**
|
|
106
|
+
* Something happened that the agent may care about.
|
|
107
|
+
*
|
|
108
|
+
* Never acted on here — an observation taken mid-tick would mutate the simulation
|
|
109
|
+
* halfway through a step. It waits for the next `tick`.
|
|
110
|
+
*/
|
|
111
|
+
observe(observation: Observation): void;
|
|
112
|
+
get state(): AgentState;
|
|
113
|
+
/** Never null once `tick` has run once. */
|
|
114
|
+
get current(): Intent | null;
|
|
115
|
+
get buffered(): Intent | null;
|
|
116
|
+
get usage(): Readonly<AiUsage>;
|
|
117
|
+
/**
|
|
118
|
+
* Advance one fixed step and return the intent to execute.
|
|
119
|
+
*
|
|
120
|
+
* Never returns null. That is the track's whole claim and it is asserted directly.
|
|
121
|
+
*/
|
|
122
|
+
tick(tickNumber: number, nowMs: number): Intent;
|
|
123
|
+
/** The consumer says the current intent is over, ahead of its expected extent. */
|
|
124
|
+
complete(nowMs: number): void;
|
|
125
|
+
/**
|
|
126
|
+
* End the current intent and fill the slot again.
|
|
127
|
+
*
|
|
128
|
+
* **Aborts a request that is still in flight.** `ahead -> intentCompleted -> idle`
|
|
129
|
+
* abandons the question, and a request nobody will read is a request that should
|
|
130
|
+
* stop costing money — but more than that, leaving it open means the next intent
|
|
131
|
+
* issues a second one and two are outstanding at once, which is the guarantee the
|
|
132
|
+
* state machine is shaped to make impossible. The state machine cannot see the
|
|
133
|
+
* provider; this is where the two are kept in agreement.
|
|
134
|
+
*/
|
|
135
|
+
private finish;
|
|
136
|
+
dispose(reason?: string): void;
|
|
137
|
+
/**
|
|
138
|
+
* Fill the current slot: from the buffer if something is there, from the floor if not.
|
|
139
|
+
*
|
|
140
|
+
* The order matters and only in one direction — a buffered intent is a model's
|
|
141
|
+
* answer to the question the floor would otherwise be answering, so it wins when it
|
|
142
|
+
* exists. There is no case where the floor should override a fresh proposal, because
|
|
143
|
+
* a proposal the floor should override is one the admission guards discard.
|
|
144
|
+
*/
|
|
145
|
+
private take;
|
|
146
|
+
/**
|
|
147
|
+
* Whether a buffered intent is still true of the world.
|
|
148
|
+
*
|
|
149
|
+
* Composed from the guards the *tools* declared, never from anything the model
|
|
150
|
+
* wrote. With no registry configured every intent admits: a consumer that has not
|
|
151
|
+
* described its world cannot have its plans checked against it, and pretending
|
|
152
|
+
* otherwise would be a check that always passes wearing the shape of one that means
|
|
153
|
+
* something.
|
|
154
|
+
*/
|
|
155
|
+
private admits;
|
|
156
|
+
/**
|
|
157
|
+
* Take the most important observation waiting, and act on it if it outranks now.
|
|
158
|
+
*
|
|
159
|
+
* At the tick boundary, never mid-tick. Nothing mutates the simulation halfway
|
|
160
|
+
* through a step, which is the boundary §33 of the parent design already runs.
|
|
161
|
+
*/
|
|
162
|
+
private drainObservations;
|
|
163
|
+
/**
|
|
164
|
+
* Throw away the current intent, the buffer and the request, and let the floor cover.
|
|
165
|
+
*
|
|
166
|
+
* *Cost, stated:* one in-flight request is discarded. That is the token price of
|
|
167
|
+
* responsiveness, bounded by the preemption rate, which the consumer sets through
|
|
168
|
+
* priorities — so `usage.preemptedRequests` reports it. A number nobody reports is a
|
|
169
|
+
* number nobody tunes.
|
|
170
|
+
*/
|
|
171
|
+
private preempt;
|
|
172
|
+
private askInterrupt;
|
|
173
|
+
private consumeInterrupt;
|
|
174
|
+
/**
|
|
175
|
+
* Write an admitted model intent into the command log.
|
|
176
|
+
*
|
|
177
|
+
* Only model intents. The floor is deterministic and recomputes identically on
|
|
178
|
+
* replay, so recording its decisions would store what can be derived — and a
|
|
179
|
+
* thousand-tick recording would be a thousand entries instead of a handful.
|
|
180
|
+
*/
|
|
181
|
+
private record;
|
|
182
|
+
/** True once a budget is exhausted: still moving, no longer asking. */
|
|
183
|
+
get degraded(): boolean;
|
|
184
|
+
/** The budget's own sentence, or empty while nothing is exhausted. */
|
|
185
|
+
get degradedReason(): string;
|
|
186
|
+
/** Buffered intents discarded because their guard had gone false. */
|
|
187
|
+
get discardedIntents(): number;
|
|
188
|
+
private finished;
|
|
189
|
+
/**
|
|
190
|
+
* Issue the continuation, if this is the tick to issue it on.
|
|
191
|
+
*
|
|
192
|
+
* The watermark itself is `leadMs`. This only decides whether the state machine
|
|
193
|
+
* has an edge available, which is where one-request-in-flight actually lives.
|
|
194
|
+
*/
|
|
195
|
+
private maybeContinue;
|
|
196
|
+
/** The lead the watermark uses: the provider's measured p90, or -1 before it knows. */
|
|
197
|
+
get leadMs(): number;
|
|
198
|
+
/**
|
|
199
|
+
* Charge the latency of a response, measured to the tick that observed it.
|
|
200
|
+
*
|
|
201
|
+
* A response lands in a microtask, where there is no simulation clock to read. So
|
|
202
|
+
* the landing is flagged and priced on the next `tick`, which measures the latency a
|
|
203
|
+
* fixed-step consumer *experiences* rather than the one a wall clock would report.
|
|
204
|
+
* Those differ by up to one step, and the one that matters for deciding when to ask
|
|
205
|
+
* again is this one.
|
|
206
|
+
*
|
|
207
|
+
* *What it costs:* a response landing just after a tick is charged nearly a whole
|
|
208
|
+
* step more than it took. *What would make it wrong:* a consumer stepping far more
|
|
209
|
+
* slowly than its provider answers, where a step's rounding would dominate the
|
|
210
|
+
* measurement — at which point the session needs a clock rather than a flag.
|
|
211
|
+
*/
|
|
212
|
+
private recordLanding;
|
|
213
|
+
private issue;
|
|
214
|
+
private consume;
|
|
215
|
+
private abortInFlight;
|
|
216
|
+
private transition;
|
|
217
|
+
}
|