@slopus/happy-agent-base 0.0.1 → 0.0.3
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/README.md +20 -235
- package/dist/Agent.d.ts +71 -9
- package/dist/Agent.d.ts.map +1 -1
- package/dist/Agent.js +258 -40
- package/dist/Agent.js.map +1 -1
- package/dist/AgentBase.d.ts +268 -23
- package/dist/AgentBase.d.ts.map +1 -1
- package/dist/AgentBase.js +1620 -333
- package/dist/AgentBase.js.map +1 -1
- package/dist/AgentBaseHooks.d.ts +108 -24
- package/dist/AgentBaseHooks.d.ts.map +1 -1
- package/dist/AgentBasePending.d.ts +44 -0
- package/dist/AgentBasePending.d.ts.map +1 -0
- package/dist/AgentBasePending.js +64 -0
- package/dist/AgentBasePending.js.map +1 -0
- package/dist/AgentBaseState.d.ts +2 -0
- package/dist/AgentBaseState.d.ts.map +1 -1
- package/dist/AgentConfig.d.ts +67 -0
- package/dist/AgentConfig.d.ts.map +1 -0
- package/dist/AgentConfig.js +81 -0
- package/dist/AgentConfig.js.map +1 -0
- package/dist/AgentContexts.d.ts +40 -0
- package/dist/AgentContexts.d.ts.map +1 -0
- package/dist/AgentContexts.js +70 -0
- package/dist/AgentContexts.js.map +1 -0
- package/dist/AgentFeature.d.ts +118 -15
- package/dist/AgentFeature.d.ts.map +1 -1
- package/dist/AgentKV.d.ts +58 -0
- package/dist/AgentKV.d.ts.map +1 -0
- package/dist/AgentKV.js +114 -0
- package/dist/AgentKV.js.map +1 -0
- package/dist/AgentModel.d.ts +17 -0
- package/dist/AgentModel.d.ts.map +1 -0
- package/dist/AgentModel.js +2 -0
- package/dist/AgentModel.js.map +1 -0
- package/dist/{AgentBasePersistence.d.ts → AgentPersistence.d.ts} +13 -8
- package/dist/AgentPersistence.d.ts.map +1 -0
- package/dist/AgentPersistence.js +2 -0
- package/dist/AgentPersistence.js.map +1 -0
- package/dist/AgentProviders.d.ts +22 -7
- package/dist/AgentProviders.d.ts.map +1 -1
- package/dist/AgentProviders.js +18 -9
- package/dist/AgentProviders.js.map +1 -1
- package/dist/AgentRef.d.ts +41 -0
- package/dist/AgentRef.d.ts.map +1 -0
- package/dist/AgentRef.js +60 -0
- package/dist/AgentRef.js.map +1 -0
- package/dist/AgentStorage.d.ts +39 -0
- package/dist/AgentStorage.d.ts.map +1 -0
- package/dist/AgentStorage.js +49 -0
- package/dist/AgentStorage.js.map +1 -0
- package/dist/AgentSystem.d.ts +52 -0
- package/dist/AgentSystem.d.ts.map +1 -0
- package/dist/AgentSystem.js +2 -0
- package/dist/AgentSystem.js.map +1 -0
- package/dist/AgentSystemContext.d.ts +15 -0
- package/dist/AgentSystemContext.d.ts.map +1 -0
- package/dist/AgentSystemContext.js +20 -0
- package/dist/AgentSystemContext.js.map +1 -0
- package/dist/AgentSystemLocal.d.ts +104 -0
- package/dist/AgentSystemLocal.d.ts.map +1 -0
- package/dist/AgentSystemLocal.js +401 -0
- package/dist/AgentSystemLocal.js.map +1 -0
- package/dist/AgentSystemRef.d.ts +56 -0
- package/dist/AgentSystemRef.d.ts.map +1 -0
- package/dist/AgentSystemRef.js +75 -0
- package/dist/AgentSystemRef.js.map +1 -0
- package/dist/AgentTaskContext.d.ts +17 -0
- package/dist/AgentTaskContext.d.ts.map +1 -0
- package/dist/AgentTaskContext.js +26 -0
- package/dist/AgentTaskContext.js.map +1 -0
- package/dist/AgentTool.d.ts +40 -0
- package/dist/AgentTool.d.ts.map +1 -1
- package/dist/AgentTool.js.map +1 -1
- package/dist/index.d.ts +21 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -3
- package/dist/index.js.map +1 -1
- package/dist/models.d.ts +62 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +185 -0
- package/dist/models.js.map +1 -0
- package/package.json +6 -4
- package/dist/AgentBaseContext.d.ts +0 -22
- package/dist/AgentBaseContext.d.ts.map +0 -1
- package/dist/AgentBaseContext.js +0 -33
- package/dist/AgentBaseContext.js.map +0 -1
- package/dist/AgentBasePersistence.d.ts.map +0 -1
- package/dist/AgentBasePersistence.js +0 -2
- package/dist/AgentBasePersistence.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,246 +1,31 @@
|
|
|
1
1
|
# @slopus/happy-agent-base
|
|
2
2
|
|
|
3
|
-
The minimal
|
|
3
|
+
The minimal durable runtime for Happy agents.
|
|
4
4
|
|
|
5
|
-
`AgentBase`
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
and feeds the results back. The conversation is observable only through hooks; there is no
|
|
10
|
-
external transcript or status surface.
|
|
5
|
+
`AgentBase` owns one agent's persistent inference and tool loop. It durably queues messages,
|
|
6
|
+
streams provider responses, executes tools, compacts history, resumes interrupted work, and
|
|
7
|
+
keeps inference, tool results, and settlement transactionally consistent across process
|
|
8
|
+
restarts.
|
|
11
9
|
|
|
12
|
-
|
|
10
|
+
The package also provides the primitives needed to host that runtime:
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
- `Agent`, `AgentSystem`, and `AgentSystemLocal` for composing and addressing agents;
|
|
13
|
+
- `AgentPersistence`, `AgentStorage`, and `AgentKV` for durable state;
|
|
14
|
+
- `AgentProviders` for resolving provider/model routes;
|
|
15
|
+
- `AgentTool` and lifecycle hooks for extending the loop.
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
One `AgentSystem` exclusively owns one durable store. Every `AgentStorage` adapter must acquire a
|
|
18
|
+
hard database-level lock before the system starts; `AgentSystem.close()` stops its agents and
|
|
19
|
+
releases that lock. The runtime intentionally contains no CAS or multi-owner coordination.
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
abort(): Promise<void>;
|
|
25
|
-
compact(ctx: Context): Promise<void>;
|
|
26
|
-
waitForIdle(): Promise<void>;
|
|
27
|
-
close(): Promise<void>;
|
|
28
|
-
}
|
|
21
|
+
Features may implement async `beforeStart(ctx, agents)` and `afterStart(ctx, agents)` hooks.
|
|
22
|
+
Every `beforeStart` settles successfully before active agents are restored; every `afterStart`
|
|
23
|
+
runs after those agents are restored and started. Both receive the system's `AgentSystemRef`.
|
|
29
24
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
persistence: AgentBasePersistence;
|
|
35
|
-
hooks?: AgentBaseHooks;
|
|
36
|
-
initialState?: Partial<AgentBaseState>; // copied into the agent's own state
|
|
37
|
-
model?: string;
|
|
38
|
-
effort?: SessionReasoningEffort;
|
|
39
|
-
serviceTier?: SessionServiceTier;
|
|
40
|
-
steeringMode?: "one-at-a-time" | "all"; // default "one-at-a-time"
|
|
41
|
-
sendMode?: "one-at-a-time" | "all"; // default "one-at-a-time"
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
interface AgentBaseState {
|
|
45
|
-
instructions: string;
|
|
46
|
-
tools: AnyAgentTool[];
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
interface AgentBaseHooks {
|
|
50
|
-
onEvent?: (ctx: Context, event: SessionEvent) => void;
|
|
51
|
-
instructions?: (ctx: Context) => string;
|
|
52
|
-
tools?: (ctx: Context) => readonly AnyAgentTool[];
|
|
53
|
-
modelChanged?: (ctx: Context, change: AgentBaseModelChange) => SessionSystemMessage | undefined;
|
|
54
|
-
beforeAgentLoop?: (ctx: Context) => void;
|
|
55
|
-
beforeTurn?: (ctx: Context) => void;
|
|
56
|
-
beforeInference?: (ctx: Context) => void;
|
|
57
|
-
afterInference?: (ctx: Context) => void;
|
|
58
|
-
afterTurn?: (ctx: Context) => readonly AgentFeatureAction[] | undefined;
|
|
59
|
-
afterAgentLoop?: (ctx: Context) => readonly AgentFeatureAction[] | undefined;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
interface AgentBaseModelChange {
|
|
63
|
-
previousModel: string | undefined;
|
|
64
|
-
model: string;
|
|
65
|
-
previousProvider: string;
|
|
66
|
-
provider: string;
|
|
67
|
-
providers: AgentProviders;
|
|
68
|
-
previousProviderInstance: BaseProvider | null;
|
|
69
|
-
providerInstance: BaseProvider | null;
|
|
70
|
-
wasReset: boolean; // the change was incompatible and the history was erased
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
interface AgentBaseMessageOptions {
|
|
74
|
-
provider?: string; // registry ID to switch to
|
|
75
|
-
model?: string;
|
|
76
|
-
effort?: SessionReasoningEffort;
|
|
77
|
-
serviceTier?: SessionServiceTier;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
type AgentFeatureAction =
|
|
81
|
-
| { type: "steer"; message: SessionUserMessage }
|
|
82
|
-
| { type: "send"; message: SessionUserMessage }
|
|
83
|
-
| { type: "compact" };
|
|
84
|
-
|
|
85
|
-
interface AgentTool<Args extends TSchema = TSchema, Result extends TSchema = TSchema> {
|
|
86
|
-
// The provider-facing descriptor fields of SessionTool, with parameters typed as Args, plus:
|
|
87
|
-
durable?: boolean;
|
|
88
|
-
returnType: Result;
|
|
89
|
-
execute(ctx: Context, args: Static<Args>): Promise<Static<Result>>;
|
|
90
|
-
toLLM(result: Static<Result>): readonly SessionOutputBlock[];
|
|
91
|
-
isError?(result: Static<Result>): boolean;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function defineAgentTool<const Args extends TSchema, const Result extends TSchema>(
|
|
95
|
-
tool: AgentTool<Args, Result>,
|
|
96
|
-
): AgentTool<Args, Result>;
|
|
97
|
-
|
|
98
|
-
interface AgentBasePersistence {
|
|
99
|
-
transaction<Result>(ctx: Context, work: (ctx: Context) => Promise<Result>): Promise<Result>;
|
|
100
|
-
load(ctx: Context): Promise<readonly AgentBaseRecord[]>;
|
|
101
|
-
append(ctx: Context, record: AgentBaseRecord): Promise<void>;
|
|
102
|
-
clearRecords(ctx: Context): Promise<void>; // physical delete, used inside the compaction transaction
|
|
103
|
-
readValues(ctx: Context, prefix: string): Promise<readonly { key: string; value: unknown }[]>;
|
|
104
|
-
writeValue(ctx: Context, key: string, value: unknown): Promise<void>;
|
|
105
|
-
deleteValue(ctx: Context, key: string): Promise<void>;
|
|
106
|
-
}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
Persistence is an append-only main context store plus a sorted key-value store alongside it. The
|
|
110
|
-
agent serializes every operation through one internal lock (configured to crash on re-entry), so
|
|
111
|
-
implementations never see concurrent calls and need no locking of their own.
|
|
112
|
-
|
|
113
|
-
A queued message is written under a `steering.` or `send.` key ordered by append time;
|
|
114
|
-
nothing that is not yet part of the context reaches the main store. When a queue drains, each
|
|
115
|
-
consumed message is appended as a user record and its queue key deleted, all inside one
|
|
116
|
-
`transaction` so a crash or failure can never leave a message in both stores or neither, and
|
|
117
|
-
only then does inference run on the resulting context. Transactions are completely transparent
|
|
118
|
-
to the agent: the implementation opens one, hands work a derived context its own operations
|
|
119
|
-
recognize, and carries the transaction on that context however it likes; work resolving
|
|
120
|
-
commits, a thrown error rolls back. Assistant output is appended one finished block at a time as
|
|
121
|
-
it streams, so main-store records always arrive in context order and consecutive block records
|
|
122
|
-
reassemble into one assistant message on load. The agent loop loads everything once, on the first
|
|
123
|
-
inference attempt; the load result replaces the in-memory state, including leftover queued
|
|
124
|
-
messages from an earlier process, which join the next turn. A failed load is reported as an
|
|
125
|
-
`internal_error` done event and is not sticky: the next requested turn retries it, with every
|
|
126
|
-
queued message still safely waiting.
|
|
127
|
-
|
|
128
|
-
The two queues give four delivery strategies, mirroring Pi:
|
|
129
|
-
|
|
130
|
-
| Strategy | Behavior |
|
|
131
|
-
|---|---|
|
|
132
|
-
| Steering + one-at-a-time | `steer` queues FIFO. After the current assistant response and all its tool calls finish, the oldest message injects, gets a response, then the next is handled. |
|
|
133
|
-
| Steering + all | After the current response and tool batch finish, every queued steering message injects together before one response. |
|
|
134
|
-
| Send + one-at-a-time | `send` waits until the agent would otherwise stop — no tool calls or steering remain — then injects one message and waits for its response before draining another. |
|
|
135
|
-
| Send + all | Once the agent would otherwise stop, every queued sent message injects together before one response. |
|
|
136
|
-
|
|
137
|
-
Both modes default to `"one-at-a-time"`, and steering always takes precedence over sent messages.
|
|
138
|
-
Queue consumption happens only between inferences — never mid-stream and never during a tool
|
|
139
|
-
batch — so an injected message can never interleave with an active response's block records.
|
|
140
|
-
|
|
141
|
-
`steer` and `send` resolve once the durable queue write lands, so a failed write keeps the
|
|
142
|
-
message out of the conversation; they wait neither for the history load nor for the turn. Each
|
|
143
|
-
message may carry its own inference settings — provider, model, effort, and service tier —
|
|
144
|
-
which take effect when the message is consumed and stay effective for every later message that does not
|
|
145
|
-
override them, surviving restarts through a durable settings entry. A message without settings
|
|
146
|
-
uses the previously effective values, or the constructor defaults when nothing was ever carried;
|
|
147
|
-
relying on those defaults is discouraged — prefer sending settings with the message.
|
|
148
|
-
|
|
149
|
-
A provider or model change is checked against the provider-model compatibility matrix from
|
|
150
|
-
`@slopus/happy-providers`, using the compatibility types the providers were registered with. A
|
|
151
|
-
compatible change keeps the conversation; a compatible provider change still gets a fresh
|
|
152
|
-
session on the new provider, since a session is bound to the provider that created it. An
|
|
153
|
-
incompatible change — including a switch to a different provider of the same type, or to an
|
|
154
|
-
unregistered ID — resets the conversation: the durable history is erased completely, the old
|
|
155
|
-
provider session is destroyed, and a fresh session serves the new selection. The `modelChanged`
|
|
156
|
-
hook fires on every selection change with the old and new model, both provider IDs and live
|
|
157
|
-
instances, the registry, and the `wasReset` flag; on a reset the handoff system message it
|
|
158
|
-
returns is injected at the very beginning of the fresh context — without one the context starts
|
|
159
|
-
completely empty. The consumed message that carried the new selection follows the handoff. A
|
|
160
|
-
thrown provider or load failure is reported to the `onEvent` hook as an `internal_error` done
|
|
161
|
-
event instead of rejecting the loop. The agent never retries inference itself — providers own
|
|
162
|
-
retry semantics and surface them as `retrying` events. A provider-reported error response ends
|
|
163
|
-
that response but not the turn: messages still queued drain into a fresh inference, each drain
|
|
164
|
-
consuming from a finite queue, so a persistently failing provider cannot loop.
|
|
165
|
-
|
|
166
|
-
A turn that ends failed surfaces its error to the context as a durable system message
|
|
167
|
-
(`The last turn failed: <message>`), so the next inference sees what went wrong. Only
|
|
168
|
-
unrecovered failures leave this trace: a provider-reported error followed by a successful
|
|
169
|
-
response in the same turn recovers silently, and a failed history load appends nothing since
|
|
170
|
-
there is no loaded context to append to.
|
|
171
|
-
|
|
172
|
-
When a turn stops for tool calls, every call in the batch runs in parallel. Arguments are
|
|
173
|
-
validated against the tool's TypeBox `parameters` schema before `execute` runs, so `execute`
|
|
174
|
-
receives them as `Static<Args>` rather than unknown. `execute` returns a structured result that
|
|
175
|
-
is validated against `returnType` and then rendered into output blocks for the model with
|
|
176
|
-
`toLLM`; an optional `isError` predicate marks a structured result as an error. A missing tool,
|
|
177
|
-
invalid JSON arguments, arguments that fail the schema, an incomplete call, a thrown `execute`,
|
|
178
|
-
or a result that fails `returnType` becomes an error tool result
|
|
179
|
-
(`isError: true`) for the model instead of failing the run; provider-settled server calls are
|
|
180
|
-
never executed by the agent, and their streamed `toolcall_result_*` events are simply ignored —
|
|
181
|
-
the server call block stays in the history, the events reach the hooks, and no tool result
|
|
182
|
-
message is stored or owed.
|
|
183
|
-
|
|
184
|
-
Before any call in a batch executes, the whole batch is committed to the sorted store under
|
|
185
|
-
`tool.` keys ordered by position, so a crash mid-batch leaves a durable record of the calls still
|
|
186
|
-
owed a result. Calls run in parallel, but results land strictly in call order: a finished result
|
|
187
|
-
waits until every earlier call in the batch has committed, and each commit appends the `tool`
|
|
188
|
-
record and deletes the pending entry in one transaction. Once the batch is complete the loop runs
|
|
189
|
-
inference again with the full context.
|
|
190
|
-
|
|
191
|
-
`start` begins the loop without a new message: it loads the durable state and continues a turn
|
|
192
|
-
that was cut off by a crash — leftover queued messages are consumed, a dispatched `tool.`
|
|
193
|
-
batch is settled, and an unanswered user or tool message gets its inference. When an interrupted
|
|
194
|
-
batch resumes, only tools marked `durable: true` execute again; every other interrupted call
|
|
195
|
-
becomes an error tool result, since the agent cannot know whether its side effects already
|
|
196
|
-
happened. On an idle history `start` loads and does nothing more.
|
|
197
|
-
|
|
198
|
-
`compact` compacts the conversation through the provider session. It waits for the active turn
|
|
199
|
-
to end — including queued messages already draining — or runs right away when idle, snapshots
|
|
200
|
-
the history, and asks the provider to compact it. The completed replacement context supersedes
|
|
201
|
-
the compacted history while any message that joined after the snapshot is kept. In one atomic
|
|
202
|
-
transaction the superseded records are physically deleted and the replacement — the messages
|
|
203
|
-
that stay — is appended as a `compaction` record, which then opens the store while later
|
|
204
|
-
records append as usual. Calls made while a compaction is pending or running
|
|
205
|
-
await that same shared compaction; it resolves on completion and rejects when the provider
|
|
206
|
-
reports failure, leaving the history untouched.
|
|
207
|
-
|
|
208
|
-
Hooks receive the agent's context first. That context — shared by tool executions — is derived
|
|
209
|
-
once at construction and carries the agent's provider registry ID, model, effort, and
|
|
210
|
-
service tier — all serializable values — readable through the exported `agentBaseProvider`,
|
|
211
|
-
`agentBaseModel`, `agentBaseEffort`, and `agentBaseServiceTier` accessors. The
|
|
212
|
-
`instructions` and `tools` hooks, when provided, answer for the session: they are consulted for
|
|
213
|
-
session creation, every inference request, compaction, and tool lookup, superseding
|
|
214
|
-
`state.instructions` and `state.tools`. A hook that throws falls back to the state and never
|
|
215
|
-
fails the run.
|
|
216
|
-
|
|
217
|
-
The lifecycle hooks bracket the loop's own structure. `beforeAgentLoop` fires when the loop
|
|
218
|
-
leaves the settled state and begins working, and `afterAgentLoop` fires when it would settle
|
|
219
|
-
back to idle; between them, each turn is bracketed by `beforeTurn` and `afterTurn`, and each
|
|
220
|
-
inference request inside a turn by `beforeInference` and `afterInference`. `afterTurn` and
|
|
221
|
-
`afterAgentLoop` may return an array of `AgentFeatureAction`s, all applied together before the
|
|
222
|
-
loop continues: `steer` and `send` queue a message through the ordinary durable queues exactly
|
|
223
|
-
as the public methods do, and `compact` triggers the shared compaction. Actions from `afterTurn`
|
|
224
|
-
drive the loop into another turn within the same loop span; actions from `afterAgentLoop` reopen
|
|
225
|
-
the loop instead of settling. Like every hook, a thrown lifecycle hook — or a failing action —
|
|
226
|
-
never fails the run.
|
|
227
|
-
|
|
228
|
-
`abort` cancels the active turn and resolves once the loop has stopped; when idle it is a no-op.
|
|
229
|
-
The inference stream is abandoned and asked to close, a `done` event with state `cancelled` is
|
|
230
|
-
emitted, blocks that already finished stay in the history while an unfinished block is dropped
|
|
231
|
-
everywhere, and each still-running tool call settles as an error tool result saying it was
|
|
232
|
-
aborted — consuming its pending `tool.` entry so the batch leaves a complete context behind.
|
|
233
|
-
The queued turn request is dropped too, but messages still waiting in the steering and
|
|
234
|
-
send queues stay durable and join the next requested turn.
|
|
235
|
-
|
|
236
|
-
`AgentProviders` is a mutable registry of provider instances keyed by caller-supplied IDs, so the
|
|
237
|
-
same provider class can be registered under several IDs. `add(id, provider, type)` registers an
|
|
238
|
-
instance together with its compatibility type (`"claude"`, `"codex"`, `"grok"`, `"bedrock"`, or
|
|
239
|
-
`"gym"`), `get(id)` returns the provider or null, and `typeOf(id)` returns the registered type
|
|
240
|
-
or null. The agent is configured entirely with serializable values — a
|
|
241
|
-
provider registry ID, a model name, an effort level, and a service tier — and resolves the live provider from
|
|
242
|
-
the registry when the session is first created; an ID that is not registered at that moment
|
|
243
|
-
fails the turn like any thrown error.
|
|
25
|
+
This package contains no ready-made product features. Reusable tools, hooks, permissions,
|
|
26
|
+
workspaces, search, workflows, and other capabilities belong in
|
|
27
|
+
[`@slopus/happy-agent-features`](../happy-agent-features). Provider protocols and vendor
|
|
28
|
+
implementations belong in [`@slopus/happy-providers`](../happy-providers).
|
|
244
29
|
|
|
245
30
|
## Validation
|
|
246
31
|
|
package/dist/Agent.d.ts
CHANGED
|
@@ -1,31 +1,93 @@
|
|
|
1
1
|
import type { SessionUserMessage } from "@slopus/happy-providers";
|
|
2
2
|
import type { Context } from "@steve.kite/stdlib";
|
|
3
|
-
import { type AgentBaseMessageOptions, type AgentBaseOptions } from "./AgentBase.js";
|
|
3
|
+
import { type AgentBaseAwaitOptions, type AgentBaseMessageOptions, type AgentBaseOptions } from "./AgentBase.js";
|
|
4
4
|
import type { AgentBaseState } from "./AgentBaseState.js";
|
|
5
5
|
import type { AgentFeature } from "./AgentFeature.js";
|
|
6
|
+
import type { AgentKV } from "./AgentKV.js";
|
|
6
7
|
import type { AnyAgentTool } from "./AgentTool.js";
|
|
8
|
+
/**
|
|
9
|
+
* Everything `AgentBase` is constructed with, except its hooks: an agent's behavior comes from
|
|
10
|
+
* its features, and the singular hooks the base runs with are merged from them.
|
|
11
|
+
*/
|
|
7
12
|
export interface AgentOptions<Tool extends AnyAgentTool = AnyAgentTool> extends Omit<AgentBaseOptions, "hooks"> {
|
|
8
13
|
/** Independent capabilities whose hook implementations are merged, in array order. */
|
|
9
14
|
readonly features?: readonly AgentFeature<Tool>[];
|
|
15
|
+
/**
|
|
16
|
+
* The store features share with every other agent built over the same storage. Each feature
|
|
17
|
+
* is handed its own scope of it, which is where anything outliving one conversation belongs.
|
|
18
|
+
*/
|
|
19
|
+
readonly sharedKV: AgentKV;
|
|
10
20
|
}
|
|
11
21
|
/**
|
|
12
22
|
* A thin wrapper around `AgentBase` that assembles its behavior from features. Each feature
|
|
13
23
|
* implements any subset of the agent hooks on its own; the agent merges them into the singular
|
|
14
|
-
* private hooks its internal base runs with.
|
|
15
|
-
*
|
|
16
|
-
*
|
|
24
|
+
* private hooks its internal base runs with.
|
|
25
|
+
*
|
|
26
|
+
* Features are independent. Observing hooks — events and lifecycle brackets — fan out to every
|
|
27
|
+
* feature in array order with per-feature isolation, so one throwing feature never silences the
|
|
28
|
+
* others, and lifecycle actions concatenate across features with a failing feature losing only
|
|
29
|
+
* its own actions. Correctness hooks are loud instead: instructions and tools concatenate in
|
|
30
|
+
* feature order — extending the base state, which `AgentBase` puts first — and a failure there
|
|
31
|
+
* fails the turn rather than running with a wrong configuration. For a model change, every
|
|
32
|
+
* feature observes the change, the first returned handoff wins, and a feature failure during an
|
|
33
|
+
* incompatible change rejects the switch so the history survives.
|
|
17
34
|
*/
|
|
18
35
|
export declare class Agent<Tool extends AnyAgentTool = AnyAgentTool> {
|
|
19
36
|
#private;
|
|
20
|
-
|
|
37
|
+
/**
|
|
38
|
+
* A new agent over a fresh identity, with its features' hooks merged into one set. Touches
|
|
39
|
+
* no storage.
|
|
40
|
+
*/
|
|
41
|
+
static create<Tool extends AnyAgentTool = AnyAgentTool>(ctx: Context, options: AgentOptions<Tool>): Promise<Agent<Tool>>;
|
|
42
|
+
/**
|
|
43
|
+
* An agent over an identity that may already have durable state, with that state's one
|
|
44
|
+
* externally meaningful fact — whether it has work left — read before it is handed back.
|
|
45
|
+
*/
|
|
46
|
+
static load<Tool extends AnyAgentTool = AnyAgentTool>(ctx: Context, options: AgentOptions<Tool>): Promise<Agent<Tool>>;
|
|
47
|
+
/**
|
|
48
|
+
* Load the agent and set it going again if it has work left, or answer with nothing when it
|
|
49
|
+
* has none — how an owner coming up carries on what an earlier process was in the middle of.
|
|
50
|
+
*/
|
|
51
|
+
static loadActive<Tool extends AnyAgentTool = AnyAgentTool>(ctx: Context, options: AgentOptions<Tool>): Promise<Agent<Tool> | undefined>;
|
|
52
|
+
/**
|
|
53
|
+
* Wrap an already-built base. Private, because an agent is made by `create` or by `load`,
|
|
54
|
+
* and which of the two the caller means is worth saying.
|
|
55
|
+
*/
|
|
56
|
+
private constructor();
|
|
57
|
+
/** The stable session identity this agent was created with. */
|
|
21
58
|
get id(): string;
|
|
59
|
+
/** Whether durable state says this agent still has work to resume. */
|
|
60
|
+
get active(): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* The feature this agent runs under `name`, when it has one. An individual feature holds the
|
|
63
|
+
* state of the single agent it was built for, so this is how that agent's owner reaches what
|
|
64
|
+
* belongs to it — a goal to pause, for instance. A shared feature is answered here too, but
|
|
65
|
+
* it is the collection's instance, serving every agent at once.
|
|
66
|
+
*/
|
|
67
|
+
feature(name: string): AgentFeature<Tool> | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* The base's mutable instructions and tools, which every inference reads and every feature's
|
|
70
|
+
* own contribution extends.
|
|
71
|
+
*/
|
|
22
72
|
get state(): AgentBaseState;
|
|
23
|
-
|
|
24
|
-
|
|
73
|
+
/** Queue a user message that injects as soon as the current response and tool batch finish. */
|
|
74
|
+
steer(ctx: Context, message: SessionUserMessage, options?: AgentBaseMessageOptions & AgentBaseAwaitOptions): Promise<void>;
|
|
75
|
+
/** Queue a user message that injects only when the agent would otherwise stop. */
|
|
76
|
+
send(ctx: Context, message: SessionUserMessage, options?: AgentBaseMessageOptions & AgentBaseAwaitOptions): Promise<void>;
|
|
77
|
+
/** Start the loop without a new message, continuing a turn an earlier run left unfinished. */
|
|
25
78
|
start(): void;
|
|
79
|
+
/** Wait until the agent has nothing left to do, including work it accepted but never began. */
|
|
26
80
|
waitForIdle(): Promise<void>;
|
|
27
|
-
|
|
28
|
-
|
|
81
|
+
/** Ask for the conversation to be replaced by the provider's summary of it. */
|
|
82
|
+
compact(ctx: Context, options?: AgentBaseAwaitOptions): Promise<void>;
|
|
83
|
+
/** Cancel the active turn, leaving queued messages durable for the next one. */
|
|
84
|
+
abort(ctx: Context, options?: AgentBaseAwaitOptions): Promise<void>;
|
|
85
|
+
/** Finish everything already accepted, then destroy the provider session. */
|
|
29
86
|
close(): Promise<void>;
|
|
87
|
+
/**
|
|
88
|
+
* Wait for a close that has already been requested to finish, including when its original
|
|
89
|
+
* caller was inside the agent and could not wait for its own turn.
|
|
90
|
+
*/
|
|
91
|
+
waitForClosed(): Promise<void>;
|
|
30
92
|
}
|
|
31
93
|
//# sourceMappingURL=Agent.d.ts.map
|
package/dist/Agent.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Agent.d.ts","sourceRoot":"","sources":["../sources/Agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAwB,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACxF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,
|
|
1
|
+
{"version":3,"file":"Agent.d.ts","sourceRoot":"","sources":["../sources/Agent.ts"],"names":[],"mappings":"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"}
|