@slopus/happy-agent-base 0.0.0 → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +241 -16
- package/dist/Agent.d.ts +31 -0
- package/dist/Agent.d.ts.map +1 -0
- package/dist/Agent.js +119 -0
- package/dist/Agent.js.map +1 -0
- package/dist/AgentBase.d.ts +93 -0
- package/dist/AgentBase.d.ts.map +1 -0
- package/dist/AgentBase.js +909 -0
- package/dist/AgentBase.js.map +1 -0
- package/dist/AgentBaseContext.d.ts +22 -0
- package/dist/AgentBaseContext.d.ts.map +1 -0
- package/dist/AgentBaseContext.js +33 -0
- package/dist/AgentBaseContext.js.map +1 -0
- package/dist/AgentBaseHooks.d.ts +68 -0
- package/dist/AgentBaseHooks.d.ts.map +1 -0
- package/dist/AgentBaseHooks.js +2 -0
- package/dist/AgentBaseHooks.js.map +1 -0
- package/dist/AgentBasePersistence.d.ts +60 -0
- package/dist/AgentBasePersistence.d.ts.map +1 -0
- package/dist/AgentBasePersistence.js +2 -0
- package/dist/AgentBasePersistence.js.map +1 -0
- package/dist/AgentBaseState.d.ts +11 -0
- package/dist/AgentBaseState.d.ts.map +1 -0
- package/dist/AgentBaseState.js +2 -0
- package/dist/AgentBaseState.js.map +1 -0
- package/dist/AgentFeature.d.ts +29 -0
- package/dist/AgentFeature.d.ts.map +1 -0
- package/dist/AgentFeature.js +2 -0
- package/dist/AgentFeature.js.map +1 -0
- package/dist/AgentFeatureAction.d.ts +16 -0
- package/dist/AgentFeatureAction.d.ts.map +1 -0
- package/dist/AgentFeatureAction.js +2 -0
- package/dist/AgentFeatureAction.js.map +1 -0
- package/dist/AgentProviders.d.ts +17 -0
- package/dist/AgentProviders.d.ts.map +1 -0
- package/dist/AgentProviders.js +29 -0
- package/dist/AgentProviders.js.map +1 -0
- package/dist/AgentTool.d.ts +47 -0
- package/dist/AgentTool.d.ts.map +1 -0
- package/dist/AgentTool.js +5 -0
- package/dist/AgentTool.js.map +1 -0
- package/dist/index.d.ts +10 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/package.json +42 -37
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 rig Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,26 +1,251 @@
|
|
|
1
1
|
# @slopus/happy-agent-base
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The minimal core of a Happy coding agent.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
`AgentBase` is one agent session over one `@slopus/happy-providers` provider. Messages arrive
|
|
6
|
+
through two FIFO queues — steering and send — the loop replays the full conversation to the
|
|
7
|
+
provider session, and the streamed events are forwarded to the optional hooks while the
|
|
8
|
+
assistant reply joins the history. When the model stops for tool calls, the agent executes them
|
|
9
|
+
and feeds the results back. The conversation is observable only through hooks; there is no
|
|
10
|
+
external transcript or status surface.
|
|
7
11
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
## Core API
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
class AgentBase {
|
|
16
|
+
constructor(ctx: Context, options: AgentBaseOptions);
|
|
17
|
+
|
|
18
|
+
readonly id: string;
|
|
19
|
+
readonly state: AgentBaseState; // the agent's own copy, mutable directly
|
|
20
|
+
|
|
21
|
+
steer(ctx: Context, message: SessionUserMessage, options?: AgentBaseMessageOptions): Promise<void>;
|
|
22
|
+
send(ctx: Context, message: SessionUserMessage, options?: AgentBaseMessageOptions): Promise<void>;
|
|
23
|
+
start(): void;
|
|
24
|
+
abort(): Promise<void>;
|
|
25
|
+
compact(ctx: Context): Promise<void>;
|
|
26
|
+
waitForIdle(): Promise<void>;
|
|
27
|
+
close(): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface AgentBaseOptions {
|
|
31
|
+
id: string;
|
|
32
|
+
providers: AgentProviders;
|
|
33
|
+
provider: string; // registry ID; serializable alongside model and effort
|
|
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
|
+
}
|
|
13
107
|
```
|
|
14
108
|
|
|
15
|
-
|
|
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:
|
|
16
129
|
|
|
17
|
-
|
|
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.
|
|
244
|
+
|
|
245
|
+
## Validation
|
|
18
246
|
|
|
19
247
|
```sh
|
|
20
|
-
pnpm
|
|
248
|
+
pnpm --filter @slopus/happy-agent-base check
|
|
249
|
+
pnpm --filter @slopus/happy-agent-base test
|
|
250
|
+
pnpm --filter @slopus/happy-agent-base build
|
|
21
251
|
```
|
|
22
|
-
|
|
23
|
-
The local release validates, tests, and builds only `@slopus/happy-agent-base`, then creates and
|
|
24
|
-
pushes a `happy-agent-base-vX.Y.Z` tag. The shared GitHub publish workflow again validates, tests,
|
|
25
|
-
and builds only this package before publishing it through npm trusted publishing. The npm trusted
|
|
26
|
-
publisher must identify `slopus/rig`, `publish.yml`, and the `npm` GitHub environment.
|
package/dist/Agent.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { SessionUserMessage } from "@slopus/happy-providers";
|
|
2
|
+
import type { Context } from "@steve.kite/stdlib";
|
|
3
|
+
import { type AgentBaseMessageOptions, type AgentBaseOptions } from "./AgentBase.js";
|
|
4
|
+
import type { AgentBaseState } from "./AgentBaseState.js";
|
|
5
|
+
import type { AgentFeature } from "./AgentFeature.js";
|
|
6
|
+
import type { AnyAgentTool } from "./AgentTool.js";
|
|
7
|
+
export interface AgentOptions<Tool extends AnyAgentTool = AnyAgentTool> extends Omit<AgentBaseOptions, "hooks"> {
|
|
8
|
+
/** Independent capabilities whose hook implementations are merged, in array order. */
|
|
9
|
+
readonly features?: readonly AgentFeature<Tool>[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A thin wrapper around `AgentBase` that assembles its behavior from features. Each feature
|
|
13
|
+
* 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. Observing hooks fan out to every feature in array
|
|
15
|
+
* order, instructions concatenate, tools concatenate, lifecycle actions concatenate, and the
|
|
16
|
+
* first feature to answer a reset injection wins.
|
|
17
|
+
*/
|
|
18
|
+
export declare class Agent<Tool extends AnyAgentTool = AnyAgentTool> {
|
|
19
|
+
#private;
|
|
20
|
+
constructor(ctx: Context, options: AgentOptions<Tool>);
|
|
21
|
+
get id(): string;
|
|
22
|
+
get state(): AgentBaseState;
|
|
23
|
+
steer(ctx: Context, message: SessionUserMessage, options?: AgentBaseMessageOptions): Promise<void>;
|
|
24
|
+
send(ctx: Context, message: SessionUserMessage, options?: AgentBaseMessageOptions): Promise<void>;
|
|
25
|
+
start(): void;
|
|
26
|
+
waitForIdle(): Promise<void>;
|
|
27
|
+
compact(ctx: Context): Promise<void>;
|
|
28
|
+
abort(): Promise<void>;
|
|
29
|
+
close(): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=Agent.d.ts.map
|
|
@@ -0,0 +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,EAAa,KAAK,uBAAuB,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEhG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,WAAW,YAAY,CAAC,IAAI,SAAS,YAAY,GAAG,YAAY,CAClE,SAAQ,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACvC,sFAAsF;IACtF,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;CACrD;AAED;;;;;;GAMG;AACH,qBAAa,KAAK,CAAC,IAAI,SAAS,YAAY,GAAG,YAAY;;IAGvD,YAAY,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,EAMpD;IAED,IAAI,EAAE,IAAI,MAAM,CAEf;IAED,IAAI,KAAK,IAAI,cAAc,CAE1B;IAEK,KAAK,CACP,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,kBAAkB,EAC3B,OAAO,CAAC,EAAE,uBAAuB,GAClC,OAAO,CAAC,IAAI,CAAC,CAEf;IAEK,IAAI,CACN,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,kBAAkB,EAC3B,OAAO,CAAC,EAAE,uBAAuB,GAClC,OAAO,CAAC,IAAI,CAAC,CAEf;IAED,KAAK,IAAI,IAAI,CAEZ;IAEK,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAEjC;IAEK,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAEzC;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3B;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3B;CACJ"}
|
package/dist/Agent.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { AgentBase } from "./AgentBase.js";
|
|
2
|
+
/**
|
|
3
|
+
* A thin wrapper around `AgentBase` that assembles its behavior from features. Each feature
|
|
4
|
+
* implements any subset of the agent hooks on its own; the agent merges them into the singular
|
|
5
|
+
* private hooks its internal base runs with. Observing hooks fan out to every feature in array
|
|
6
|
+
* order, instructions concatenate, tools concatenate, lifecycle actions concatenate, and the
|
|
7
|
+
* first feature to answer a reset injection wins.
|
|
8
|
+
*/
|
|
9
|
+
export class Agent {
|
|
10
|
+
#base;
|
|
11
|
+
constructor(ctx, options) {
|
|
12
|
+
const { features, ...base } = options;
|
|
13
|
+
this.#base = new AgentBase(ctx, {
|
|
14
|
+
...base,
|
|
15
|
+
hooks: mergeFeatures(features ?? []),
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
get id() {
|
|
19
|
+
return this.#base.id;
|
|
20
|
+
}
|
|
21
|
+
get state() {
|
|
22
|
+
return this.#base.state;
|
|
23
|
+
}
|
|
24
|
+
async steer(ctx, message, options) {
|
|
25
|
+
await this.#base.steer(ctx, message, options);
|
|
26
|
+
}
|
|
27
|
+
async send(ctx, message, options) {
|
|
28
|
+
await this.#base.send(ctx, message, options);
|
|
29
|
+
}
|
|
30
|
+
start() {
|
|
31
|
+
this.#base.start();
|
|
32
|
+
}
|
|
33
|
+
async waitForIdle() {
|
|
34
|
+
await this.#base.waitForIdle();
|
|
35
|
+
}
|
|
36
|
+
async compact(ctx) {
|
|
37
|
+
await this.#base.compact(ctx);
|
|
38
|
+
}
|
|
39
|
+
async abort() {
|
|
40
|
+
await this.#base.abort();
|
|
41
|
+
}
|
|
42
|
+
async close() {
|
|
43
|
+
await this.#base.close();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Merge every feature's hook implementations into one `AgentBaseHooks`. A hook is provided only
|
|
48
|
+
* when at least one feature implements it, so the base's own fallbacks — such as the mutable
|
|
49
|
+
* state for instructions and tools — stay in effect otherwise.
|
|
50
|
+
*/
|
|
51
|
+
function mergeFeatures(features) {
|
|
52
|
+
const withInstructions = features.filter((feature) => feature.instructions !== undefined);
|
|
53
|
+
const withTools = features.filter((feature) => feature.tools !== undefined);
|
|
54
|
+
const withModelChanged = features.filter((feature) => feature.modelChanged !== undefined);
|
|
55
|
+
const fanOut = (pick) => {
|
|
56
|
+
const implemented = features.filter((feature) => pick(feature) !== undefined);
|
|
57
|
+
if (implemented.length === 0)
|
|
58
|
+
return undefined;
|
|
59
|
+
return (ctx) => {
|
|
60
|
+
for (const feature of implemented)
|
|
61
|
+
pick(feature)?.(ctx);
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
const collect = (pick) => {
|
|
65
|
+
const implemented = features.filter((feature) => pick(feature) !== undefined);
|
|
66
|
+
if (implemented.length === 0)
|
|
67
|
+
return undefined;
|
|
68
|
+
return (ctx) => implemented.flatMap((feature) => pick(feature)?.(ctx) ?? []);
|
|
69
|
+
};
|
|
70
|
+
const onEvent = fanOutEvent(features);
|
|
71
|
+
return {
|
|
72
|
+
...(onEvent === undefined ? {} : { onEvent }),
|
|
73
|
+
...(withInstructions.length === 0
|
|
74
|
+
? {}
|
|
75
|
+
: {
|
|
76
|
+
instructions: (ctx) => withInstructions
|
|
77
|
+
.map((feature) => feature.instructions?.(ctx) ?? "")
|
|
78
|
+
.filter((text) => text.length > 0)
|
|
79
|
+
.join("\n\n"),
|
|
80
|
+
}),
|
|
81
|
+
...(withTools.length === 0
|
|
82
|
+
? {}
|
|
83
|
+
: {
|
|
84
|
+
tools: (ctx) => withTools.flatMap((feature) => [...(feature.tools?.(ctx) ?? [])]),
|
|
85
|
+
}),
|
|
86
|
+
...(withModelChanged.length === 0
|
|
87
|
+
? {}
|
|
88
|
+
: {
|
|
89
|
+
modelChanged: (ctx, change) => {
|
|
90
|
+
let injected;
|
|
91
|
+
// Every feature observes the change; the first returned message wins.
|
|
92
|
+
for (const feature of withModelChanged) {
|
|
93
|
+
const message = feature.modelChanged?.(ctx, change);
|
|
94
|
+
injected ??= message;
|
|
95
|
+
}
|
|
96
|
+
return injected;
|
|
97
|
+
},
|
|
98
|
+
}),
|
|
99
|
+
...spread("beforeAgentLoop", fanOut((feature) => feature.beforeAgentLoop)),
|
|
100
|
+
...spread("beforeTurn", fanOut((feature) => feature.beforeTurn)),
|
|
101
|
+
...spread("beforeInference", fanOut((feature) => feature.beforeInference)),
|
|
102
|
+
...spread("afterInference", fanOut((feature) => feature.afterInference)),
|
|
103
|
+
...spread("afterTurn", collect((feature) => feature.afterTurn)),
|
|
104
|
+
...spread("afterAgentLoop", collect((feature) => feature.afterAgentLoop)),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function fanOutEvent(features) {
|
|
108
|
+
const implemented = features.filter((feature) => feature.onEvent !== undefined);
|
|
109
|
+
if (implemented.length === 0)
|
|
110
|
+
return undefined;
|
|
111
|
+
return (ctx, event) => {
|
|
112
|
+
for (const feature of implemented)
|
|
113
|
+
feature.onEvent?.(ctx, event);
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function spread(key, value) {
|
|
117
|
+
return value === undefined ? {} : { [key]: value };
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=Agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Agent.js","sourceRoot":"","sources":["../sources/Agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { SessionReasoningEffort, SessionServiceTier, SessionUserMessage } from "@slopus/happy-providers";
|
|
2
|
+
import { type Context } from "@steve.kite/stdlib";
|
|
3
|
+
import type { AgentBaseHooks } from "./AgentBaseHooks.js";
|
|
4
|
+
import type { AgentBasePersistence } from "./AgentBasePersistence.js";
|
|
5
|
+
import type { AgentBaseState } from "./AgentBaseState.js";
|
|
6
|
+
import { AgentProviders } from "./AgentProviders.js";
|
|
7
|
+
/** How a message queue drains: one message per model response, or every queued message at once. */
|
|
8
|
+
export type AgentBaseQueueMode = "one-at-a-time" | "all";
|
|
9
|
+
/**
|
|
10
|
+
* Inference settings carried by a queued message. An omitted field keeps the previously
|
|
11
|
+
* effective value; the first message without a value falls back to the constructor default,
|
|
12
|
+
* though relying on that default is discouraged — prefer sending settings with the message.
|
|
13
|
+
*/
|
|
14
|
+
export interface AgentBaseMessageOptions {
|
|
15
|
+
/** The registry ID of the provider to switch to. */
|
|
16
|
+
readonly provider?: string;
|
|
17
|
+
readonly model?: string;
|
|
18
|
+
readonly effort?: SessionReasoningEffort;
|
|
19
|
+
readonly serviceTier?: SessionServiceTier;
|
|
20
|
+
}
|
|
21
|
+
export interface AgentBaseOptions {
|
|
22
|
+
/** Stable session identity supplied by the caller. */
|
|
23
|
+
readonly id: string;
|
|
24
|
+
/** The registry providers are resolved from, at session creation time. */
|
|
25
|
+
readonly providers: AgentProviders;
|
|
26
|
+
/** The registry ID of the provider to use; serializable alongside model and effort. */
|
|
27
|
+
readonly provider: string;
|
|
28
|
+
readonly persistence: AgentBasePersistence;
|
|
29
|
+
readonly hooks?: AgentBaseHooks;
|
|
30
|
+
/** Copied into the agent's own mutable `state`. */
|
|
31
|
+
readonly initialState?: Partial<AgentBaseState>;
|
|
32
|
+
readonly model?: string;
|
|
33
|
+
readonly effort?: SessionReasoningEffort;
|
|
34
|
+
readonly serviceTier?: SessionServiceTier;
|
|
35
|
+
readonly steeringMode?: AgentBaseQueueMode;
|
|
36
|
+
readonly sendMode?: AgentBaseQueueMode;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* A single agent session over one provider. Messages arrive through two FIFO queues: steering
|
|
40
|
+
* messages inject as soon as the current assistant response and its tool batch finish, while
|
|
41
|
+
* sent messages wait until the agent would otherwise stop — no tool calls or steering remain.
|
|
42
|
+
* Each queue drains per its configured mode, and the conversation is durable through
|
|
43
|
+
* append-only persistence loaded on the first inference attempt.
|
|
44
|
+
*/
|
|
45
|
+
export declare class AgentBase {
|
|
46
|
+
#private;
|
|
47
|
+
readonly id: string;
|
|
48
|
+
/**
|
|
49
|
+
* The agent's own copy of the initial state, mutable directly; every inference reads the
|
|
50
|
+
* current values.
|
|
51
|
+
*/
|
|
52
|
+
readonly state: AgentBaseState;
|
|
53
|
+
constructor(ctx: Context, options: AgentBaseOptions);
|
|
54
|
+
/**
|
|
55
|
+
* Queue a user message that injects as soon as the current assistant response and its tool
|
|
56
|
+
* batch finish; steering always takes precedence over sent messages. The returned promise
|
|
57
|
+
* resolves once the durable write lands; it waits neither for the history load nor for the
|
|
58
|
+
* turn, and a failed write keeps the message out of the conversation entirely.
|
|
59
|
+
*/
|
|
60
|
+
steer(ctx: Context, message: SessionUserMessage, options?: AgentBaseMessageOptions): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Queue a user message that waits until the agent would otherwise stop — no tool calls or
|
|
63
|
+
* steering remain — before injecting. The returned promise resolves once the durable write
|
|
64
|
+
* lands; it waits neither for the history load nor for the turn, and a failed write keeps
|
|
65
|
+
* the message out of the conversation entirely.
|
|
66
|
+
*/
|
|
67
|
+
send(ctx: Context, message: SessionUserMessage, options?: AgentBaseMessageOptions): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Start the loop without a new message: load the durable state and, if a turn was cut off —
|
|
70
|
+
* queued messages, a dispatched tool batch without results, or an unanswered user or tool
|
|
71
|
+
* message — continue it to completion. On an idle history this loads and does nothing more.
|
|
72
|
+
*/
|
|
73
|
+
start(): void;
|
|
74
|
+
waitForIdle(): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Compact the conversation. The compaction waits for the active turn to end — or runs right
|
|
77
|
+
* away when idle — and replaces the compacted history with the provider's replacement
|
|
78
|
+
* context while keeping every message that joined the history after the snapshot. Calls made
|
|
79
|
+
* while a compaction is pending or running await that same compaction; the shared promise
|
|
80
|
+
* resolves when it completes and rejects when the provider reports failure.
|
|
81
|
+
*/
|
|
82
|
+
compact(ctx: Context): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* Cancel the active turn: stop consuming the inference stream, settle still-running tool
|
|
85
|
+
* calls as aborted error results, and drop the queued turn request. Blocks that already
|
|
86
|
+
* finished stay in the history; an unfinished block is dropped. Messages still waiting in
|
|
87
|
+
* the steering and send queues stay durable and join the next requested turn. Resolves
|
|
88
|
+
* once the loop has stopped; a no-op when the agent is idle.
|
|
89
|
+
*/
|
|
90
|
+
abort(): Promise<void>;
|
|
91
|
+
close(): Promise<void>;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=AgentBase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentBase.d.ts","sourceRoot":"","sources":["../sources/AgentBase.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAMR,sBAAsB,EACtB,kBAAkB,EAIlB,kBAAkB,EACrB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAA2C,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG3F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAOrD,mGAAmG;AACnG,MAAM,MAAM,kBAAkB,GAAG,eAAe,GAAG,KAAK,CAAC;AAEzD;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACpC,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,sBAAsB,CAAC;IACzC,QAAQ,CAAC,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAC7C;AASD,MAAM,WAAW,gBAAgB;IAC7B,sDAAsD;IACtD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;IACnC,uFAAuF;IACvF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,oBAAoB,CAAC;IAC3C,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC;IAChC,mDAAmD;IACnD,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IAChD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,sBAAsB,CAAC;IACzC,QAAQ,CAAC,WAAW,CAAC,EAAE,kBAAkB,CAAC;IAC1C,QAAQ,CAAC,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAC3C,QAAQ,CAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAC;CAC1C;AAED;;;;;;GAMG;AACH,qBAAa,SAAS;;IAClB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAwC/B,YAAY,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAmBlD;IAWD;;;;;OAKG;IACG,KAAK,CACP,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,kBAAkB,EAC3B,OAAO,CAAC,EAAE,uBAAuB,GAClC,OAAO,CAAC,IAAI,CAAC,CAEf;IAED;;;;;OAKG;IACG,IAAI,CACN,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,kBAAkB,EAC3B,OAAO,CAAC,EAAE,uBAAuB,GAClC,OAAO,CAAC,IAAI,CAAC,CAEf;IAmBD;;;;OAIG;IACH,KAAK,IAAI,IAAI,CAGZ;IAEK,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAIjC;IAED;;;;;;OAMG;IACG,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAGzC;IAyCD;;;;;;OAMG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAM3B;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAM3B;CAqvBJ"}
|