@swirls/looms 0.4.0 → 0.5.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/CHANGELOG.md +61 -0
- package/dist/actor/cell.d.ts +21 -2
- package/dist/actor/cell.js +15 -3
- package/dist/actor/host.d.ts +10 -2
- package/dist/actor/host.js +27 -4
- package/dist/actor/index.d.ts +2 -1
- package/dist/actor/index.js +1 -1
- package/dist/actor/routing.d.ts +3 -0
- package/dist/actor/routing.js +13 -2
- package/dist/agent/definitions-store.d.ts +1 -1
- package/dist/agent/definitions-store.js +1 -1
- package/dist/agent/definitions.d.ts +48 -0
- package/dist/agent/definitions.js +44 -0
- package/dist/agent/effects.d.ts +184 -0
- package/dist/agent/effects.js +172 -40
- package/dist/agent/events.d.ts +89 -0
- package/dist/agent/events.js +25 -0
- package/dist/agent/module.d.ts +412 -0
- package/dist/agent/module.js +5 -1
- package/dist/agent/scope.d.ts +88 -0
- package/dist/agent/threads.js +39 -3
- package/dist/agent/types.d.ts +4 -0
- package/dist/approval/effects.d.ts +40 -0
- package/dist/approval/module.d.ts +80 -0
- package/dist/client/client.d.ts +468 -119
- package/dist/client/client.js +214 -21
- package/dist/client/index.d.ts +1 -1
- package/dist/client/sse.d.ts +1 -1
- package/dist/client/sse.js +2 -2
- package/dist/cloudflare/durable-object.d.ts +66 -2
- package/dist/cloudflare/durable-object.js +96 -1
- package/dist/cloudflare/event-store.d.ts +7 -3
- package/dist/cloudflare/event-store.js +16 -3
- package/dist/cloudflare/index.d.ts +7 -1
- package/dist/cloudflare/index.js +7 -1
- package/dist/cloudflare/memory-queue.d.ts +18 -0
- package/dist/cloudflare/memory-queue.js +53 -0
- package/dist/cloudflare/queue-consumer.d.ts +52 -0
- package/dist/cloudflare/queue-consumer.js +102 -0
- package/dist/cloudflare/queue-message.d.ts +31 -0
- package/dist/cloudflare/queue-message.js +33 -0
- package/dist/cloudflare/queue-pull.d.ts +62 -0
- package/dist/cloudflare/queue-pull.js +130 -0
- package/dist/cloudflare/queue-worker.d.ts +39 -0
- package/dist/cloudflare/queue-worker.js +62 -0
- package/dist/cloudflare/queues.d.ts +10 -0
- package/dist/cloudflare/queues.js +10 -0
- package/dist/cloudflare/r2-blob-store.d.ts +33 -0
- package/dist/cloudflare/r2-blob-store.js +60 -0
- package/dist/cloudflare/router.d.ts +4 -1
- package/dist/cloudflare/router.js +8 -3
- package/dist/cloudflare/websocket.d.ts +27 -0
- package/dist/cloudflare/websocket.js +215 -0
- package/dist/core/blob-offload.d.ts +21 -0
- package/dist/core/blob-offload.js +143 -0
- package/dist/core/blob-store.d.ts +45 -0
- package/dist/core/blob-store.js +164 -0
- package/dist/core/blobs.d.ts +37 -0
- package/dist/core/blobs.js +160 -0
- package/dist/core/definition-resolver.d.ts +40 -0
- package/dist/core/definition-resolver.js +129 -0
- package/dist/core/definition-store.d.ts +6 -0
- package/dist/core/definition-store.js +37 -1
- package/dist/core/effects.d.ts +86 -3
- package/dist/core/effects.js +99 -3
- package/dist/core/envelope.d.ts +9 -0
- package/dist/core/envelope.js +4 -0
- package/dist/core/event-codec.js +3 -0
- package/dist/core/fold.js +83 -1
- package/dist/core/ids.d.ts +2 -0
- package/dist/core/ids.js +4 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/index.js +8 -0
- package/dist/core/launcher.d.ts +97 -0
- package/dist/core/launcher.js +67 -0
- package/dist/core/module-scope.d.ts +7 -3
- package/dist/core/module-scope.js +3 -0
- package/dist/core/module.d.ts +10 -0
- package/dist/core/projection.js +4 -0
- package/dist/core/protocol.d.ts +36 -1
- package/dist/core/protocol.js +35 -0
- package/dist/core/published.d.ts +2 -0
- package/dist/core/published.js +4 -1
- package/dist/core/replay.d.ts +96 -0
- package/dist/core/run-context.d.ts +33 -0
- package/dist/core/run-context.js +23 -0
- package/dist/core/sqlite-store.js +57 -5
- package/dist/core/state.d.ts +60 -0
- package/dist/core/state.js +19 -0
- package/dist/core/store.d.ts +6 -0
- package/dist/core/store.js +7 -0
- package/dist/core/subscription.d.ts +97 -0
- package/dist/core/subscription.js +224 -0
- package/dist/core/thread.d.ts +7 -0
- package/dist/core/thread.js +1 -0
- package/dist/core/trace.d.ts +21 -0
- package/dist/core/trace.js +45 -0
- package/dist/core/worker-callback.d.ts +25 -1
- package/dist/debugger/app/assets/{index-CgDzWJg7.css → index-B7GdT1UA.css} +1 -1
- package/dist/debugger/app/assets/index-C31SnCuN.js +22 -0
- package/dist/debugger/app/assets/routes-DPA3O5AF.js +47 -0
- package/dist/debugger/app/index.html +2 -2
- package/dist/debugger/components/event-inspector.d.ts +3 -1
- package/dist/debugger/components/event-inspector.js +25 -4
- package/dist/debugger/components/event-stream.d.ts +4 -1
- package/dist/debugger/components/event-stream.js +2 -2
- package/dist/debugger/components/run-tree.d.ts +5 -2
- package/dist/debugger/components/run-tree.js +10 -4
- package/dist/debugger/context.d.ts +8 -1
- package/dist/debugger/context.js +15 -3
- package/dist/debugger/events/protocol-summarize.js +18 -3
- package/dist/debugger/index.d.ts +1 -1
- package/dist/debugger/index.js +1 -1
- package/dist/debugger/shell/debugger-shell.js +1 -1
- package/dist/debugger/shell/events-pane.js +4 -3
- package/dist/debugger/styles.css +1 -0
- package/dist/evaluator/definitions-store.d.ts +3 -4
- package/dist/evaluator/definitions-store.js +3 -3
- package/dist/evaluator/definitions.d.ts +4 -1
- package/dist/evaluator/definitions.js +5 -2
- package/dist/evaluator/effects.d.ts +41 -0
- package/dist/evaluator/effects.js +6 -2
- package/dist/evaluator/module.d.ts +84 -0
- package/dist/evaluator/module.js +7 -3
- package/dist/evaluator/threads.d.ts +2 -0
- package/dist/evaluator/threads.js +4 -0
- package/dist/projectors/event-log.d.ts +87 -0
- package/dist/projectors/event-log.js +396 -0
- package/dist/projectors/index-model.d.ts +12 -0
- package/dist/projectors/index-model.js +12 -3
- package/dist/projectors/memory.js +7 -0
- package/dist/projectors/postgres.d.ts +1 -0
- package/dist/projectors/postgres.js +32 -15
- package/dist/projectors/schema.d.ts +5 -0
- package/dist/projectors/schema.js +26 -1
- package/dist/projectors/sqlite.js +47 -19
- package/dist/projectors/with-projectors.d.ts +7 -1
- package/dist/projectors/with-projectors.js +13 -3
- package/dist/react/materialize.js +5 -1
- package/dist/react/react.d.ts +10 -2
- package/dist/react/react.js +43 -19
- package/dist/react/store.d.ts +11 -2
- package/dist/react/store.js +104 -12
- package/dist/react/tables.d.ts +4 -1
- package/dist/runtime/cancellation.d.ts +2 -1
- package/dist/runtime/cancellation.js +35 -2
- package/dist/runtime/child-run.d.ts +10 -0
- package/dist/runtime/child-run.js +58 -0
- package/dist/runtime/deadline-transition-planner.js +11 -2
- package/dist/runtime/dispatch-effect.d.ts +2 -2
- package/dist/runtime/dispatch-effect.js +43 -19
- package/dist/runtime/errors.d.ts +14 -1
- package/dist/runtime/errors.js +10 -0
- package/dist/runtime/filesystem-blob-store.d.ts +6 -0
- package/dist/runtime/filesystem-blob-store.js +59 -0
- package/dist/runtime/helpers.d.ts +15 -6
- package/dist/runtime/helpers.js +46 -6
- package/dist/runtime/index.d.ts +4 -2
- package/dist/runtime/index.js +3 -1
- package/dist/runtime/local-effect-executor.d.ts +11 -2
- package/dist/runtime/local-effect-executor.js +80 -4
- package/dist/runtime/looms.d.ts +38 -4
- package/dist/runtime/looms.js +17 -3
- package/dist/runtime/repository.d.ts +5 -4
- package/dist/runtime/repository.js +5 -2
- package/dist/runtime/retry-policy.d.ts +5 -0
- package/dist/runtime/retry-policy.js +10 -2
- package/dist/runtime/run-start.d.ts +1 -1
- package/dist/runtime/run-start.js +10 -0
- package/dist/runtime/runtime.d.ts +2 -2
- package/dist/runtime/runtime.js +191 -68
- package/dist/runtime/server/auth.d.ts +3 -0
- package/dist/runtime/server/fetch-handler.d.ts +2 -2
- package/dist/runtime/server/fetch-handler.js +35 -4
- package/dist/runtime/server/grant.d.ts +49 -0
- package/dist/runtime/server/grant.js +177 -0
- package/dist/runtime/server/routes/effects.js +47 -5
- package/dist/runtime/server/routes/runs.js +6 -1
- package/dist/runtime/server/run-route.d.ts +18 -0
- package/dist/runtime/server/run-route.js +26 -0
- package/dist/runtime/server.d.ts +3 -1
- package/dist/runtime/server.js +3 -1
- package/dist/runtime/sse.js +26 -4
- package/dist/runtime/subscription.d.ts +8 -0
- package/dist/runtime/subscription.js +23 -0
- package/dist/runtime/types.d.ts +87 -8
- package/dist/runtime/wake-engine.d.ts +4 -2
- package/dist/runtime/wake-engine.js +57 -6
- package/dist/runtime/worker-callbacks.d.ts +12 -2
- package/dist/runtime/worker-callbacks.js +102 -72
- package/dist/runtime/worker-effect-dispatch.d.ts +14 -5
- package/dist/runtime/worker-effect-dispatch.js +84 -18
- package/dist/schedule/debugger/index.d.ts +4 -0
- package/dist/schedule/debugger/index.js +11 -0
- package/dist/schedule/debugger/schedule-view.d.ts +3 -0
- package/dist/schedule/debugger/schedule-view.js +68 -0
- package/dist/schedule/debugger/summarize.d.ts +2 -0
- package/dist/schedule/debugger/summarize.js +43 -0
- package/dist/schedule/definitions-store.d.ts +10 -0
- package/dist/schedule/definitions-store.js +8 -0
- package/dist/schedule/definitions.d.ts +57 -0
- package/dist/schedule/definitions.js +30 -0
- package/dist/schedule/effects.d.ts +756 -0
- package/dist/schedule/effects.js +244 -0
- package/dist/schedule/ensure.d.ts +55 -0
- package/dist/schedule/ensure.js +109 -0
- package/dist/schedule/events.d.ts +116 -0
- package/dist/schedule/events.js +49 -0
- package/dist/schedule/index.d.ts +11 -0
- package/dist/schedule/index.js +11 -0
- package/dist/schedule/module.d.ts +1474 -0
- package/dist/schedule/module.js +22 -0
- package/dist/schedule/projections.d.ts +55 -0
- package/dist/schedule/projections.js +88 -0
- package/dist/schedule/scope.d.ts +121 -0
- package/dist/schedule/scope.js +7 -0
- package/dist/schedule/signals.d.ts +25 -0
- package/dist/schedule/signals.js +33 -0
- package/dist/schedule/specs.d.ts +59 -0
- package/dist/schedule/specs.js +231 -0
- package/dist/schedule/threads.d.ts +25 -0
- package/dist/schedule/threads.js +259 -0
- package/dist/testing/corpus-module.d.ts +34 -0
- package/dist/testing/corpus-module.js +87 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.js +5 -6
- package/dist/testing/replay-corpus.d.ts +22 -0
- package/dist/testing/replay-corpus.js +50 -0
- package/dist/workflow/definitions-store.d.ts +1 -1
- package/dist/workflow/definitions-store.js +1 -1
- package/dist/workflow/definitions.d.ts +14 -0
- package/dist/workflow/effects.d.ts +122 -0
- package/dist/workflow/effects.js +16 -6
- package/dist/workflow/events.d.ts +42 -0
- package/dist/workflow/events.js +4 -0
- package/dist/workflow/module.d.ts +313 -0
- package/dist/workflow/module.js +7 -3
- package/dist/workflow/scope.d.ts +42 -0
- package/dist/workflow/threads.d.ts +72 -0
- package/dist/workflow/threads.js +106 -38
- package/package.json +14 -1
- package/dist/debugger/app/assets/index-D--9esm9.js +0 -22
- package/dist/debugger/app/assets/routes-Dakrdusf.js +0 -47
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,66 @@
|
|
|
1
1
|
# @swirls/looms
|
|
2
2
|
|
|
3
|
+
## 0.5.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 86280a0: Export `@swirls/looms/cloudflare/queues` so Bun/Node pull consumers can load queue helpers without importing `cloudflare:workers`.
|
|
8
|
+
|
|
9
|
+
## 0.5.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- edd3c5c: Agents gain structured output through a `submit_output` tool, one compaction-and-retry when the model reports a context overflow, `resolveTools` for tools that depend on the agent input, an `assertCredits` gate before each model call, and `trackUsage` beside a new `agent.turn.usage` event. Team members spawned with `asAgentTool` stop at `TEAM_MEMBER_MAX_DEPTH` (3); the parent sends the child its depth with a new `agent.lineage` event.
|
|
14
|
+
- 0ac83ab: `createLooms({ blobStore })` and `LoomsDurableObject` `blobs` store strings over 64 KiB by SHA-256 and keep a reference in the event or snapshot. A payload that is still over the 1 MiB event limit is stored as one blob. Reads, subscribers, folds, projections, and snapshot loads resolve the reference, so a run can complete with a payload larger than that limit. Trim removes a blob body once nothing retained still points at it. `memoryBlobStore`, `filesystemBlobStore`, and `r2BlobStore` are the included stores. Without a blob store, events over 1 MiB and snapshots over 8 MiB are still rejected.
|
|
15
|
+
- 0ac83ab: feat(runtime)!: launch workflow children as their own runs
|
|
16
|
+
|
|
17
|
+
A workflow can set `childExecution: 'run'` so spawn, map, fanout, and loop start a child run instead of a thread. The child run id is stable across retries. When the child finishes it signals `runtime.child.settled`, which completes the parent's wait. `childClose` is `terminate` or `wait`. The default remains in-process threads.
|
|
18
|
+
|
|
19
|
+
BREAKING CHANGE: `RunLauncher` implementations must provide `signal` and `cancel`.
|
|
20
|
+
|
|
21
|
+
- 0ac83ab: Definitions can be loaded at start, spawn, and recovery through `definitionResolver`, with registered definitions checked first and an LRU cache in front. A missing definition fails the start before any event is written, and the accepted version stays pinned on the run. Evaluator definitions now include `version`, defaulting to `v1`, and lookup takes the name and version.
|
|
22
|
+
|
|
23
|
+
BREAKING CHANGE: `EvaluatorDefinition` requires `version`, and evaluator lookup is `(name, version)` instead of `(name)`. `defineEvaluator` still defaults the version to `v1`.
|
|
24
|
+
|
|
25
|
+
- 2436516: Worker callbacks now answer `{ status: 'accepted' | 'stale' | 'cancelled', cancelRequested }` instead of the run state. `createLooms().workerCallback` and `createLoomsClient().workerCallback` return that result. `cancelRequested` tells an attempt that is already running to stop, because a dispatch that has left the host cannot be recalled. A stale report records nothing.
|
|
26
|
+
|
|
27
|
+
`failEffect({ error, nonRetryable, retryAfterMs })` fails the current attempt. `nonRetryable` ends the effect even when the retry policy has attempts left. `retryAfterMs` waits at least that long before the next attempt and never shortens the policy backoff. Worker `fail` callbacks take the same two fields.
|
|
28
|
+
|
|
29
|
+
A heartbeat may include `details`. The latest details are kept across retries and included on the next `EffectWorkerTask`, so a resumed attempt can continue from the recorded progress.
|
|
30
|
+
|
|
31
|
+
- 0ac83ab: Durable Objects accept a hibernating WebSocket on `GET /runs/:id/events`. The socket replays the retained log, then receives later events without a subscription held in memory. SSE sends the same `hello` and `resync` frames. A cursor below the retained head is told to resume from `head` instead of silently skipping trimmed events. `subscribeEvents` and the React store take `transport: "websocket" | "sse" | "auto"`; the default remains SSE, and a numeric reconnect delay still works.
|
|
32
|
+
- c01d046: A run started from an effect through `RunLauncher` now records its source on `runtime.run.started`. The payload's `launchedBy` holds the launching run, thread, and effect, plus the id and seq of the event that requested the effect. The event's origin is `{ type: 'run', runId }`, and its `correlationId` names the root run of the launch chain. The runtime sets these fields itself and replaces any value a handler passes. `RunState.startIdentity` exposes both fields, and a later start of the same run id that does not match them rejects with `StartRunConflictError`.
|
|
33
|
+
|
|
34
|
+
The launching run's log gets a new `runtime.run.launched` event for each start the target accepts. It carries the started run's id and definition plus the effect id, so listing what a run launched reads that run's log alone.
|
|
35
|
+
|
|
36
|
+
The index projectors store `launchedByRunId`, `launchedByEffectId`, and `correlationId` on run rows, and `listLaunched(runId)` returns the runs a run launched. Their version is now 3, so delivery replays history to fill the new columns, and `init` adds the columns to existing SQLite and Postgres tables.
|
|
37
|
+
|
|
38
|
+
`useRunSummary` returns `launchedBy`. The debugger shows a Launched by link above the thread tree that opens the launching run at the requesting event, the event inspector links `runtime.run.launched` and `runtime.run.started` to the run on the other side, and `openRun` accepts a `{ seq }` target.
|
|
39
|
+
|
|
40
|
+
- 0ac83ab: Runs carry the caller's W3C trace context. `POST /runs` reads the `traceparent` and `tracestate` headers, and `start`, `startRun`, and `client.startRun` accept `trace`. A valid context is recorded on `runtime.run.started` and `startIdentity.trace`, then passed unchanged to effect handlers (`ctx.trace`), worker tasks (`task.trace`), and every launched or child run unless the launch sets its own.
|
|
41
|
+
- a1fa2c3: feat(projectors): project runs into a Postgres event log without blocking append
|
|
42
|
+
|
|
43
|
+
Durable Object projectors are scheduled with `waitUntil` after the log commits. `postgresEventLog` stores each non-ephemeral envelope and a run index with status, launch links, and tenant attributes, and can rebuild that sink from the log.
|
|
44
|
+
|
|
45
|
+
- 0ac83ab: feat(cloudflare): run worker effects over Cloudflare Queues
|
|
46
|
+
|
|
47
|
+
`cloudflareQueueWorker` sends each attempt to a queue as JSON, with the run's trace context and the attempt's deadlines; inputs over 100 KB travel as a blob reference and secrets stay off the queue. `queueConsumer` (push) and `createQueuePullConsumer` with `cloudflareQueuePullSource` (HTTP pull) run handlers that heartbeat, read secrets through the worker callback API, and stop when the run is cancelled. The consumer acks after `started`, so Looms owns retries; duplicate and stale deliveries are dropped, and dead-lettered messages are recovered by the schedule-to-start timeout. The pull consumer batches acks, backs off when idle, reports the backlog, and drains on `stop()`. `createMemoryQueue` gives tests the same lease and dead-letter behavior.
|
|
48
|
+
|
|
49
|
+
In the runtime, `EffectWorker.dispatchSemantics: 'acknowledged'` fails a rejected dispatch under the retry policy instead of parking it as ambiguous, and creating a runtime fails if such a worker claims an effect without `retry.scheduleToStartTimeoutMs`. Worker tasks carry `deadlines`, and `maxInFlightWorkerEffects` caps the worker attempts one run has in flight.
|
|
50
|
+
|
|
51
|
+
- 0ac83ab: Runs accept immutable `attributes` and a `secrets` context. Attributes are recorded on `runtime.run.started`, the run state, and the run summary, and are passed to `authorize` when present. Secrets stay in a side store: they are available to effect handlers and in-process worker dispatch, and they are not written to events, snapshots, or run responses. A worker whose transport persists tasks reads them with `POST /runs/:runId/effects/:effectId/:attempt/secrets` (`client.workerSecrets`), which only answers the attempt that is currently running.
|
|
52
|
+
- 0ac83ab: feat(runtime): authorize browser event streams with a signed run grant
|
|
53
|
+
|
|
54
|
+
`grantAuth` checks a short-lived HMAC grant from the `grant` query parameter or a `v1.` WebSocket subprotocol. The grant allows one principal to read one run, which is the credential a browser can send on EventSource or WebSocket. The Durable Object socket echoes a subprotocol grant on the upgrade, and `grantSubprotocol` gives other hosts the value to echo.
|
|
55
|
+
|
|
56
|
+
- c01d046: Add a schedule module so a cron, interval, or one-shot time can start a run, and so a deploy can update, pause, or retire that schedule without a new run id.
|
|
57
|
+
- 0ac83ab: feat(testing): replay recorded run logs in CI and document effect contracts
|
|
58
|
+
|
|
59
|
+
Adds a production-shaped event-log corpus under `packages/testing/corpus`, folded
|
|
60
|
+
deterministically in CI with `assertCorpusEntry`. Documents versioning effect
|
|
61
|
+
types (`payments.charge@v2`) and worker `handles` so fleets can roll out beside
|
|
62
|
+
each other without Temporal-style patches.
|
|
63
|
+
|
|
3
64
|
## 0.4.0
|
|
4
65
|
|
|
5
66
|
### Minor Changes
|
package/dist/actor/cell.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { type AnyRuntimeModule, type EventStore, type EventStoreTrimCoverage, type RunState, type SnapshotStore } from '@swirls/looms/core';
|
|
2
|
-
import { type Authorize, type LoomsRuntime, type WakeScheduler } from '@swirls/looms/runtime';
|
|
1
|
+
import { type AnyRuntimeModule, type DefinitionResolver, type EventInput, type EventStore, type EventStoreTrimCoverage, type LaunchRunArgs, type RunLauncher, type RunState, type RunStatusSnapshot, type SnapshotStore } from '@swirls/looms/core';
|
|
2
|
+
import { type Authorize, type LoomsRuntime, type StartResult, type StartRunArgs, type WakeScheduler } from '@swirls/looms/runtime';
|
|
3
3
|
export interface ActorCellOptions<TModules extends readonly AnyRuntimeModule[] = readonly AnyRuntimeModule[]> {
|
|
4
4
|
readonly runId: string;
|
|
5
5
|
readonly store: EventStore;
|
|
6
6
|
readonly scheduler?: WakeScheduler;
|
|
7
7
|
readonly modules: TModules;
|
|
8
|
+
/** Loads definitions that were not registered on a module. See `CreateRuntimeOptions`. */
|
|
9
|
+
readonly definitionResolver?: DefinitionResolver;
|
|
8
10
|
readonly snapshotEvery?: number;
|
|
9
11
|
readonly maxWakeIterations?: number;
|
|
10
12
|
readonly maxPendingRunOperations?: number;
|
|
@@ -15,6 +17,8 @@ export interface ActorCellOptions<TModules extends readonly AnyRuntimeModule[] =
|
|
|
15
17
|
};
|
|
16
18
|
/** Authorizes the cell's HTTP API; see `createFetchHandler`. */
|
|
17
19
|
readonly authorize?: Authorize;
|
|
20
|
+
/** Starts runs from effect handlers. Required for schedules; there is no default inside a cell. */
|
|
21
|
+
readonly launcher?: RunLauncher;
|
|
18
22
|
}
|
|
19
23
|
export interface ActorCell<TModules extends readonly AnyRuntimeModule[] = readonly AnyRuntimeModule[]> {
|
|
20
24
|
readonly runId: string;
|
|
@@ -24,6 +28,21 @@ export interface ActorCell<TModules extends readonly AnyRuntimeModule[] = readon
|
|
|
24
28
|
wake(): Promise<RunState>;
|
|
25
29
|
recoverWake(): Promise<number>;
|
|
26
30
|
dispose(): Promise<void>;
|
|
31
|
+
/** Commit this cell's run and schedule a wake. A conflicting restart is a no-op. */
|
|
32
|
+
launch(args: LaunchRunArgs): Promise<void>;
|
|
33
|
+
status(): Promise<RunStatusSnapshot | null>;
|
|
34
|
+
startRun(args: StartRunArgs): Promise<StartResult>;
|
|
35
|
+
signal(events: ReadonlyArray<EventInput>, options?: {
|
|
36
|
+
idempotencyKey?: string;
|
|
37
|
+
coalesce?: boolean;
|
|
38
|
+
}): Promise<RunState>;
|
|
39
|
+
/** Append runtime-originated events. Not the client signal path. */
|
|
40
|
+
accept(events: ReadonlyArray<EventInput>, options?: {
|
|
41
|
+
idempotencyKey?: string;
|
|
42
|
+
coalesce?: boolean;
|
|
43
|
+
}): Promise<RunState>;
|
|
44
|
+
cancel(): Promise<void>;
|
|
45
|
+
getRun(): Promise<RunState>;
|
|
27
46
|
}
|
|
28
47
|
/**
|
|
29
48
|
* Creates an in-process actor cell that owns a single `runId`.
|
package/dist/actor/cell.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Effect } from 'effect';
|
|
2
2
|
import { EventStoreTag, } from '@swirls/looms/core';
|
|
3
|
-
import { createFetchHandler, createRuntime, } from '@swirls/looms/runtime';
|
|
3
|
+
import { createFetchHandler, createRuntime, StartRunConflictError, } from '@swirls/looms/runtime';
|
|
4
4
|
import { runIdFromRequest } from './routing.js';
|
|
5
5
|
/**
|
|
6
6
|
* Creates an in-process actor cell that owns a single `runId`.
|
|
@@ -10,14 +10,17 @@ export function createActorCell(options) {
|
|
|
10
10
|
const { runId, store, scheduler } = options;
|
|
11
11
|
const runtime = createRuntime({
|
|
12
12
|
modules: options.modules,
|
|
13
|
+
definitionResolver: options.definitionResolver,
|
|
13
14
|
store,
|
|
14
15
|
scheduler,
|
|
16
|
+
launcher: options.launcher,
|
|
15
17
|
snapshotEvery: options.snapshotEvery,
|
|
16
18
|
maxWakeIterations: options.maxWakeIterations,
|
|
17
19
|
maxPendingRunOperations: options.maxPendingRunOperations,
|
|
18
20
|
snapshotStore: options.snapshotStore,
|
|
19
21
|
trimAfterSnapshot: options.trimAfterSnapshot,
|
|
20
22
|
});
|
|
23
|
+
const provide = (effect) => Effect.runPromise(Effect.provideService(effect, EventStoreTag, store));
|
|
21
24
|
const fetchHandler = createFetchHandler({ runtime, store, authorize: options.authorize });
|
|
22
25
|
return {
|
|
23
26
|
runId,
|
|
@@ -30,8 +33,17 @@ export function createActorCell(options) {
|
|
|
30
33
|
}
|
|
31
34
|
return fetchHandler(req).then((res) => res ?? new Response('Not Found', { status: 404 }));
|
|
32
35
|
},
|
|
33
|
-
wake: () =>
|
|
34
|
-
recoverWake: () =>
|
|
36
|
+
wake: () => provide(runtime.wake(runId)),
|
|
37
|
+
recoverWake: () => provide(runtime.rescanTimers),
|
|
35
38
|
dispose: () => Effect.runPromise(runtime.dispose),
|
|
39
|
+
launch: (args) => provide(runtime.launchRun({ ...args, runId }).pipe(Effect.catchIf((error) => error instanceof StartRunConflictError, () => Effect.void), Effect.asVoid)),
|
|
40
|
+
status: () => provide(runtime
|
|
41
|
+
.getRun(runId)
|
|
42
|
+
.pipe(Effect.map((state) => (state.rootThreadId === null ? null : { status: state.status })))),
|
|
43
|
+
startRun: (args) => provide(runtime.startRun({ ...args, runId })),
|
|
44
|
+
signal: (events, signalOptions) => provide(runtime.signal(runId, events, signalOptions)),
|
|
45
|
+
accept: (events, signalOptions) => provide(runtime.accept(runId, events, signalOptions)),
|
|
46
|
+
cancel: () => provide(runtime.cancel(runId).pipe(Effect.asVoid)),
|
|
47
|
+
getRun: () => provide(runtime.getRun(runId)),
|
|
36
48
|
};
|
|
37
49
|
}
|
package/dist/actor/host.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import type { AnyRuntimeModule, EventStore, EventStoreTrimCoverage, SnapshotStore } from '@swirls/looms/core';
|
|
2
|
-
import { type Authorize } from '@swirls/looms/runtime';
|
|
1
|
+
import type { AnyRuntimeModule, DefinitionResolver, EventInput, EventStore, EventStoreTrimCoverage, RunLauncher, RunState, SnapshotStore } from '@swirls/looms/core';
|
|
2
|
+
import { type Authorize, type StartResult, type StartRunArgs } from '@swirls/looms/runtime';
|
|
3
3
|
import { type ActorCell } from './cell';
|
|
4
4
|
export interface LocalActorHostOptions<TModules extends readonly AnyRuntimeModule[] = readonly AnyRuntimeModule[]> {
|
|
5
5
|
readonly createStore: (runId: string) => EventStore | Promise<EventStore>;
|
|
6
6
|
readonly modules: TModules;
|
|
7
|
+
/** Loads definitions that were not registered on a module. See `CreateRuntimeOptions`. */
|
|
8
|
+
readonly definitionResolver?: DefinitionResolver;
|
|
7
9
|
readonly snapshotStore?: SnapshotStore;
|
|
8
10
|
readonly snapshotEvery?: number;
|
|
9
11
|
readonly maxWakeIterations?: number;
|
|
@@ -21,6 +23,12 @@ export interface LocalActorHostOptions<TModules extends readonly AnyRuntimeModul
|
|
|
21
23
|
}
|
|
22
24
|
export interface LocalActorHost<TModules extends readonly AnyRuntimeModule[] = readonly AnyRuntimeModule[]> {
|
|
23
25
|
getCell(runId: string): Promise<ActorCell<TModules>>;
|
|
26
|
+
readonly launcher: RunLauncher;
|
|
27
|
+
startRun(args: StartRunArgs): Promise<StartResult>;
|
|
28
|
+
signal(runId: string, events: ReadonlyArray<EventInput>, options?: {
|
|
29
|
+
idempotencyKey?: string;
|
|
30
|
+
}): Promise<RunState>;
|
|
31
|
+
getRun(runId: string): Promise<RunState>;
|
|
24
32
|
fetch(req: Request): Promise<Response | null>;
|
|
25
33
|
dispose(): Promise<void>;
|
|
26
34
|
}
|
package/dist/actor/host.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Data, Effect } from 'effect';
|
|
2
|
-
import { EventStoreTag } from '@swirls/looms/core';
|
|
3
|
-
import { createTimeoutScheduler, isLoomsApiPath } from '@swirls/looms/runtime';
|
|
2
|
+
import { createRemoteRunLauncher, EventStoreTag } from '@swirls/looms/core';
|
|
3
|
+
import { createTimeoutScheduler, isLoomsApiPath, } from '@swirls/looms/runtime';
|
|
4
4
|
import { createActorCell } from './cell.js';
|
|
5
|
-
import { crossRunResponse, resolveRunTarget, RunTargetError } from './routing.js';
|
|
5
|
+
import { crossRunResponse, definitionsResponse, resolveRunTarget, RunTargetError } from './routing.js';
|
|
6
6
|
class ActorWakeError extends Data.TaggedError('ActorWakeError') {
|
|
7
7
|
constructor(cause) {
|
|
8
8
|
super({
|
|
@@ -28,7 +28,14 @@ class ActorHostError extends Data.TaggedError('ActorHostError') {
|
|
|
28
28
|
export function createLocalActorHost(options) {
|
|
29
29
|
const cells = new Map();
|
|
30
30
|
const rescanTimers = options.rescanTimers !== false;
|
|
31
|
-
|
|
31
|
+
let getCell;
|
|
32
|
+
const launcher = createRemoteRunLauncher({
|
|
33
|
+
launch: (runId, args) => getCell(runId).then((cell) => cell.launch(args)),
|
|
34
|
+
status: (runId) => getCell(runId).then((cell) => cell.status()),
|
|
35
|
+
accept: (runId, events, signalOptions) => getCell(runId).then((cell) => cell.accept(events, signalOptions).then(() => undefined)),
|
|
36
|
+
cancel: (runId) => getCell(runId).then((cell) => cell.cancel()),
|
|
37
|
+
});
|
|
38
|
+
getCell = (runId) => {
|
|
32
39
|
const existing = cells.get(runId);
|
|
33
40
|
if (existing) {
|
|
34
41
|
return existing;
|
|
@@ -51,11 +58,13 @@ export function createLocalActorHost(options) {
|
|
|
51
58
|
store,
|
|
52
59
|
scheduler,
|
|
53
60
|
modules: options.modules,
|
|
61
|
+
definitionResolver: options.definitionResolver,
|
|
54
62
|
snapshotStore: options.snapshotStore,
|
|
55
63
|
snapshotEvery: options.snapshotEvery,
|
|
56
64
|
maxWakeIterations: options.maxWakeIterations,
|
|
57
65
|
trimAfterSnapshot: options.trimAfterSnapshot,
|
|
58
66
|
authorize: options.authorize,
|
|
67
|
+
launcher,
|
|
59
68
|
});
|
|
60
69
|
wake = () => cell.wake();
|
|
61
70
|
if (rescanTimers) {
|
|
@@ -68,6 +77,16 @@ export function createLocalActorHost(options) {
|
|
|
68
77
|
};
|
|
69
78
|
return {
|
|
70
79
|
getCell,
|
|
80
|
+
launcher,
|
|
81
|
+
startRun: (args) => {
|
|
82
|
+
const runId = args.runId;
|
|
83
|
+
if (!runId) {
|
|
84
|
+
return Promise.reject(new Error('LocalActorHost.startRun requires runId'));
|
|
85
|
+
}
|
|
86
|
+
return getCell(runId).then((cell) => cell.startRun(args));
|
|
87
|
+
},
|
|
88
|
+
signal: (runId, events, signalOptions) => getCell(runId).then((cell) => cell.signal(events, signalOptions)),
|
|
89
|
+
getRun: (runId) => getCell(runId).then((cell) => cell.getRun()),
|
|
71
90
|
fetch: (req) => {
|
|
72
91
|
const url = new URL(req.url);
|
|
73
92
|
if (!isLoomsApiPath(url.pathname)) {
|
|
@@ -76,6 +95,10 @@ export function createLocalActorHost(options) {
|
|
|
76
95
|
if (url.pathname === '/health') {
|
|
77
96
|
return Promise.resolve(Response.json({ ok: true }));
|
|
78
97
|
}
|
|
98
|
+
const definitions = definitionsResponse(req, options.modules);
|
|
99
|
+
if (definitions) {
|
|
100
|
+
return Promise.resolve(definitions);
|
|
101
|
+
}
|
|
79
102
|
const unsupported = crossRunResponse(req, 'the actor host');
|
|
80
103
|
if (unsupported) {
|
|
81
104
|
return Promise.resolve(unsupported);
|
package/dist/actor/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { createActorCell, type ActorCell, type ActorCellOptions } from './cell';
|
|
2
|
-
export { crossRunResponse, runIdFromRequest, resolveRunTarget, RunTargetError, type ResolvedRunTarget, } from './routing';
|
|
2
|
+
export { crossRunResponse, definitionsResponse, runIdFromRequest, resolveRunTarget, RunTargetError, type ResolvedRunTarget, } from './routing';
|
|
3
3
|
export { createLocalActorHost, type LocalActorHost, type LocalActorHostOptions } from './host';
|
|
4
|
+
export type { RunLauncher } from '@swirls/looms/core';
|
package/dist/actor/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { createActorCell } from './cell.js';
|
|
2
|
-
export { crossRunResponse, runIdFromRequest, resolveRunTarget, RunTargetError, } from './routing.js';
|
|
2
|
+
export { crossRunResponse, definitionsResponse, runIdFromRequest, resolveRunTarget, RunTargetError, } from './routing.js';
|
|
3
3
|
export { createLocalActorHost } from './host.js';
|
package/dist/actor/routing.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type AnyRuntimeModule } from '@swirls/looms/core';
|
|
1
2
|
/**
|
|
2
3
|
* Extracts the target `runId` from a Looms HTTP request.
|
|
3
4
|
* Inspects `x-looms-run-id` and `/runs/:runId/*`.
|
|
@@ -8,6 +9,8 @@ export declare function runIdFromRequest(req: Request): string | null;
|
|
|
8
9
|
* runs needs a global index, and a fork writes a second run. `host` names the backend.
|
|
9
10
|
*/
|
|
10
11
|
export declare function crossRunResponse(req: Request, host: string): Response | null;
|
|
12
|
+
/** Answers `GET /definitions` from a module list or lazy factory without touching any run cell. */
|
|
13
|
+
export declare function definitionsResponse(req: Request, modules: readonly AnyRuntimeModule[] | (() => readonly AnyRuntimeModule[]) | undefined): Response | null;
|
|
11
14
|
export interface ResolvedRunTarget {
|
|
12
15
|
readonly runId: string;
|
|
13
16
|
readonly request: Request;
|
package/dist/actor/routing.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Data, Effect, Option, Schema } from 'effect';
|
|
2
|
-
import { createRunId, isJsonObject, stringifyJson } from '@swirls/looms/core';
|
|
1
|
+
import { Data, Effect, Option, Predicate, Schema } from 'effect';
|
|
2
|
+
import { composeModules, createRunId, isJsonObject, publishDefinition, stringifyJson, } from '@swirls/looms/core';
|
|
3
3
|
const RunTargetBodySchema = Schema.Struct({
|
|
4
4
|
runId: Schema.optional(Schema.NonEmptyString),
|
|
5
5
|
});
|
|
@@ -36,6 +36,17 @@ export function crossRunResponse(req, host) {
|
|
|
36
36
|
}
|
|
37
37
|
return null;
|
|
38
38
|
}
|
|
39
|
+
/** Answers `GET /definitions` from a module list or lazy factory without touching any run cell. */
|
|
40
|
+
export function definitionsResponse(req, modules) {
|
|
41
|
+
if (!modules || req.method !== 'GET' || new URL(req.url).pathname !== '/definitions') {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
const registry = composeModules(Predicate.isFunction(modules) ? modules() : modules);
|
|
45
|
+
return Response.json({
|
|
46
|
+
definitions: registry.definitions.map(publishDefinition),
|
|
47
|
+
projections: [...registry.projections.keys()],
|
|
48
|
+
});
|
|
49
|
+
}
|
|
39
50
|
export class RunTargetError extends Data.TaggedError('RunTargetError') {
|
|
40
51
|
constructor(method, path) {
|
|
41
52
|
super({
|
|
@@ -6,5 +6,5 @@ declare const AgentDefinitionsTag_base: Context.ServiceClass<AgentDefinitionsTag
|
|
|
6
6
|
export declare class AgentDefinitionsTag extends AgentDefinitionsTag_base {
|
|
7
7
|
}
|
|
8
8
|
export declare function makeAgentDefinitionStore(definitions: ReadonlyArray<AgentDefinition>): AgentDefinitionStore;
|
|
9
|
-
export declare const AgentDefinitionsLive: (definitions:
|
|
9
|
+
export declare const AgentDefinitionsLive: (definitions: AgentDefinitionStore) => Layer.Layer<AgentDefinitionsTag, never, never>;
|
|
10
10
|
export {};
|
|
@@ -5,4 +5,4 @@ export class AgentDefinitionsTag extends Context.Service()('looms/AgentDefinitio
|
|
|
5
5
|
export function makeAgentDefinitionStore(definitions) {
|
|
6
6
|
return makeDefinitionStore('agent', definitions);
|
|
7
7
|
}
|
|
8
|
-
export const AgentDefinitionsLive = (definitions) => Layer.succeed(AgentDefinitionsTag,
|
|
8
|
+
export const AgentDefinitionsLive = (definitions) => Layer.succeed(AgentDefinitionsTag, definitions);
|
|
@@ -3,6 +3,28 @@ import type { Schema } from 'effect';
|
|
|
3
3
|
import { type JsonValue, type RuntimeEffect, type SchemaInput } from '@swirls/looms/core';
|
|
4
4
|
import type { StopWhen } from './stop-when';
|
|
5
5
|
import type { Message, ToolCall } from './types';
|
|
6
|
+
export declare const TEAM_MEMBER_MAX_DEPTH: 3;
|
|
7
|
+
export declare const STRUCTURED_OUTPUT_TOOL_NAME: 'submit_output';
|
|
8
|
+
export interface AgentCompactionContext {
|
|
9
|
+
readonly threadId: string;
|
|
10
|
+
readonly turn: number;
|
|
11
|
+
readonly messages: readonly Message[];
|
|
12
|
+
readonly reason: 'overflow' | 'manual' | 'threshold';
|
|
13
|
+
}
|
|
14
|
+
export interface AgentCompactedResult {
|
|
15
|
+
readonly messages: readonly Message[];
|
|
16
|
+
readonly summary?: string;
|
|
17
|
+
}
|
|
18
|
+
export type AgentCompactor = (ctx: AgentCompactionContext) => Promise<AgentCompactedResult> | AgentCompactedResult;
|
|
19
|
+
/**
|
|
20
|
+
* Keeps the first message (the task) and the most recent messages, replacing the rest with a
|
|
21
|
+
* note. The recent window never starts on a tool result, so every kept result still follows
|
|
22
|
+
* the assistant message that requested it.
|
|
23
|
+
*/
|
|
24
|
+
export declare function defaultAgentCompactor(ctx: AgentCompactionContext): AgentCompactedResult;
|
|
25
|
+
/** Whether a model error reports that the prompt exceeded the model's context window. */
|
|
26
|
+
export declare function isContextOverflowError(error: Error): boolean;
|
|
27
|
+
export declare function buildStructuredOutputInstructions(toolName?: "submit_output"): string;
|
|
6
28
|
export interface ToolContext {
|
|
7
29
|
readonly threadId: string;
|
|
8
30
|
readonly turn: number;
|
|
@@ -59,6 +81,17 @@ export interface AgentTurnContext<TInput = JsonValue> {
|
|
|
59
81
|
readonly instructions: string;
|
|
60
82
|
readonly signal?: AbortSignal;
|
|
61
83
|
}
|
|
84
|
+
/** What `resolveTools` sees. It runs before each model turn and again when a tool executes. */
|
|
85
|
+
export interface AgentToolResolutionContext<TInput = JsonValue> {
|
|
86
|
+
readonly threadId: string;
|
|
87
|
+
readonly turn: number;
|
|
88
|
+
readonly input: TInput;
|
|
89
|
+
}
|
|
90
|
+
export interface AgentUsage {
|
|
91
|
+
readonly input: number;
|
|
92
|
+
readonly output: number;
|
|
93
|
+
readonly turn: number;
|
|
94
|
+
}
|
|
62
95
|
export interface AgentTurnResult<TOutput extends JsonValue = JsonValue> {
|
|
63
96
|
message: Message;
|
|
64
97
|
toolCalls?: ToolCall[];
|
|
@@ -77,7 +110,22 @@ export interface AgentDefinition<TName extends string = string, TInput = JsonVal
|
|
|
77
110
|
readonly model?: string;
|
|
78
111
|
readonly instructions: string;
|
|
79
112
|
readonly input?: StandardSchemaV1<any, TInput> | Schema.ConstraintDecoder<TInput>;
|
|
113
|
+
readonly output?: StandardSchemaV1<any, TOutput> | Schema.ConstraintDecoder<TOutput> | SchemaInput;
|
|
80
114
|
readonly tools?: ToolLike[];
|
|
115
|
+
/**
|
|
116
|
+
* Tools added for one turn, such as per-tenant integrations. Must return the same tools for the
|
|
117
|
+
* same input and turn, because tool execution resolves them again to find the handler.
|
|
118
|
+
*/
|
|
119
|
+
resolveTools?(ctx: AgentToolResolutionContext<TInput>): Promise<readonly AgentToolEntry[]> | readonly AgentToolEntry[];
|
|
120
|
+
/** Shrinks the conversation after the model reports a context overflow. */
|
|
121
|
+
readonly compact?: AgentCompactor;
|
|
122
|
+
/** Runs before each model call. Throwing fails the agent thread with the thrown message. */
|
|
123
|
+
assertCredits?(ctx: AgentTurnContext<TInput>): Promise<void> | void;
|
|
124
|
+
/**
|
|
125
|
+
* Reports token usage after each model call. Usage is also recorded as `agent.turn.usage`;
|
|
126
|
+
* a retried turn calls this again, so deduplicate on `threadId` and `turn`.
|
|
127
|
+
*/
|
|
128
|
+
trackUsage?(usage: AgentUsage, ctx: AgentTurnContext<TInput>): Promise<void> | void;
|
|
81
129
|
readonly maxTurns?: number;
|
|
82
130
|
readonly conversational?: boolean;
|
|
83
131
|
readonly stopWhen?: StopWhen;
|
|
@@ -1,4 +1,48 @@
|
|
|
1
1
|
import { DEFAULT_DEFINITION_VERSION, } from '@swirls/looms/core';
|
|
2
|
+
export const TEAM_MEMBER_MAX_DEPTH = 3;
|
|
3
|
+
export const STRUCTURED_OUTPUT_TOOL_NAME = 'submit_output';
|
|
4
|
+
const COMPACTION_RECENT_MESSAGES = 4;
|
|
5
|
+
/**
|
|
6
|
+
* Keeps the first message (the task) and the most recent messages, replacing the rest with a
|
|
7
|
+
* note. The recent window never starts on a tool result, so every kept result still follows
|
|
8
|
+
* the assistant message that requested it.
|
|
9
|
+
*/
|
|
10
|
+
export function defaultAgentCompactor(ctx) {
|
|
11
|
+
let start = ctx.messages.length - COMPACTION_RECENT_MESSAGES;
|
|
12
|
+
while (start > 1 && ctx.messages[start]?.role === 'tool') {
|
|
13
|
+
start -= 1;
|
|
14
|
+
}
|
|
15
|
+
if (start <= 1) {
|
|
16
|
+
return { messages: [...ctx.messages] };
|
|
17
|
+
}
|
|
18
|
+
const summary = `[${start - 1} earlier messages compacted for context window]`;
|
|
19
|
+
const summaryMessage = { role: 'system', content: summary };
|
|
20
|
+
return {
|
|
21
|
+
messages: [...ctx.messages.slice(0, 1), summaryMessage, ...ctx.messages.slice(start)],
|
|
22
|
+
summary,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const CONTEXT_OVERFLOW_MARKERS = [
|
|
26
|
+
'context window',
|
|
27
|
+
'context length',
|
|
28
|
+
'context_length_exceeded',
|
|
29
|
+
'maximum context',
|
|
30
|
+
'prompt is too long',
|
|
31
|
+
'prompt too long',
|
|
32
|
+
'too many tokens',
|
|
33
|
+
];
|
|
34
|
+
/** Whether a model error reports that the prompt exceeded the model's context window. */
|
|
35
|
+
export function isContextOverflowError(error) {
|
|
36
|
+
const message = error.message.toLowerCase();
|
|
37
|
+
return CONTEXT_OVERFLOW_MARKERS.some((marker) => message.includes(marker));
|
|
38
|
+
}
|
|
39
|
+
export function buildStructuredOutputInstructions(toolName = STRUCTURED_OUTPUT_TOOL_NAME) {
|
|
40
|
+
return [
|
|
41
|
+
`This task requires structured output matching the output schema.`,
|
|
42
|
+
`When you have completed all work and have the final result, call the "${toolName}" tool with your output.`,
|
|
43
|
+
`If "${toolName}" returns an error indicating validation failure, inspect the errors, correct the values, and call "${toolName}" again.`,
|
|
44
|
+
].join(' ');
|
|
45
|
+
}
|
|
2
46
|
export function defineAgentSession(def) {
|
|
3
47
|
const definition = {
|
|
4
48
|
kind: 'agent-session',
|