@loopingai/core 0.1.1 → 0.1.2
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 +58 -4
- package/dist/contract/index.d.ts +1 -1
- package/dist/contract/index.d.ts.map +1 -1
- package/dist/contract/index.js.map +1 -1
- package/dist/contract/plugin.d.ts +86 -3
- package/dist/contract/plugin.d.ts.map +1 -1
- package/dist/contract/plugin.js.map +1 -1
- package/dist/db/db.d.ts +32 -14
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/db.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/runtime/index.d.ts +20 -2
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +37 -2
- package/dist/runtime/index.js.map +1 -1
- package/dist/subagent/workspace.d.ts +21 -0
- package/dist/subagent/workspace.d.ts.map +1 -1
- package/dist/subagent/workspace.js +80 -5
- package/dist/subagent/workspace.js.map +1 -1
- package/dist/testing/node.d.ts +23 -0
- package/dist/testing/node.d.ts.map +1 -1
- package/dist/testing/node.js +23 -0
- package/dist/testing/node.js.map +1 -1
- package/dist/testing/vcr-spec.d.ts +4 -4
- package/dist/testing/vcr-spec.d.ts.map +1 -1
- package/dist/testing/vcr-spec.js +32 -11
- package/dist/testing/vcr-spec.js.map +1 -1
- package/package.json +8 -4
package/README.md
CHANGED
|
@@ -207,10 +207,40 @@ its cause.
|
|
|
207
207
|
The contract is **additive-only within a major**: new capabilities arrive as optional
|
|
208
208
|
fields on `AgentPlugin`.
|
|
209
209
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
210
|
+
### Plugin-owned tables
|
|
211
|
+
|
|
212
|
+
A plugin owns its tables outright, through `store: PluginStore` — but it must stay out of
|
|
213
|
+
core's migration journal. `drizzle-orm/durable-sqlite/migrator` keeps one flat integer
|
|
214
|
+
journal and one global `__drizzle_migrations` table, and two independently-versioned
|
|
215
|
+
packages cannot share that index space.
|
|
216
|
+
|
|
217
|
+
That is a prohibition on exactly **one import**, not on drizzle. The query builder holds
|
|
218
|
+
no journal and no connection state, so a plugin declares its tables with `sqliteTable`,
|
|
219
|
+
writes idempotent DDL in `ensureTables`, and queries through its own handle:
|
|
220
|
+
|
|
221
|
+
```ts
|
|
222
|
+
export const scrapes = sqliteTable("scraper_scrapes", { url: text("url").primaryKey() });
|
|
223
|
+
|
|
224
|
+
store: {
|
|
225
|
+
plugin: "scraper",
|
|
226
|
+
version: 1,
|
|
227
|
+
// Re-run on every hibernation wake-up, so it must be idempotent.
|
|
228
|
+
ensureTables: (sql) => sql.exec(`CREATE TABLE IF NOT EXISTS scraper_scrapes (…)`)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// …and anywhere the plugin queries:
|
|
232
|
+
const db = drizzle(storage, { schema: { scrapes } });
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Core records each store's version in a `plugin_migrations` row, so `ensureTables` receives
|
|
236
|
+
the version last seen on disk and an upgrade path can branch on it.
|
|
237
|
+
|
|
238
|
+
### Session hooks
|
|
239
|
+
|
|
240
|
+
`onMessagesDisplaced` hands over the raw messages a compaction is about to fold into a
|
|
241
|
+
summary. Core performs the compaction, so core announces the loss; it neither stores the
|
|
242
|
+
messages nor knows who wants them. An episodic-memory plugin, an audit log, and a
|
|
243
|
+
cold-storage dump all want exactly this callback, and each gets it:
|
|
214
244
|
|
|
215
245
|
```ts
|
|
216
246
|
// in your DO, wiring the runtime's fan-out into the session
|
|
@@ -224,6 +254,30 @@ Best-effort in both directions — a listener that throws never aborts compactio
|
|
|
224
254
|
must still shorten when a side store is down), and the fan-out is `Promise.allSettled`, so
|
|
225
255
|
one plugin's outage cannot cost another its notification.
|
|
226
256
|
|
|
257
|
+
`shouldHandleTurn` is the other side of the session: a gate that decides whether a turn
|
|
258
|
+
runs at all, before the loop builds or calls anything. An agent that sees every message in
|
|
259
|
+
its channels is mostly seeing messages that are not for it, and asking a model already
|
|
260
|
+
trying to be helpful to stay quiet degrades _invisibly_ — failing to call a decline-tool
|
|
261
|
+
looks identical to deciding not to. Every declaring plugin is consulted and the answers are
|
|
262
|
+
AND-ed, so any one gate may decline.
|
|
263
|
+
|
|
264
|
+
```ts
|
|
265
|
+
if (!(await this.runtime.shouldHandleTurn({ history }))) return; // declined
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
It **fails open**: a gate that throws is counted as `true`. The two mistakes are not
|
|
269
|
+
symmetric — a wrong reply is noise the user can see and ignore, while a wrong silence is
|
|
270
|
+
invisible to the person who needed an answer.
|
|
271
|
+
|
|
272
|
+
### The workspace backend
|
|
273
|
+
|
|
274
|
+
Core declares the `WorkspaceBacking` shape and enforces the caps, but ships no backend —
|
|
275
|
+
the predecessor's was `@cloudflare/shell`, which is experimental, and an agent that never
|
|
276
|
+
delegates file work should not carry it. A plugin supplies one via `workspaceBacking`; at
|
|
277
|
+
most one may, and an agent that installs none gets `memoryWorkspaceBacking`. So
|
|
278
|
+
`runtime.workspaceBacking` is always defined and your `SubagentRuntime` never needs a null
|
|
279
|
+
check.
|
|
280
|
+
|
|
227
281
|
---
|
|
228
282
|
|
|
229
283
|
## Testing
|
package/dist/contract/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Re-exported from the package root as well, so a plugin author writes
|
|
5
5
|
* `import { definePlugin } from "@loopingai/core"` and nothing else.
|
|
6
6
|
*/
|
|
7
|
-
export { PLUGIN_CONTRACT_VERSION, definePlugin, type AgentPlugin, type EmitProgress, type EnrichResultContext, type PluginRequirements, type RecipeToolSet, type ResolveRuntimeContext, type ToolFamilyBuilder, type ToolFamilyContext } from "./plugin.js";
|
|
7
|
+
export { PLUGIN_CONTRACT_VERSION, definePlugin, type AgentPlugin, type EmitProgress, type EnrichResultContext, type MainAgentToolContext, type PluginRequirements, type RecipeToolSet, type ResolveRuntimeContext, type ToolFamilyBuilder, type ToolFamilyContext, type TurnGateContext } from "./plugin.js";
|
|
8
8
|
export type { DelegationNames, RecipeLimits, ResolvedRecipe, SubtaskParams, SubtaskParamsSchema, SubtaskParamsShape, SubtaskTypeSpec, ValidatedRecipe } from "./recipe.js";
|
|
9
9
|
export { RecipeValidationError, resolveLimits, validateRecipe, type RecipePolicy } from "./validation.js";
|
|
10
10
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/contract/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,uBAAuB,EACvB,YAAY,EACZ,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/contract/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,uBAAuB,EACvB,YAAY,EACZ,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACrB,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,eAAe,EACf,YAAY,EACZ,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,eAAe,EAChB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,qBAAqB,EACrB,aAAa,EACb,cAAc,EACd,KAAK,YAAY,EAClB,MAAM,iBAAiB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/contract/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,uBAAuB,EACvB,YAAY,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/contract/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,uBAAuB,EACvB,YAAY,EAWb,MAAM,aAAa,CAAC;AAarB,OAAO,EACL,qBAAqB,EACrB,aAAa,EACb,cAAc,EAEf,MAAM,iBAAiB,CAAC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { ToolSet } from "ai";
|
|
2
2
|
import type { SessionMessage } from "agents/experimental/memory/session";
|
|
3
|
+
import type { SessionLike } from "../agent/session.js";
|
|
3
4
|
import type { PluginStore } from "../db/db.js";
|
|
4
|
-
import type { WorkspaceHandle } from "../subagent/workspace.js";
|
|
5
|
+
import type { WorkspaceBacking, WorkspaceHandle } from "../subagent/workspace.js";
|
|
5
6
|
import type { ProgressEvent, RecipeExecutionRequest, RecipeExecutionResult, SubtaskRuntime } from "../subtasks/types.js";
|
|
6
7
|
import type { SubtaskParams, SubtaskTypeSpec } from "./recipe.js";
|
|
7
8
|
/**
|
|
@@ -88,6 +89,34 @@ export interface EnrichResultContext<TRuntime = SubtaskRuntime> {
|
|
|
88
89
|
request: RecipeExecutionRequest;
|
|
89
90
|
runtime: TRuntime;
|
|
90
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* What a plugin knows when it builds the *main* agent's tools.
|
|
94
|
+
*
|
|
95
|
+
* Deliberately just the session, and deliberately not the caller's identity. A
|
|
96
|
+
* plugin that needs a per-caller value takes it as config at instantiation, like
|
|
97
|
+
* every other config value — the Durable Object is keyed 1:1 by the verified
|
|
98
|
+
* caller, so that value is constant for its life. Putting it here as well would
|
|
99
|
+
* give a plugin two ways to reach one fact, and the *other* hook that needs it
|
|
100
|
+
* ({@link AgentPlugin.onMessagesDisplaced}) has no context to read it from
|
|
101
|
+
* anyway.
|
|
102
|
+
*
|
|
103
|
+
* What the session gives that config cannot is **durable state the tool surface
|
|
104
|
+
* depends on** — whether history has ever been compacted, how many contexts are
|
|
105
|
+
* set. That is a question only the session can answer, and only at call time.
|
|
106
|
+
*/
|
|
107
|
+
export interface MainAgentToolContext {
|
|
108
|
+
session: SessionLike;
|
|
109
|
+
}
|
|
110
|
+
/** What a plugin knows when deciding whether a turn should run at all. */
|
|
111
|
+
export interface TurnGateContext {
|
|
112
|
+
/**
|
|
113
|
+
* The conversation so far, **including the message being judged** — which is
|
|
114
|
+
* already appended when a gate runs, so the agent reads a message it declines.
|
|
115
|
+
* A bare message is frequently unclassifiable ("yes", "thanks", "and the
|
|
116
|
+
* second one?"), so the tail is what makes the judgement possible at all.
|
|
117
|
+
*/
|
|
118
|
+
history: SessionMessage[];
|
|
119
|
+
}
|
|
91
120
|
/** Bindings and secrets a plugin needs the *host* to provide in `wrangler.jsonc`. */
|
|
92
121
|
export interface PluginRequirements {
|
|
93
122
|
/** Secret names, e.g. `["ARC_API_KEY"]`. */
|
|
@@ -115,11 +144,25 @@ export interface AgentPlugin<TRuntime = SubtaskRuntime> {
|
|
|
115
144
|
* `validateRecipe`, so the legal set is exactly what is installed.
|
|
116
145
|
*/
|
|
117
146
|
toolFamilies?: Record<string, ToolFamilyBuilder<TRuntime>>;
|
|
118
|
-
/**
|
|
119
|
-
|
|
147
|
+
/**
|
|
148
|
+
* Tools offered to the *main* agent (e.g. a catalogue lookup before
|
|
149
|
+
* delegating).
|
|
150
|
+
*
|
|
151
|
+
* May return a promise, so a plugin can shape its tool surface from durable
|
|
152
|
+
* state — offering a search tool only once there is something to search, say.
|
|
153
|
+
* A tool that can only ever return "nothing here yet" costs the model a call to
|
|
154
|
+
* find that out, and costs every round the tokens to describe it.
|
|
155
|
+
*/
|
|
156
|
+
mainAgentTools?: (ctx: MainAgentToolContext) => ToolSet | Promise<ToolSet>;
|
|
120
157
|
/**
|
|
121
158
|
* What the main agent is told it can do with this domain, rendered into its
|
|
122
159
|
* soul alongside the other capability blocks.
|
|
160
|
+
*
|
|
161
|
+
* A plugin that declares a {@link subtaskType} should put its capability block
|
|
162
|
+
* on the *type* instead ({@link SubtaskTypeSpec.capability}) and leave this
|
|
163
|
+
* unset — the two are rendered by different call sites, so declaring both
|
|
164
|
+
* makes the main agent read the same advice twice per round. Which is the
|
|
165
|
+
* exact failure the type's own prompt fields were introduced to end.
|
|
123
166
|
*/
|
|
124
167
|
capability?: string;
|
|
125
168
|
/**
|
|
@@ -138,6 +181,28 @@ export interface AgentPlugin<TRuntime = SubtaskRuntime> {
|
|
|
138
181
|
enrichResult?: (ctx: EnrichResultContext<TRuntime>, result: RecipeExecutionResult) => Promise<RecipeExecutionResult>;
|
|
139
182
|
/** Release anything {@link resolveRuntime} acquired, when an execution is canceled. */
|
|
140
183
|
onAbort?: (ctx: ResolveRuntimeContext) => Promise<void>;
|
|
184
|
+
/**
|
|
185
|
+
* Decide whether a turn should run at all, before the loop builds or calls
|
|
186
|
+
* anything.
|
|
187
|
+
*
|
|
188
|
+
* An agent that sees every message in its channels is mostly seeing messages
|
|
189
|
+
* that are not for it. Left to the main loop that judgement is made by a model
|
|
190
|
+
* simultaneously trying to be helpful, with history and half a dozen tools in
|
|
191
|
+
* view, and it degrades exactly there — *invisibly*, because failing to call a
|
|
192
|
+
* decline-tool looks identical to deciding not to. A gate moves the decision
|
|
193
|
+
* somewhere it cannot be skipped.
|
|
194
|
+
*
|
|
195
|
+
* **Fails open, and the asymmetry is the whole design.** A gate that throws is
|
|
196
|
+
* counted as `true`, so an outage degrades to the previous behaviour (run the
|
|
197
|
+
* turn) and never to a silent agent: a wrong reply is noise the user can see
|
|
198
|
+
* and ignore, while a wrong silence is invisible — the person who needed the
|
|
199
|
+
* agent simply never hears back. Failing *synchronously* is as safe as
|
|
200
|
+
* rejecting.
|
|
201
|
+
*
|
|
202
|
+
* Every declaring plugin is consulted and the results are AND-ed: any one gate
|
|
203
|
+
* may decline the turn. Returning `true` is always valid.
|
|
204
|
+
*/
|
|
205
|
+
shouldHandleTurn?: (ctx: TurnGateContext) => Promise<boolean>;
|
|
141
206
|
/**
|
|
142
207
|
* The raw messages a compaction is about to fold into a summary, handed over
|
|
143
208
|
* before they stop being readable as history.
|
|
@@ -158,6 +223,24 @@ export interface AgentPlugin<TRuntime = SubtaskRuntime> {
|
|
|
158
223
|
onMessagesDisplaced?: (messages: SessionMessage[]) => Promise<void>;
|
|
159
224
|
/** Tables this plugin owns, outside core's migration journal. See {@link PluginStore}. */
|
|
160
225
|
store?: PluginStore;
|
|
226
|
+
/**
|
|
227
|
+
* The durable file store a subagent execution's workspace is built over.
|
|
228
|
+
*
|
|
229
|
+
* Core declares the {@link WorkspaceBacking} shape and enforces the caps, but
|
|
230
|
+
* ships no backend: the predecessor's was `@cloudflare/shell`, which is
|
|
231
|
+
* experimental ("expect breaking changes"), and an agent that never delegates
|
|
232
|
+
* file work should not carry it. So the backend arrives here, from a plugin,
|
|
233
|
+
* and an agent that installs none falls back to an in-memory one.
|
|
234
|
+
*
|
|
235
|
+
* At most one installed plugin may declare this — two backends would mean two
|
|
236
|
+
* answers to "where did that file go", and the file would be in whichever the
|
|
237
|
+
* runtime happened to pick.
|
|
238
|
+
*
|
|
239
|
+
* `sql` is the executing facet's own SQLite, so isolation per execution is
|
|
240
|
+
* free and deleting the child wipes the workspace with it. `name` is lazy
|
|
241
|
+
* because a facet's name is set after construction.
|
|
242
|
+
*/
|
|
243
|
+
workspaceBacking?: (sql: SqlStorage, name: () => string | undefined) => WorkspaceBacking;
|
|
161
244
|
/**
|
|
162
245
|
* Bindings and secrets the host must declare in `wrangler.jsonc`. A plugin
|
|
163
246
|
* cannot add its own binding, so declaring them lets startup fail with a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/contract/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/contract/plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/contract/plugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/contract/plugin.ts"],"names":[],"mappings":"AAgBA;;;;;;;;GAQG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAkQzC;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAC1B,MAEC;IAED,OAAO;QACL,GAAG,MAAM;QACT,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,uBAAuB;KACnE,CAAC;AACJ,CAAC"}
|
package/dist/db/db.d.ts
CHANGED
|
@@ -4,23 +4,37 @@ export type DB = DrizzleSqliteDODatabase<typeof schema>;
|
|
|
4
4
|
/**
|
|
5
5
|
* A table owner outside core's migration journal.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* diff at all.
|
|
7
|
+
* What a plugin cannot share is the **migrator**. `drizzle-orm/durable-sqlite/
|
|
8
|
+
* migrator` keeps one flat integer journal and one global
|
|
9
|
+
* `__drizzle_migrations` table, and two independently-versioned npm packages
|
|
10
|
+
* cannot share that index space — not hypothetically: the two predecessor
|
|
11
|
+
* agents, both consuming the same `notify_tasks` module, had already forked the
|
|
12
|
+
* journal at index 1 (`0001_unusual_nova` vs `0001_great_goliath`). Worse,
|
|
13
|
+
* `drizzle-kit generate` diffs against a snapshot in one output directory, so a
|
|
14
|
+
* plugin shipping from its own repo cannot produce a correct diff at all.
|
|
15
15
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
16
|
+
* **The query builder is a different thing entirely, and a plugin should use
|
|
17
|
+
* it.** `drizzle(storage, { schema })` is a typed wrapper over the same
|
|
18
|
+
* `DurableObjectStorage`; it holds no journal, no connection, and no state that
|
|
19
|
+
* a second handle could disturb. So the rule is narrow — *never import the
|
|
20
|
+
* migrator* — rather than "no drizzle".
|
|
21
|
+
*
|
|
22
|
+
* A plugin therefore does three things: declares its tables with `sqliteTable`
|
|
23
|
+
* as usual, emits idempotent DDL here, and queries through its own drizzle
|
|
24
|
+
* handle. Version bookkeeping lives in the {@link PLUGIN_MIGRATIONS_TABLE} row
|
|
25
|
+
* this class manages for it. Only the DDL is hand-written, and that pattern is
|
|
26
|
+
* not novel here — it is what the subagent facet already does for its own two
|
|
27
|
+
* tables.
|
|
21
28
|
*
|
|
22
29
|
* ```ts
|
|
23
|
-
*
|
|
30
|
+
* // schema.ts — an ordinary drizzle table, under the plugin's own prefix.
|
|
31
|
+
* export const arcScorecards = sqliteTable("arc_scorecards", {
|
|
32
|
+
* cardId: text("card_id").primaryKey(),
|
|
33
|
+
* lastUsedAt: integer("last_used_at").notNull()
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* // The DDL half: idempotent, re-run on every hibernation wake-up.
|
|
37
|
+
* const store: PluginStore = {
|
|
24
38
|
* plugin: "arc-agi",
|
|
25
39
|
* version: 2,
|
|
26
40
|
* ensureTables(sql, from) {
|
|
@@ -28,6 +42,10 @@ export type DB = DrizzleSqliteDODatabase<typeof schema>;
|
|
|
28
42
|
* if (from < 2) sql.exec(`ALTER TABLE arc_scorecards ADD COLUMN …`);
|
|
29
43
|
* }
|
|
30
44
|
* };
|
|
45
|
+
*
|
|
46
|
+
* // The query half: drizzle, over the plugin's own handle.
|
|
47
|
+
* const db = drizzle(storage, { schema: { arcScorecards } });
|
|
48
|
+
* db.select().from(arcScorecards).where(gte(arcScorecards.lastUsedAt, since));
|
|
31
49
|
* ```
|
|
32
50
|
*/
|
|
33
51
|
export interface PluginStore {
|
package/dist/db/db.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/db/db.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AAKtC,MAAM,MAAM,EAAE,GAAG,uBAAuB,CAAC,OAAO,MAAM,CAAC,CAAC;AAExD
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/db/db.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AAKtC,MAAM,MAAM,EAAE,GAAG,uBAAuB,CAAC,OAAO,MAAM,CAAC,CAAC;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,MAAM,WAAW,WAAW;IAC1B,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;;OAOG;IACH,YAAY,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACnD;AAED,iGAAiG;AACjG,eAAO,MAAM,uBAAuB,sBAAsB,CAAC;AAE3D,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IAChC;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,OAAO;IAOhB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAP1B,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAK;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,MAAM,CAAC,CAA+B;IAC9C,OAAO,CAAC,SAAS,CAAC,CAAkC;gBAGjC,OAAO,EAAE,oBAAoB,EAC7B,OAAO,EAAE,cAAc;IAQ1C,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,IAAI,KAAK;;;;;;;;;;;;;;;MAER;IAED,IAAI,QAAQ;;;;;;;;;;;;;;;MAIX;IAED;;;;;;;;OAQG;IACH,OAAO,CAAC,WAAW;CAsDpB"}
|
package/dist/db/db.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/db/db.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EAER,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAC;AAC9D,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,YAAY,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/db/db.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
* production bundle.
|
|
10
10
|
*/
|
|
11
11
|
export { createAgentRuntime, RuntimeSetupError, buildRecipeTools, collectToolFamilies, type AgentRuntime, type CreateAgentRuntimeOptions } from "./runtime/index.js";
|
|
12
|
-
export { PLUGIN_CONTRACT_VERSION, definePlugin, type AgentPlugin, type EmitProgress, type EnrichResultContext, type PluginRequirements, type RecipeToolSet, type ResolveRuntimeContext, type ToolFamilyBuilder, type ToolFamilyContext } from "./contract/plugin.js";
|
|
12
|
+
export { PLUGIN_CONTRACT_VERSION, definePlugin, type AgentPlugin, type EmitProgress, type EnrichResultContext, type MainAgentToolContext, type PluginRequirements, type RecipeToolSet, type ResolveRuntimeContext, type ToolFamilyBuilder, type ToolFamilyContext, type TurnGateContext } from "./contract/plugin.js";
|
|
13
13
|
export type { DelegationNames, RecipeLimits, ResolvedRecipe, SubtaskParams, SubtaskParamsSchema, SubtaskParamsShape, SubtaskTypeSpec, ValidatedRecipe } from "./contract/recipe.js";
|
|
14
14
|
export { RecipeValidationError, resolveLimits, validateRecipe, type RecipePolicy } from "./contract/validation.js";
|
|
15
15
|
export { ConfigError, DEFAULT_CORE_CONFIG, resolveConfig, type AgentLimits, type CoreConfig, type CoreConfigOverrides, type ModelConfig, type SessionConfig } from "./config.js";
|
|
16
16
|
export { parseGatewayOrigins, type A2ASecretsEnv, type AiEnv, type CoreEnv } from "./env.js";
|
|
17
17
|
export { CHUNK_SOFT_MS, MAX_CHUNKS_PER_BRANCH, STEP_TIMEOUT_MS, STEPS_PER_INSTANCE } from "./platform.js";
|
|
18
18
|
export type { PluginStore } from "./db/db.js";
|
|
19
|
-
export { makeWorkspaceHandle, WorkspaceLimitError, WORKSPACE_MAX_FILES, WORKSPACE_MAX_FILE_BYTES, type WorkspaceBacking, type WorkspaceEntry, type WorkspaceHandle } from "./subagent/workspace.js";
|
|
19
|
+
export { makeWorkspaceHandle, memoryWorkspaceBacking, WorkspaceLimitError, WORKSPACE_MAX_FILES, WORKSPACE_MAX_FILE_BYTES, type WorkspaceBacking, type WorkspaceEntry, type WorkspaceHandle } from "./subagent/workspace.js";
|
|
20
20
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,KAAK,YAAY,EACjB,KAAK,yBAAyB,EAC/B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,uBAAuB,EACvB,YAAY,EACZ,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,KAAK,YAAY,EACjB,KAAK,yBAAyB,EAC/B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,uBAAuB,EACvB,YAAY,EACZ,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACrB,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EACV,eAAe,EACf,YAAY,EACZ,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,eAAe,EAChB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,qBAAqB,EACrB,aAAa,EACb,cAAc,EACd,KAAK,YAAY,EAClB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAChB,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,mBAAmB,EACnB,KAAK,aAAa,EAClB,KAAK,KAAK,EACV,KAAK,OAAO,EACb,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EACnB,MAAM,eAAe,CAAC;AAEvB,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,EACxB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -14,5 +14,5 @@ export { RecipeValidationError, resolveLimits, validateRecipe } from "./contract
|
|
|
14
14
|
export { ConfigError, DEFAULT_CORE_CONFIG, resolveConfig } from "./config.js";
|
|
15
15
|
export { parseGatewayOrigins } from "./env.js";
|
|
16
16
|
export { CHUNK_SOFT_MS, MAX_CHUNKS_PER_BRANCH, STEP_TIMEOUT_MS, STEPS_PER_INSTANCE } from "./platform.js";
|
|
17
|
-
export { makeWorkspaceHandle, WorkspaceLimitError, WORKSPACE_MAX_FILES, WORKSPACE_MAX_FILE_BYTES } from "./subagent/workspace.js";
|
|
17
|
+
export { makeWorkspaceHandle, memoryWorkspaceBacking, WorkspaceLimitError, WORKSPACE_MAX_FILES, WORKSPACE_MAX_FILE_BYTES } from "./subagent/workspace.js";
|
|
18
18
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EAGpB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,uBAAuB,EACvB,YAAY,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EAGpB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,uBAAuB,EACvB,YAAY,EAWb,MAAM,sBAAsB,CAAC;AAa9B,OAAO,EACL,qBAAqB,EACrB,aAAa,EACb,cAAc,EAEf,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,aAAa,EAMd,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,mBAAmB,EAIpB,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EACnB,MAAM,eAAe,CAAC;AAIvB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,EAIzB,MAAM,yBAAyB,CAAC"}
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { ToolSet } from "ai";
|
|
2
2
|
import type { SessionMessage } from "agents/experimental/memory/session";
|
|
3
3
|
import { type CoreConfig, type CoreConfigOverrides } from "../config.js";
|
|
4
|
-
import { type AgentPlugin, type EnrichResultContext, type ResolveRuntimeContext, type ToolFamilyBuilder } from "../contract/plugin.js";
|
|
4
|
+
import { type AgentPlugin, type EnrichResultContext, type MainAgentToolContext, type ResolveRuntimeContext, type ToolFamilyBuilder, type TurnGateContext } from "../contract/plugin.js";
|
|
5
5
|
import type { PluginStore } from "../db/db.js";
|
|
6
|
+
import { type WorkspaceBacking } from "../subagent/workspace.js";
|
|
6
7
|
import type { RecipePolicy } from "../contract/validation.js";
|
|
7
8
|
import { type SubtaskTypeRegistry } from "../subtasks/subtask-types.js";
|
|
8
9
|
import type { RecipeExecutionResult, SubtaskRuntime } from "../subtasks/types.js";
|
|
@@ -46,15 +47,32 @@ export interface AgentRuntime {
|
|
|
46
47
|
secrets: string[];
|
|
47
48
|
bindings: string[];
|
|
48
49
|
};
|
|
50
|
+
/**
|
|
51
|
+
* The subagent workspace backend — the one plugin that declared it, or an
|
|
52
|
+
* in-memory fallback when none did. Always defined, so a host writes
|
|
53
|
+
* `workspaceBacking: runtime.workspaceBacking` into its `SubagentRuntime`
|
|
54
|
+
* unconditionally.
|
|
55
|
+
*/
|
|
56
|
+
workspaceBacking: (sql: SqlStorage, name: () => string | undefined) => WorkspaceBacking;
|
|
49
57
|
/** The plugin that declared a subtask type, or null. */
|
|
50
58
|
pluginForType(type: string): AgentPlugin | null;
|
|
51
59
|
/** Tools the installed plugins offer the *main* agent, merged. */
|
|
52
|
-
mainAgentTools(): ToolSet
|
|
60
|
+
mainAgentTools(ctx: MainAgentToolContext): Promise<ToolSet>;
|
|
53
61
|
/**
|
|
54
62
|
* Every plugin's `capability` block, for the main agent's soul. Returns `""`
|
|
55
63
|
* when none declares one, so a call site can append unconditionally.
|
|
56
64
|
*/
|
|
57
65
|
renderCapabilities(): string;
|
|
66
|
+
/**
|
|
67
|
+
* Ask every plugin declaring {@link AgentPlugin.shouldHandleTurn} whether this
|
|
68
|
+
* turn should run. `true` when none declares one, and `false` if any single
|
|
69
|
+
* gate declines.
|
|
70
|
+
*
|
|
71
|
+
* Never rejects: a gate that fails is logged against its plugin key and
|
|
72
|
+
* counted as `true`, because the failure mode of a broken gate must be a noisy
|
|
73
|
+
* agent, never a silent one.
|
|
74
|
+
*/
|
|
75
|
+
shouldHandleTurn(ctx: TurnGateContext): Promise<boolean>;
|
|
58
76
|
/**
|
|
59
77
|
* Announce the messages a compaction is folding into a summary to every plugin
|
|
60
78
|
* declaring {@link AgentPlugin.onMessagesDisplaced}. Pass it straight to
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,mBAAmB,EACzB,MAAM,cAAc,CAAC;AACtB,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { resolveConfig } from "../config.js";
|
|
2
2
|
import { PLUGIN_CONTRACT_VERSION } from "../contract/plugin.js";
|
|
3
|
+
import { memoryWorkspaceBacking } from "../subagent/workspace.js";
|
|
3
4
|
import { makeSubtaskTypes } from "../subtasks/subtask-types.js";
|
|
4
5
|
import { collectToolFamilies } from "./tool-families.js";
|
|
5
6
|
export { buildRecipeTools, collectToolFamilies } from "./tool-families.js";
|
|
@@ -43,6 +44,14 @@ export function createAgentRuntime(options) {
|
|
|
43
44
|
const displacementListeners = plugins.flatMap((p) => p.onMessagesDisplaced
|
|
44
45
|
? [{ key: p.key, notify: p.onMessagesDisplaced.bind(p) }]
|
|
45
46
|
: []);
|
|
47
|
+
const turnGates = plugins.flatMap((p) => p.shouldHandleTurn ? [{ key: p.key, gate: p.shouldHandleTurn.bind(p) }] : []);
|
|
48
|
+
// At most one backend: two would mean two answers to "where did that file go".
|
|
49
|
+
const backings = plugins.flatMap((p) => p.workspaceBacking ? [{ key: p.key, make: p.workspaceBacking.bind(p) }] : []);
|
|
50
|
+
if (backings.length > 1) {
|
|
51
|
+
throw new RuntimeSetupError(`plugins ${backings.map((b) => `"${b.key}"`).join(" and ")} both declare a ` +
|
|
52
|
+
"workspaceBacking — an execution has one workspace, so only one plugin may back it");
|
|
53
|
+
}
|
|
54
|
+
const workspaceBacking = backings[0]?.make ?? memoryWorkspaceBacking;
|
|
46
55
|
const secrets = [
|
|
47
56
|
...new Set(plugins.flatMap((p) => [...(p.requires?.secrets ?? [])]))
|
|
48
57
|
];
|
|
@@ -87,12 +96,16 @@ export function createAgentRuntime(options) {
|
|
|
87
96
|
policy,
|
|
88
97
|
stores,
|
|
89
98
|
requirements: { secrets, bindings },
|
|
99
|
+
workspaceBacking,
|
|
90
100
|
pluginForType,
|
|
91
|
-
mainAgentTools() {
|
|
101
|
+
async mainAgentTools(ctx) {
|
|
92
102
|
const tools = {};
|
|
103
|
+
// Sequential rather than fanned out: this is a handful of plugins reading
|
|
104
|
+
// one session, and merging in declaration order is what makes a name
|
|
105
|
+
// collision resolve the same way on every call.
|
|
93
106
|
for (const plugin of plugins) {
|
|
94
107
|
if (plugin.mainAgentTools)
|
|
95
|
-
Object.assign(tools, plugin.mainAgentTools());
|
|
108
|
+
Object.assign(tools, await plugin.mainAgentTools(ctx));
|
|
96
109
|
}
|
|
97
110
|
return tools;
|
|
98
111
|
},
|
|
@@ -104,6 +117,28 @@ export function createAgentRuntime(options) {
|
|
|
104
117
|
}
|
|
105
118
|
return blocks.join("\n\n");
|
|
106
119
|
},
|
|
120
|
+
async shouldHandleTurn(ctx) {
|
|
121
|
+
if (turnGates.length === 0)
|
|
122
|
+
return true;
|
|
123
|
+
// Same `allSettled` + `async`-wrapped-callback discipline as
|
|
124
|
+
// `onMessagesDisplaced` below, and for the same two reasons: every gate is
|
|
125
|
+
// consulted even when one throws, and a gate that throws *synchronously*
|
|
126
|
+
// (reading a binding before its first await) is caught rather than
|
|
127
|
+
// escaping past the aggregation.
|
|
128
|
+
//
|
|
129
|
+
// A rejection resolves to `true`. That is not leniency — it is the only
|
|
130
|
+
// safe default here. A wrong reply is noise the user sees and ignores; a
|
|
131
|
+
// wrong silence is invisible to the person who needed an answer, so a
|
|
132
|
+
// broken gate must degrade to "run the turn" and never to a mute agent.
|
|
133
|
+
const results = await Promise.allSettled(turnGates.map(async (g) => g.gate(ctx)));
|
|
134
|
+
return results.every((result, i) => {
|
|
135
|
+
if (result.status === "rejected") {
|
|
136
|
+
console.warn(`[runtime] plugin "${turnGates[i].key}" turn gate failed, handling the turn`, result.reason);
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
return result.value;
|
|
140
|
+
});
|
|
141
|
+
},
|
|
107
142
|
async onMessagesDisplaced(messages) {
|
|
108
143
|
// allSettled, not all: `all` rejects at the first listener to throw and
|
|
109
144
|
// stops awaiting the rest, so every other plugin's write is still in
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,aAAa,EAGd,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,uBAAuB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -48,6 +48,27 @@ export interface WorkspaceBacking {
|
|
|
48
48
|
fileCount: number;
|
|
49
49
|
}>;
|
|
50
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* An in-memory {@link WorkspaceBacking} — the fallback when no installed plugin
|
|
53
|
+
* declares one.
|
|
54
|
+
*
|
|
55
|
+
* Deliberately **not durable**, and that is the honest behaviour rather than a
|
|
56
|
+
* shortcut: a durable stand-in would have to invent a storage layout that a real
|
|
57
|
+
* backend would then have to migrate away from. An agent that delegates file
|
|
58
|
+
* work installs a backend; one that does not never writes a file, and pays
|
|
59
|
+
* nothing for the option. What this buys is that `createAgentRuntime` composes
|
|
60
|
+
* without a workspace plugin at all, so `SubagentRuntime.workspaceBacking` can
|
|
61
|
+
* stay required and a host never writes a null check.
|
|
62
|
+
*
|
|
63
|
+
* Scoped per call, so each execution gets its own map, exactly as a facet's own
|
|
64
|
+
* SQLite would give it its own tables. Contents are lost on isolate eviction —
|
|
65
|
+
* the resumable runner treats a lost workspace as a resumable state everywhere
|
|
66
|
+
* it matters.
|
|
67
|
+
*
|
|
68
|
+
* Signature matches {@link AgentPlugin.workspaceBacking}; both arguments are
|
|
69
|
+
* ignored.
|
|
70
|
+
*/
|
|
71
|
+
export declare function memoryWorkspaceBacking(_sql?: SqlStorage, _name?: () => string | undefined): WorkspaceBacking;
|
|
51
72
|
/** Per-file byte ceiling — safely under the 2 MB Durable Object SQLite row limit. */
|
|
52
73
|
export declare const WORKSPACE_MAX_FILE_BYTES: number;
|
|
53
74
|
/** Max number of files in one workspace — a cheap guard against runaway writes. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/subagent/workspace.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,WAAW,eAAe;IAC9B,wDAAwD;IACxD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC3C,+EAA+E;IAC/E,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,sDAAsD;IACtD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,yDAAyD;IACzD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,8EAA8E;IAC9E,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAC9C,iFAAiF;IACjF,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7C,yDAAyD;IACzD,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxD;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;IACvC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC/C,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC,CAAC;IAC1D,gBAAgB,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAED,qFAAqF;AACrF,eAAO,MAAM,wBAAwB,QAAa,CAAC;AACnD,mFAAmF;AACnF,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,gBAAgB,GAAG,eAAe,
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/subagent/workspace.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,WAAW,eAAe;IAC9B,wDAAwD;IACxD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC3C,+EAA+E;IAC/E,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,sDAAsD;IACtD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,yDAAyD;IACzD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,8EAA8E;IAC9E,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAC9C,iFAAiF;IACjF,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7C,yDAAyD;IACzD,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxD;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;IACvC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC/C,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC,CAAC;IAC1D,gBAAgB,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,CAAC,EAAE,UAAU,EACjB,KAAK,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,GAC/B,gBAAgB,CA2ClB;AAOD,qFAAqF;AACrF,eAAO,MAAM,wBAAwB,QAAa,CAAC;AACnD,mFAAmF;AACnF,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,gBAAgB,GAAG,eAAe,CAsDzE"}
|
|
@@ -1,3 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An in-memory {@link WorkspaceBacking} — the fallback when no installed plugin
|
|
3
|
+
* declares one.
|
|
4
|
+
*
|
|
5
|
+
* Deliberately **not durable**, and that is the honest behaviour rather than a
|
|
6
|
+
* shortcut: a durable stand-in would have to invent a storage layout that a real
|
|
7
|
+
* backend would then have to migrate away from. An agent that delegates file
|
|
8
|
+
* work installs a backend; one that does not never writes a file, and pays
|
|
9
|
+
* nothing for the option. What this buys is that `createAgentRuntime` composes
|
|
10
|
+
* without a workspace plugin at all, so `SubagentRuntime.workspaceBacking` can
|
|
11
|
+
* stay required and a host never writes a null check.
|
|
12
|
+
*
|
|
13
|
+
* Scoped per call, so each execution gets its own map, exactly as a facet's own
|
|
14
|
+
* SQLite would give it its own tables. Contents are lost on isolate eviction —
|
|
15
|
+
* the resumable runner treats a lost workspace as a resumable state everywhere
|
|
16
|
+
* it matters.
|
|
17
|
+
*
|
|
18
|
+
* Signature matches {@link AgentPlugin.workspaceBacking}; both arguments are
|
|
19
|
+
* ignored.
|
|
20
|
+
*/
|
|
21
|
+
export function memoryWorkspaceBacking(_sql, _name) {
|
|
22
|
+
const files = new Map();
|
|
23
|
+
/** Immediate children of `dir`, as `readDir` reports them. */
|
|
24
|
+
const entriesUnder = (dir) => {
|
|
25
|
+
const prefix = dir === "" ? "" : `${dir}/`;
|
|
26
|
+
const seen = new Map();
|
|
27
|
+
for (const [path, content] of files) {
|
|
28
|
+
if (!path.startsWith(prefix))
|
|
29
|
+
continue;
|
|
30
|
+
const rest = path.slice(prefix.length);
|
|
31
|
+
if (rest === "")
|
|
32
|
+
continue;
|
|
33
|
+
const slash = rest.indexOf("/");
|
|
34
|
+
if (slash === -1) {
|
|
35
|
+
seen.set(path, {
|
|
36
|
+
path,
|
|
37
|
+
type: "file",
|
|
38
|
+
size: new TextEncoder().encode(content).length
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
// A directory exists only because something under it does, so report it
|
|
43
|
+
// once and say nothing about its size.
|
|
44
|
+
const child = `${prefix}${rest.slice(0, slash)}`;
|
|
45
|
+
seen.set(child, { path: child, type: "directory", size: 0 });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return [...seen.values()];
|
|
49
|
+
};
|
|
50
|
+
return {
|
|
51
|
+
readFile: async (path) => files.get(normalize(path)) ?? null,
|
|
52
|
+
writeFile: async (path, content) => {
|
|
53
|
+
files.set(normalize(path), content);
|
|
54
|
+
},
|
|
55
|
+
// Directories are implied by their contents, so a path with anything under
|
|
56
|
+
// it exists even though nothing ever created it.
|
|
57
|
+
exists: async (path) => {
|
|
58
|
+
const key = normalize(path);
|
|
59
|
+
return files.has(key) || entriesUnder(key).length > 0;
|
|
60
|
+
},
|
|
61
|
+
deleteFile: async (path) => files.delete(normalize(path)),
|
|
62
|
+
readDir: async (dir) => entriesUnder(normalize(dir ?? "")),
|
|
63
|
+
getWorkspaceInfo: async () => ({ fileCount: files.size })
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/** Strip the leading/trailing slashes that would otherwise key two paths apart. */
|
|
67
|
+
function normalize(path) {
|
|
68
|
+
return path.replace(/^\/+|\/+$/g, "");
|
|
69
|
+
}
|
|
1
70
|
/** Per-file byte ceiling — safely under the 2 MB Durable Object SQLite row limit. */
|
|
2
71
|
export const WORKSPACE_MAX_FILE_BYTES = 512 * 1024;
|
|
3
72
|
/** Max number of files in one workspace — a cheap guard against runaway writes. */
|
|
@@ -23,11 +92,17 @@ export function makeWorkspaceHandle(ws) {
|
|
|
23
92
|
if (bytes > WORKSPACE_MAX_FILE_BYTES) {
|
|
24
93
|
throw new WorkspaceLimitError(`file "${path}" is ${bytes} bytes, over the ${WORKSPACE_MAX_FILE_BYTES}-byte limit`);
|
|
25
94
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
95
|
+
// The cap bounds how many files exist, so it may only refuse a write that
|
|
96
|
+
// *creates* one. `exists` is the wrong question: it is true for a
|
|
97
|
+
// directory too (filesystem semantics, which every real backing has), so
|
|
98
|
+
// at the cap a write to `notes` — with `notes/a.txt` present — read as an
|
|
99
|
+
// overwrite and added a 201st file. `readFile` returning null is the only
|
|
100
|
+
// honest test for "there is no file here", and it runs solely when the
|
|
101
|
+
// workspace is already full, so the ordinary write still costs one call.
|
|
102
|
+
const { fileCount } = await ws.getWorkspaceInfo();
|
|
103
|
+
if (fileCount >= WORKSPACE_MAX_FILES &&
|
|
104
|
+
(await ws.readFile(path)) === null) {
|
|
105
|
+
throw new WorkspaceLimitError(`workspace already holds ${fileCount} files (max ${WORKSPACE_MAX_FILES})`);
|
|
31
106
|
}
|
|
32
107
|
await ws.writeFile(path, content);
|
|
33
108
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/subagent/workspace.ts"],"names":[],"mappings":"AAmDA,qFAAqF;AACrF,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,GAAG,IAAI,CAAC;AACnD,mFAAmF;AACnF,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEvC,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAAoB;IACtD,MAAM,UAAU,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAE7E,OAAO;QACL,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;QAEjC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO;YACvB,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;YAClC,IAAI,KAAK,GAAG,wBAAwB,EAAE,CAAC;gBACrC,MAAM,IAAI,mBAAmB,CAC3B,SAAS,IAAI,QAAQ,KAAK,oBAAoB,wBAAwB,aAAa,CACpF,CAAC;YACJ,CAAC;YACD,
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/subagent/workspace.ts"],"names":[],"mappings":"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"}
|
package/dist/testing/node.d.ts
CHANGED
|
@@ -12,8 +12,31 @@
|
|
|
12
12
|
* ```ts
|
|
13
13
|
* // vitest.config.ts
|
|
14
14
|
* import { createVcrAgent } from "@loopingai/core/testing/node";
|
|
15
|
+
*
|
|
16
|
+
* export default defineConfig({
|
|
17
|
+
* plugins: [cloudflareTest({ miniflare: { fetchMock: createVcrAgent({ … }) } })],
|
|
18
|
+
* test: { globalSetup: ["@loopingai/core/testing/vcr-global-setup"] }
|
|
19
|
+
* });
|
|
15
20
|
* ```
|
|
16
21
|
*
|
|
22
|
+
* ## Two version constraints, both of which fail unreadably
|
|
23
|
+
*
|
|
24
|
+
* **1. `@cloudflare/vitest-pool-workers` must be `^0.18`.** The recorder is
|
|
25
|
+
* installed as Miniflare's `fetchMock`, and that option **does not exist in
|
|
26
|
+
* Miniflare 5**, which pool `0.19`+ depends on — only `outboundService` remains.
|
|
27
|
+
* On a newer pool the option is silently ignored rather than rejected, so
|
|
28
|
+
* `disableNetConnect()` never takes effect, every request goes to the real
|
|
29
|
+
* network, and each one fails as `internal error; reference = …` naming nothing.
|
|
30
|
+
* That is why the peer range is pinned rather than open.
|
|
31
|
+
*
|
|
32
|
+
* **2. Your `undici` must be the copy Miniflare uses.** `fetchMock` is an undici
|
|
33
|
+
* `MockAgent` and Miniflare validates it against *its own* undici, so two copies
|
|
34
|
+
* in one `node_modules` fail with `Input not instance of MockAgent`. Miniflare
|
|
35
|
+
* pins an exact version (7.28.0 at the time of writing) and this package's
|
|
36
|
+
* `undici` peer range tracks it. Check with
|
|
37
|
+
* `ls node_modules/miniflare/node_modules/undici` — anything there means a
|
|
38
|
+
* second copy, and the fix is to align yours rather than to debug the message.
|
|
39
|
+
*
|
|
17
40
|
* For the common case — wiring cassette flush/teardown — you do not need this
|
|
18
41
|
* subpath at all. Point `globalSetup` at
|
|
19
42
|
* `@loopingai/core/testing/vcr-global-setup`, which is this module's `setup`/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/testing/node.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/testing/node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,EACL,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,KAAK,qBAAqB,EAC3B,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/testing/node.js
CHANGED
|
@@ -12,8 +12,31 @@
|
|
|
12
12
|
* ```ts
|
|
13
13
|
* // vitest.config.ts
|
|
14
14
|
* import { createVcrAgent } from "@loopingai/core/testing/node";
|
|
15
|
+
*
|
|
16
|
+
* export default defineConfig({
|
|
17
|
+
* plugins: [cloudflareTest({ miniflare: { fetchMock: createVcrAgent({ … }) } })],
|
|
18
|
+
* test: { globalSetup: ["@loopingai/core/testing/vcr-global-setup"] }
|
|
19
|
+
* });
|
|
15
20
|
* ```
|
|
16
21
|
*
|
|
22
|
+
* ## Two version constraints, both of which fail unreadably
|
|
23
|
+
*
|
|
24
|
+
* **1. `@cloudflare/vitest-pool-workers` must be `^0.18`.** The recorder is
|
|
25
|
+
* installed as Miniflare's `fetchMock`, and that option **does not exist in
|
|
26
|
+
* Miniflare 5**, which pool `0.19`+ depends on — only `outboundService` remains.
|
|
27
|
+
* On a newer pool the option is silently ignored rather than rejected, so
|
|
28
|
+
* `disableNetConnect()` never takes effect, every request goes to the real
|
|
29
|
+
* network, and each one fails as `internal error; reference = …` naming nothing.
|
|
30
|
+
* That is why the peer range is pinned rather than open.
|
|
31
|
+
*
|
|
32
|
+
* **2. Your `undici` must be the copy Miniflare uses.** `fetchMock` is an undici
|
|
33
|
+
* `MockAgent` and Miniflare validates it against *its own* undici, so two copies
|
|
34
|
+
* in one `node_modules` fail with `Input not instance of MockAgent`. Miniflare
|
|
35
|
+
* pins an exact version (7.28.0 at the time of writing) and this package's
|
|
36
|
+
* `undici` peer range tracks it. Check with
|
|
37
|
+
* `ls node_modules/miniflare/node_modules/undici` — anything there means a
|
|
38
|
+
* second copy, and the fix is to align yours rather than to debug the message.
|
|
39
|
+
*
|
|
17
40
|
* For the common case — wiring cassette flush/teardown — you do not need this
|
|
18
41
|
* subpath at all. Point `globalSetup` at
|
|
19
42
|
* `@loopingai/core/testing/vcr-global-setup`, which is this module's `setup`/
|
package/dist/testing/node.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/testing/node.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/testing/node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,EACL,cAAc,EACd,QAAQ,EACR,QAAQ,EAET,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { RunnerTestCase } from "vitest";
|
|
2
2
|
/**
|
|
3
|
-
* Cassette filename for a test: `kebab(<
|
|
4
|
-
* then each describe level then the test name, all kebab-cased and
|
|
5
|
-
* `--`, plus `.snapshot.json`. Example:
|
|
6
|
-
* `
|
|
3
|
+
* Cassette filename for a test: `kebab(<project-relative path, minus
|
|
4
|
+
* .spec.ts>)` then each describe level then the test name, all kebab-cased and
|
|
5
|
+
* joined by `--`, plus `.snapshot.json`. Example:
|
|
6
|
+
* `test-arc-agi-recorded--arc-recorded-real-api--plays-a-real-game.snapshot.json`.
|
|
7
7
|
* Exported for debugging / the cassette-rename step.
|
|
8
8
|
*/
|
|
9
9
|
export declare function cassetteNameFor(task: RunnerTestCase): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vcr-spec.d.ts","sourceRoot":"","sources":["../../src/testing/vcr-spec.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAmB,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"vcr-spec.d.ts","sourceRoot":"","sources":["../../src/testing/vcr-spec.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAmB,MAAM,QAAQ,CAAC;AAkD9D;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAW5D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,IAAI,CA8BrC"}
|
package/dist/testing/vcr-spec.js
CHANGED
|
@@ -20,17 +20,38 @@ function isFileTask(suite) {
|
|
|
20
20
|
return typeof suite.filepath === "string";
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
23
|
+
* The spec's path relative to the project root.
|
|
24
|
+
*
|
|
25
|
+
* Vitest already computes this as `file.name`, which is the whole answer: it is
|
|
26
|
+
* stable across machines and checkouts, and it is *unique per spec file*, which
|
|
27
|
+
* is what a cassette name has to be.
|
|
28
|
+
*
|
|
29
|
+
* Deriving it from `filepath` instead — by stripping a leading `test/` or
|
|
30
|
+
* `src/` — got this wrong twice. Splitting on a segment that never matched
|
|
31
|
+
* returned the absolute path unchanged, so a cassette was named after the
|
|
32
|
+
* developer's home directory; and stripping *both* roots collapsed
|
|
33
|
+
* `test/api.spec.ts` and `src/api.spec.ts` onto one name, which for a store
|
|
34
|
+
* keyed solely by filename means one recording silently overwrites the other
|
|
35
|
+
* and playback serves the wrong responses.
|
|
36
|
+
*
|
|
37
|
+
* The fallback is only for a runner that does not populate `name`; a bare
|
|
38
|
+
* filename can still collide, but it is strictly better than an absolute path
|
|
39
|
+
* and nothing here reaches it.
|
|
40
|
+
*/
|
|
41
|
+
function relativeSpecPath(file) {
|
|
42
|
+
if (typeof file.name === "string" && file.name !== "")
|
|
43
|
+
return file.name;
|
|
44
|
+
return file.filepath.replace(/\\/g, "/").split("/").pop();
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Cassette filename for a test: `kebab(<project-relative path, minus
|
|
48
|
+
* .spec.ts>)` then each describe level then the test name, all kebab-cased and
|
|
49
|
+
* joined by `--`, plus `.snapshot.json`. Example:
|
|
50
|
+
* `test-arc-agi-recorded--arc-recorded-real-api--plays-a-real-game.snapshot.json`.
|
|
27
51
|
* Exported for debugging / the cassette-rename step.
|
|
28
52
|
*/
|
|
29
53
|
export function cassetteNameFor(task) {
|
|
30
|
-
const rel = task.file.
|
|
31
|
-
.split(/[\\/]test[\\/]/)
|
|
32
|
-
.pop()
|
|
33
|
-
.replace(/\.spec\.ts$/, "");
|
|
54
|
+
const rel = relativeSpecPath(task.file).replace(/\.spec\.ts$/, "");
|
|
34
55
|
const suites = [];
|
|
35
56
|
let suite = task.suite;
|
|
36
57
|
while (suite && !isFileTask(suite)) {
|
|
@@ -52,9 +73,9 @@ export function setupRecording() {
|
|
|
52
73
|
method: "POST"
|
|
53
74
|
});
|
|
54
75
|
if (res.status === 404) {
|
|
55
|
-
throw new Error(`No VCR cassette "${cassette}". Record it with \`
|
|
56
|
-
`(add
|
|
57
|
-
`
|
|
76
|
+
throw new Error(`No VCR cassette "${cassette}". Record it with \`RECORD=1\` ` +
|
|
77
|
+
`(add \`-t "${ctx.task.name}"\` to record only this test), which needs ` +
|
|
78
|
+
`whatever real credentials the recorded API calls require.`);
|
|
58
79
|
}
|
|
59
80
|
if (res.status === 409) {
|
|
60
81
|
throw new Error(`VCR cassette "${cassette}" could not activate: another recorded test is ` +
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vcr-spec.js","sourceRoot":"","sources":["../../src/testing/vcr-spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAE/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD;;;;;;;;;;GAUG;AAEH,MAAM,KAAK,GAAG,CAAC,CAAS,EAAU,EAAE,CAClC,CAAC;KACE,WAAW,EAAE;KACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;KAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAE7B,kFAAkF;AAClF,SAAS,UAAU,CAAC,KAAsB;IACxC,OAAO,OAAQ,KAA+B,CAAC,QAAQ,KAAK,QAAQ,CAAC;AACvE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,IAAoB;IAClD,MAAM,GAAG,GAAG,
|
|
1
|
+
{"version":3,"file":"vcr-spec.js","sourceRoot":"","sources":["../../src/testing/vcr-spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAE/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD;;;;;;;;;;GAUG;AAEH,MAAM,KAAK,GAAG,CAAC,CAAS,EAAU,EAAE,CAClC,CAAC;KACE,WAAW,EAAE;KACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;KAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAE7B,kFAAkF;AAClF,SAAS,UAAU,CAAC,KAAsB;IACxC,OAAO,OAAQ,KAA+B,CAAC,QAAQ,KAAK,QAAQ,CAAC;AACvE,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAS,gBAAgB,CAAC,IAA4B;IACpD,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IACxE,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAG,CAAC;AAC7D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,IAAoB;IAClD,MAAM,GAAG,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IAEnE,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,GAAgC,IAAI,CAAC,KAAK,CAAC;IACpD,OAAO,KAAK,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACnC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IACtB,CAAC;IAED,OAAO,CAAC,GAAG,EAAE,GAAG,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC;AAC9E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc;IAC5B,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACvB,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,kBAAkB,iBAAiB,QAAQ,EAAE,EAAE;YACxE,MAAM,EAAE,MAAM;SACf,CAAC,CAAC;QACH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CACb,oBAAoB,QAAQ,iCAAiC;gBAC3D,cAAc,GAAG,CAAC,IAAI,CAAC,IAAI,6CAA6C;gBACxE,2DAA2D,CAC9D,CAAC;QACJ,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CACb,iBAAiB,QAAQ,iDAAiD;gBACxE,iEAAiE;gBACjE,kCAAkC,CACrC,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,mCAAmC,GAAG,CAAC,MAAM,iBAAiB,QAAQ,IAAI,CAC3E,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,KAAK,CAAC,GAAG,kBAAkB,UAAU,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loopingai/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Shared, mandatory foundation for Looping agents on Cloudflare Workers: zero-trust A2A, durable task lifecycle, delegation and subagent runtime, test harness.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"a2a",
|
|
@@ -102,13 +102,17 @@
|
|
|
102
102
|
"zod": "^4.4.3"
|
|
103
103
|
},
|
|
104
104
|
"peerDependencies": {
|
|
105
|
+
"@cloudflare/vitest-pool-workers": "^0.18.8",
|
|
105
106
|
"agents": "^0.20.0",
|
|
106
107
|
"ai": "^7.0.40",
|
|
107
|
-
"undici": "
|
|
108
|
+
"undici": "^7.28.0",
|
|
108
109
|
"vitest": ">=4",
|
|
109
110
|
"workers-ai-provider": "^4.0.0"
|
|
110
111
|
},
|
|
111
112
|
"peerDependenciesMeta": {
|
|
113
|
+
"@cloudflare/vitest-pool-workers": {
|
|
114
|
+
"optional": true
|
|
115
|
+
},
|
|
112
116
|
"undici": {
|
|
113
117
|
"optional": true
|
|
114
118
|
},
|
|
@@ -117,7 +121,7 @@
|
|
|
117
121
|
}
|
|
118
122
|
},
|
|
119
123
|
"devDependencies": {
|
|
120
|
-
"@cloudflare/vitest-pool-workers": "^0.
|
|
124
|
+
"@cloudflare/vitest-pool-workers": "^0.18.8",
|
|
121
125
|
"@types/node": "^26.1.1",
|
|
122
126
|
"agents": "^0.20.0",
|
|
123
127
|
"ai": "^7.0.40",
|
|
@@ -126,7 +130,7 @@
|
|
|
126
130
|
"prettier": "^3.9.6",
|
|
127
131
|
"typescript": "^6.0.3",
|
|
128
132
|
"typescript-eslint": "^8.65.0",
|
|
129
|
-
"undici": "
|
|
133
|
+
"undici": "7.28.0",
|
|
130
134
|
"vitest": "^4.1.10",
|
|
131
135
|
"workers-ai-provider": "^4.0.0",
|
|
132
136
|
"wrangler": "^4.114.0"
|