@swirls/looms 0.0.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -2
- package/dist/actor/cell.d.ts +9 -4
- package/dist/actor/cell.js +7 -11
- package/dist/actor/host.d.ts +7 -3
- package/dist/actor/host.js +57 -33
- package/dist/actor/index.d.ts +1 -1
- package/dist/actor/index.js +1 -1
- package/dist/actor/routing.d.ts +12 -1
- package/dist/actor/routing.js +57 -51
- package/dist/agent/agent-session.d.ts +5 -0
- package/dist/agent/agent-session.js +270 -0
- package/dist/agent/debugger/agent-chat.d.ts +2 -0
- package/dist/agent/debugger/agent-chat.js +176 -0
- package/dist/agent/debugger/index.d.ts +5 -0
- package/dist/agent/debugger/index.js +19 -0
- package/dist/agent/debugger/summarize.d.ts +2 -0
- package/dist/agent/debugger/summarize.js +51 -0
- package/dist/agent/debugger/token-usage.d.ts +3 -0
- package/dist/agent/debugger/token-usage.js +11 -0
- package/dist/agent/definitions-store.d.ts +2 -3
- package/dist/agent/definitions-store.js +2 -4
- package/dist/agent/definitions.d.ts +47 -29
- package/dist/agent/definitions.js +39 -12
- package/dist/agent/effects.d.ts +359 -2
- package/dist/agent/effects.js +60 -34
- package/dist/agent/events.d.ts +175 -19
- package/dist/agent/events.js +45 -10
- package/dist/agent/index.d.ts +1 -0
- package/dist/agent/index.js +1 -0
- package/dist/agent/llm.d.ts +11 -2
- package/dist/agent/llm.js +13 -3
- package/dist/agent/module.d.ts +812 -78
- package/dist/agent/module.js +16 -4
- package/dist/agent/scope.d.ts +174 -18
- package/dist/agent/signals.d.ts +26 -1
- package/dist/agent/signals.js +79 -0
- package/dist/agent/threads.d.ts +3 -33
- package/dist/agent/threads.js +20 -25
- package/dist/agent/tool-schema.d.ts +1 -17
- package/dist/agent/tool-schema.js +3 -43
- package/dist/agent/types.d.ts +49 -4
- package/dist/agent/types.js +5 -5
- package/dist/ai-vercel/index.d.ts +1 -0
- package/dist/ai-vercel/index.js +1 -0
- package/dist/ai-vercel/messages.js +22 -7
- package/dist/ai-vercel/vercel-evaluator.d.ts +36 -0
- package/dist/ai-vercel/vercel-evaluator.js +73 -0
- package/dist/ai-vercel/vercel-llm.js +64 -44
- package/dist/approval/debugger/approvals-view.d.ts +3 -0
- package/dist/approval/debugger/approvals-view.js +16 -0
- package/dist/approval/debugger/index.d.ts +4 -0
- package/dist/approval/debugger/index.js +11 -0
- package/dist/approval/debugger/summarize.d.ts +2 -0
- package/dist/approval/debugger/summarize.js +17 -0
- package/dist/approval/effects.d.ts +89 -0
- package/dist/approval/module.d.ts +179 -29
- package/dist/approval/projections.d.ts +0 -14
- package/dist/approval/projections.js +20 -3
- package/dist/approval/signals.d.ts +2 -0
- package/dist/approval/signals.js +18 -2
- package/dist/cli/cli.js +2 -0
- package/dist/cli/commands.js +12 -16
- package/dist/client/client.d.ts +1213 -18
- package/dist/client/client.js +120 -120
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/sse.d.ts +13 -0
- package/dist/client/sse.js +38 -44
- package/dist/cloudflare/alarm-scheduler.d.ts +12 -2
- package/dist/cloudflare/alarm-scheduler.js +34 -7
- package/dist/cloudflare/durable-object.d.ts +10 -2
- package/dist/cloudflare/durable-object.js +59 -28
- package/dist/cloudflare/event-store.d.ts +7 -2
- package/dist/cloudflare/event-store.js +8 -7
- package/dist/cloudflare/index.d.ts +2 -2
- package/dist/cloudflare/index.js +2 -2
- package/dist/cloudflare/router.d.ts +1 -1
- package/dist/cloudflare/router.js +15 -16
- package/dist/core/catalog.d.ts +3 -3
- package/dist/core/catalog.js +2 -5
- package/dist/core/coalesce.js +5 -3
- package/dist/core/compose.d.ts +2 -1
- package/dist/core/compose.js +19 -2
- package/dist/core/debugger-host.d.ts +16 -0
- package/dist/core/debugger-host.js +1 -0
- package/dist/core/definition-store.d.ts +11 -0
- package/dist/core/definition-store.js +6 -0
- package/dist/core/effects.d.ts +127 -15
- package/dist/core/effects.js +89 -17
- package/dist/core/envelope.d.ts +27 -7
- package/dist/core/envelope.js +20 -6
- package/dist/core/event-codec.d.ts +4 -2
- package/dist/core/event-codec.js +10 -5
- package/dist/core/event-index.js +1 -3
- package/dist/core/fold.d.ts +3 -0
- package/dist/core/fold.js +171 -24
- package/dist/core/ids.d.ts +5 -0
- package/dist/core/ids.js +35 -2
- package/dist/core/index.d.ts +7 -1
- package/dist/core/index.js +6 -1
- package/dist/core/kind.d.ts +22 -0
- package/dist/core/kind.js +17 -0
- package/dist/core/limits.d.ts +34 -0
- package/dist/core/limits.js +46 -0
- package/dist/core/match.d.ts +1 -0
- package/dist/core/match.js +10 -1
- package/dist/core/module-scope.d.ts +22 -20
- package/dist/core/module-scope.js +38 -28
- package/dist/core/module.d.ts +18 -5
- package/dist/core/module.js +4 -0
- package/dist/core/projection.d.ts +13 -13
- package/dist/core/projection.js +9 -5
- package/dist/core/protocol.d.ts +68 -11
- package/dist/core/protocol.js +82 -11
- package/dist/core/published.d.ts +43 -0
- package/dist/core/published.js +44 -0
- package/dist/core/replay.d.ts +312 -3
- package/dist/core/replay.js +11 -1
- package/dist/core/schema.d.ts +11 -20
- package/dist/core/schema.js +63 -80
- package/dist/core/serialize.js +2 -4
- package/dist/core/snapshot-store.d.ts +6 -1
- package/dist/core/snapshot-store.js +15 -2
- package/dist/core/snapshots.d.ts +5 -1
- package/dist/core/snapshots.js +10 -15
- package/dist/core/sqlite-store.js +95 -11
- package/dist/core/state.d.ts +142 -4
- package/dist/core/state.js +78 -0
- package/dist/core/store.d.ts +38 -3
- package/dist/core/store.js +77 -22
- package/dist/core/thread.d.ts +10 -9
- package/dist/core/types.d.ts +5 -8
- package/dist/core/types.js +28 -24
- package/dist/core/validate-event.js +14 -4
- package/dist/core/worker-callback.d.ts +17 -0
- package/dist/core/worker-callback.js +1 -0
- package/dist/debugger/app/assets/index-B3Ah8WAE.css +2 -0
- package/dist/debugger/app/assets/index-Qb371t_O.js +22 -0
- package/dist/debugger/app/assets/rolldown-runtime-CbXtAM7H.js +1 -0
- package/dist/debugger/app/assets/routes-CjtEHgPQ.js +47 -0
- package/dist/debugger/app/index.html +14 -0
- package/dist/debugger/components/composer.d.ts +17 -0
- package/dist/debugger/components/composer.js +25 -0
- package/dist/debugger/components/debugger-split.d.ts +2 -1
- package/dist/debugger/components/debugger-split.js +2 -2
- package/dist/debugger/components/event-inspector.d.ts +2 -1
- package/dist/debugger/components/event-inspector.js +25 -16
- package/dist/debugger/components/event-stream.d.ts +2 -1
- package/dist/debugger/components/event-stream.js +14 -74
- package/dist/debugger/components/follow-list.d.ts +19 -0
- package/dist/debugger/components/follow-list.js +96 -0
- package/dist/debugger/components/json-tree.d.ts +11 -0
- package/dist/debugger/components/json-tree.js +120 -0
- package/dist/debugger/components/json-view.js +2 -2
- package/dist/debugger/components/run-tree.js +53 -20
- package/dist/debugger/components/status-dot.d.ts +4 -0
- package/dist/debugger/components/status-dot.js +6 -2
- package/dist/debugger/context.d.ts +14 -0
- package/dist/debugger/context.js +17 -0
- package/dist/debugger/contracts.d.ts +7 -4
- package/dist/debugger/events/builtin-families.d.ts +3 -0
- package/dist/debugger/events/builtin-families.js +9 -0
- package/dist/debugger/events/catalog.d.ts +3 -4
- package/dist/debugger/events/catalog.js +27 -17
- package/dist/debugger/events/protocol-summarize.d.ts +1 -2
- package/dist/debugger/events/protocol-summarize.js +42 -24
- package/dist/debugger/index.d.ts +20 -6
- package/dist/debugger/index.js +19 -5
- package/dist/debugger/lib/cn.d.ts +1 -0
- package/dist/debugger/lib/cn.js +3 -0
- package/dist/debugger/lib/event-meta.d.ts +2 -3
- package/dist/debugger/lib/event-meta.js +6 -12
- package/dist/debugger/lib/json.d.ts +25 -0
- package/dist/debugger/lib/json.js +87 -0
- package/dist/debugger/lib/payload.d.ts +7 -0
- package/dist/debugger/lib/payload.js +11 -0
- package/dist/debugger/lib/time.d.ts +3 -0
- package/dist/debugger/lib/time.js +24 -0
- package/dist/debugger/plugin.d.ts +36 -0
- package/dist/debugger/plugin.js +14 -0
- package/dist/debugger/server/index.d.ts +14 -0
- package/dist/debugger/server/index.js +114 -0
- package/dist/debugger/shell/debugger-shell.d.ts +15 -0
- package/dist/debugger/shell/debugger-shell.js +43 -0
- package/dist/debugger/shell/definition-key.d.ts +3 -0
- package/dist/debugger/shell/definition-key.js +4 -0
- package/dist/debugger/shell/events-pane.d.ts +12 -0
- package/dist/debugger/shell/events-pane.js +25 -0
- package/dist/debugger/shell/projections-panel.d.ts +4 -0
- package/dist/debugger/shell/projections-panel.js +59 -0
- package/dist/debugger/shell/run-controls.d.ts +4 -0
- package/dist/debugger/shell/run-controls.js +72 -0
- package/dist/debugger/shell/run-search.d.ts +6 -0
- package/dist/debugger/shell/run-search.js +102 -0
- package/dist/debugger/shell/run-type-menu.d.ts +6 -0
- package/dist/debugger/shell/run-type-menu.js +11 -0
- package/dist/debugger/shell/schema-form.d.ts +31 -0
- package/dist/debugger/shell/schema-form.js +117 -0
- package/dist/debugger/shell/start-form.d.ts +3 -0
- package/dist/debugger/shell/start-form.js +75 -0
- package/dist/debugger/shell/use-start-run.d.ts +14 -0
- package/dist/debugger/shell/use-start-run.js +32 -0
- package/dist/debugger/shell/workspace.d.ts +6 -0
- package/dist/debugger/shell/workspace.js +15 -0
- package/dist/debugger/styles.css +111 -27
- package/dist/debugger/ui/button.d.ts +24 -0
- package/dist/debugger/ui/button.js +24 -0
- package/dist/debugger/ui/command.d.ts +9 -0
- package/dist/debugger/ui/command.js +24 -0
- package/dist/debugger/ui/dropdown-menu.d.ts +13 -0
- package/dist/debugger/ui/dropdown-menu.js +37 -0
- package/dist/debugger/ui/panel.d.ts +14 -0
- package/dist/debugger/ui/panel.js +16 -0
- package/dist/debugger/ui/popover.d.ts +7 -0
- package/dist/debugger/ui/popover.js +17 -0
- package/dist/debugger/ui/resizable.d.ts +7 -0
- package/dist/debugger/ui/resizable.js +14 -0
- package/dist/debugger/ui/scroll-area.d.ts +2 -1
- package/dist/debugger/ui/scroll-area.js +5 -3
- package/dist/debugger/ui/select.d.ts +10 -0
- package/dist/debugger/ui/select.js +21 -0
- package/dist/debugger/ui/tabs.js +2 -2
- package/dist/debugger/ui/textarea.d.ts +3 -0
- package/dist/debugger/ui/textarea.js +7 -0
- package/dist/evaluator/definitions-store.d.ts +11 -0
- package/dist/evaluator/definitions-store.js +8 -0
- package/dist/evaluator/definitions.d.ts +18 -0
- package/dist/evaluator/definitions.js +4 -0
- package/dist/evaluator/effects.d.ts +226 -0
- package/dist/evaluator/effects.js +132 -0
- package/dist/evaluator/evaluator.d.ts +24 -0
- package/dist/evaluator/evaluator.js +67 -0
- package/dist/evaluator/events.d.ts +59 -0
- package/dist/evaluator/events.js +21 -0
- package/dist/evaluator/index.d.ts +11 -0
- package/dist/evaluator/index.js +11 -0
- package/dist/evaluator/module.d.ts +606 -0
- package/dist/evaluator/module.js +25 -0
- package/dist/evaluator/projections.d.ts +50 -0
- package/dist/evaluator/projections.js +20 -0
- package/dist/evaluator/scope.d.ts +59 -0
- package/dist/evaluator/scope.js +7 -0
- package/dist/evaluator/signals.d.ts +3 -0
- package/dist/evaluator/signals.js +17 -0
- package/dist/evaluator/threads.d.ts +62 -0
- package/dist/evaluator/threads.js +117 -0
- package/dist/evaluator/types.d.ts +125 -0
- package/dist/evaluator/types.js +51 -0
- package/dist/projectors/delivery.d.ts +83 -0
- package/dist/projectors/delivery.js +182 -0
- package/dist/projectors/index-model.d.ts +1 -1
- package/dist/projectors/index-model.js +4 -6
- package/dist/projectors/index.d.ts +2 -0
- package/dist/projectors/index.js +2 -0
- package/dist/projectors/memory.d.ts +1 -1
- package/dist/projectors/memory.js +10 -8
- package/dist/projectors/postgres.js +44 -58
- package/dist/projectors/projector.d.ts +17 -0
- package/dist/projectors/projector.js +26 -1
- package/dist/projectors/sqlite-delivery.d.ts +4 -0
- package/dist/projectors/sqlite-delivery.js +147 -0
- package/dist/projectors/sqlite.js +23 -23
- package/dist/projectors/with-projectors.d.ts +7 -2
- package/dist/projectors/with-projectors.js +27 -28
- package/dist/react/notify.js +11 -8
- package/dist/react/react.d.ts +2 -3
- package/dist/react/react.js +14 -30
- package/dist/react/sse.d.ts +1 -1
- package/dist/react/sse.js +1 -1
- package/dist/react/store.d.ts +3 -3
- package/dist/react/store.js +109 -119
- package/dist/runtime/cancellation.d.ts +16 -0
- package/dist/runtime/cancellation.js +129 -0
- package/dist/runtime/deadline-transition-planner.d.ts +31 -0
- package/dist/runtime/deadline-transition-planner.js +139 -0
- package/dist/runtime/dispatch-effect.d.ts +3 -2
- package/dist/runtime/dispatch-effect.js +7 -13
- package/dist/runtime/errors.d.ts +51 -0
- package/dist/runtime/errors.js +39 -0
- package/dist/runtime/{runtime-helpers.d.ts → helpers.d.ts} +24 -4
- package/dist/runtime/{runtime-helpers.js → helpers.js} +56 -19
- package/dist/runtime/index.d.ts +3 -3
- package/dist/runtime/index.js +3 -3
- package/dist/runtime/ingress.d.ts +15 -0
- package/dist/runtime/ingress.js +42 -0
- package/dist/runtime/local-effect-executor.d.ts +21 -0
- package/dist/runtime/local-effect-executor.js +137 -0
- package/dist/runtime/looms.d.ts +30 -4
- package/dist/runtime/looms.js +57 -37
- package/dist/runtime/observer.d.ts +45 -0
- package/dist/runtime/observer.js +11 -0
- package/dist/runtime/repository.d.ts +55 -0
- package/dist/runtime/repository.js +293 -0
- package/dist/runtime/retry-policy.d.ts +16 -0
- package/dist/runtime/retry-policy.js +29 -0
- package/dist/runtime/run-execution-context.d.ts +30 -0
- package/dist/runtime/run-execution-context.js +56 -0
- package/dist/runtime/run-start.d.ts +4 -0
- package/dist/runtime/run-start.js +44 -0
- package/dist/runtime/runtime.d.ts +6 -87
- package/dist/runtime/runtime.js +248 -470
- package/dist/runtime/server/auth.d.ts +41 -0
- package/dist/runtime/server/auth.js +45 -0
- package/dist/runtime/server/debugger-host.d.ts +11 -0
- package/dist/runtime/server/debugger-host.js +32 -0
- package/dist/runtime/server/fetch-handler.d.ts +18 -0
- package/dist/runtime/server/fetch-handler.js +62 -0
- package/dist/runtime/server/http.d.ts +38 -0
- package/dist/runtime/server/http.js +66 -0
- package/dist/runtime/server/route-table.d.ts +55 -0
- package/dist/runtime/server/route-table.js +74 -0
- package/dist/runtime/server/routes/definitions.d.ts +3 -0
- package/dist/runtime/server/routes/definitions.js +20 -0
- package/dist/runtime/server/routes/effects.d.ts +3 -0
- package/dist/runtime/server/routes/effects.js +59 -0
- package/dist/runtime/server/routes/operations.d.ts +3 -0
- package/dist/runtime/server/routes/operations.js +14 -0
- package/dist/runtime/server/routes/runs.d.ts +3 -0
- package/dist/runtime/server/routes/runs.js +199 -0
- package/dist/runtime/server.d.ts +4 -8
- package/dist/runtime/server.js +6 -211
- package/dist/runtime/sse.d.ts +2 -1
- package/dist/runtime/sse.js +24 -17
- package/dist/runtime/types.d.ts +117 -0
- package/dist/runtime/types.js +1 -0
- package/dist/runtime/wake-engine.d.ts +20 -0
- package/dist/runtime/wake-engine.js +311 -0
- package/dist/runtime/wake-scheduler.d.ts +3 -4
- package/dist/runtime/wake-scheduler.js +25 -31
- package/dist/runtime/worker-callbacks.d.ts +16 -0
- package/dist/runtime/worker-callbacks.js +167 -0
- package/dist/runtime/worker-effect-dispatch.d.ts +36 -0
- package/dist/runtime/worker-effect-dispatch.js +126 -0
- package/dist/s2/config.d.ts +1 -1
- package/dist/s2/config.js +1 -1
- package/dist/s2/lite.js +70 -82
- package/dist/s2/pagination.d.ts +15 -0
- package/dist/s2/pagination.js +36 -0
- package/dist/s2/projector.js +6 -5
- package/dist/s2/snapshot-store.js +188 -161
- package/dist/s2/store.d.ts +3 -21
- package/dist/s2/store.js +71 -165
- package/dist/testing/index.d.ts +15 -0
- package/dist/testing/index.js +53 -16
- package/dist/workflow/debugger/index.d.ts +4 -0
- package/dist/workflow/debugger/index.js +11 -0
- package/dist/workflow/debugger/nodes-view.d.ts +3 -0
- package/dist/workflow/debugger/nodes-view.js +13 -0
- package/dist/workflow/debugger/summarize.d.ts +2 -0
- package/dist/workflow/debugger/summarize.js +30 -0
- package/dist/workflow/definitions-store.d.ts +2 -3
- package/dist/workflow/definitions-store.js +2 -2
- package/dist/workflow/definitions.d.ts +78 -22
- package/dist/workflow/definitions.js +80 -14
- package/dist/workflow/effects.d.ts +453 -107
- package/dist/workflow/effects.js +214 -115
- package/dist/workflow/events.d.ts +149 -5
- package/dist/workflow/events.js +27 -5
- package/dist/workflow/graph.d.ts +56 -0
- package/dist/workflow/graph.js +207 -0
- package/dist/workflow/index.d.ts +1 -0
- package/dist/workflow/index.js +1 -0
- package/dist/workflow/module.d.ts +1047 -266
- package/dist/workflow/projections.d.ts +14 -12
- package/dist/workflow/projections.js +30 -8
- package/dist/workflow/scope.d.ts +146 -4
- package/dist/workflow/threads.d.ts +383 -155
- package/dist/workflow/threads.js +308 -110
- package/package.json +26 -2
- package/dist/debugger/events/domain-summarize.d.ts +0 -3
- package/dist/debugger/events/domain-summarize.js +0 -107
- package/dist/debugger/events/family.d.ts +0 -8
- package/dist/debugger/events/family.js +0 -44
- package/dist/runtime/events-api.d.ts +0 -4
- package/dist/runtime/events-api.js +0 -84
package/dist/agent/threads.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Predicate } from 'effect';
|
|
2
|
-
import { createWaitId, emit, invoke, isWithdrawnError, parseEffectId, spawn, wait, } from '@swirls/looms/core';
|
|
2
|
+
import { createWaitId, DEFAULT_DEFINITION_VERSION, emit, invoke, isWithdrawnError, parseEffectId, spawn, wait, waitOutcome, } from '@swirls/looms/core';
|
|
3
3
|
import { callLlmEffect, executeToolEffect } from './effects.js';
|
|
4
4
|
import { agentModule } from './scope.js';
|
|
5
|
-
import { AgentStateSchema } from './types.js';
|
|
6
5
|
function inputToLine(input) {
|
|
7
6
|
if (input === null) {
|
|
8
7
|
return null;
|
|
@@ -44,9 +43,9 @@ function attachToolCall(lines, toolCall) {
|
|
|
44
43
|
}
|
|
45
44
|
export const agentThread = agentModule.thread({
|
|
46
45
|
kind: 'agent',
|
|
47
|
-
shape: AgentStateSchema,
|
|
48
46
|
initialState: (ctx) => ({
|
|
49
47
|
definitionName: ctx.definitionName,
|
|
48
|
+
definitionVersion: ctx.definitionVersion,
|
|
50
49
|
lines: [],
|
|
51
50
|
pendingToolCalls: [],
|
|
52
51
|
executingToolCalls: [],
|
|
@@ -60,12 +59,14 @@ export const agentThread = agentModule.thread({
|
|
|
60
59
|
input: ctx.input,
|
|
61
60
|
output: null,
|
|
62
61
|
pendingEffectTools: {},
|
|
62
|
+
consumedSteerMessageIds: [],
|
|
63
63
|
}),
|
|
64
64
|
step(state, event, ctx) {
|
|
65
65
|
switch (event.type) {
|
|
66
66
|
case 'runtime.thread.started': {
|
|
67
67
|
const payload = event.payload;
|
|
68
68
|
const defName = payload.definitionName || state.definitionName;
|
|
69
|
+
const defVersion = payload.definitionVersion ?? state.definitionVersion ?? DEFAULT_DEFINITION_VERSION;
|
|
69
70
|
// SAFETY: event payload input is JSON
|
|
70
71
|
const input = payload.input !== undefined ? payload.input : state.input;
|
|
71
72
|
const line = inputToLine(input);
|
|
@@ -73,6 +74,7 @@ export const agentThread = agentModule.thread({
|
|
|
73
74
|
return {
|
|
74
75
|
...state,
|
|
75
76
|
definitionName: defName,
|
|
77
|
+
definitionVersion: defVersion,
|
|
76
78
|
input,
|
|
77
79
|
lines,
|
|
78
80
|
needsLlmCall: true,
|
|
@@ -141,6 +143,10 @@ export const agentThread = agentModule.thread({
|
|
|
141
143
|
case 'agent.steered': {
|
|
142
144
|
const message = event.payload.message;
|
|
143
145
|
const interrupt = event.payload.interrupt ?? false;
|
|
146
|
+
const messageId = event.payload.messageId;
|
|
147
|
+
const consumedSteerMessageIds = messageId && !state.consumedSteerMessageIds.includes(messageId)
|
|
148
|
+
? [...state.consumedSteerMessageIds, messageId]
|
|
149
|
+
: state.consumedSteerMessageIds;
|
|
144
150
|
if (interrupt) {
|
|
145
151
|
return {
|
|
146
152
|
...state,
|
|
@@ -152,16 +158,18 @@ export const agentThread = agentModule.thread({
|
|
|
152
158
|
pendingEffects: [],
|
|
153
159
|
pendingEmits: [],
|
|
154
160
|
needsLlmCall: true,
|
|
161
|
+
consumedSteerMessageIds,
|
|
155
162
|
};
|
|
156
163
|
}
|
|
157
164
|
return {
|
|
158
165
|
...state,
|
|
159
166
|
lines: [...state.lines, message],
|
|
160
167
|
pendingSteer: message,
|
|
168
|
+
consumedSteerMessageIds,
|
|
161
169
|
};
|
|
162
170
|
}
|
|
163
171
|
case 'agent.spawn.requested': {
|
|
164
|
-
const { childThreadId, kind, definitionName, toolCallId, input } = event.payload;
|
|
172
|
+
const { childThreadId, kind, definitionName, definitionVersion, toolCallId, input } = event.payload;
|
|
165
173
|
return {
|
|
166
174
|
...state,
|
|
167
175
|
executingToolCalls: state.executingToolCalls.filter((item) => item.id !== toolCallId),
|
|
@@ -171,6 +179,7 @@ export const agentThread = agentModule.thread({
|
|
|
171
179
|
childThreadId,
|
|
172
180
|
kind,
|
|
173
181
|
definitionName,
|
|
182
|
+
definitionVersion,
|
|
174
183
|
toolCallId,
|
|
175
184
|
// SAFETY: schema-decoded input is JSON
|
|
176
185
|
input: input ?? null,
|
|
@@ -180,10 +189,7 @@ export const agentThread = agentModule.thread({
|
|
|
180
189
|
}
|
|
181
190
|
case 'agent.effects.requested': {
|
|
182
191
|
const { toolCallId, effects: rawEffects, waitOn } = event.payload;
|
|
183
|
-
|
|
184
|
-
const effects = Array.isArray(rawEffects)
|
|
185
|
-
? [...rawEffects]
|
|
186
|
-
: [];
|
|
192
|
+
const effects = Array.isArray(rawEffects) ? [...rawEffects] : [];
|
|
187
193
|
const taggedEffects = effects.map((effect, idx) => {
|
|
188
194
|
if (!('tag' in effect && Predicate.isString(effect.tag))) {
|
|
189
195
|
return { ...effect, tag: `${toolCallId}_${effect.type}_${idx}` };
|
|
@@ -211,7 +217,6 @@ export const agentThread = agentModule.thread({
|
|
|
211
217
|
waitOn: waitOn
|
|
212
218
|
? {
|
|
213
219
|
type: waitOn.type,
|
|
214
|
-
// SAFETY: schema-decoded match is JSON
|
|
215
220
|
match: waitOn.match ?? undefined,
|
|
216
221
|
}
|
|
217
222
|
: undefined,
|
|
@@ -283,17 +288,9 @@ export const agentThread = agentModule.thread({
|
|
|
283
288
|
if (!toolCallId) {
|
|
284
289
|
return state;
|
|
285
290
|
}
|
|
286
|
-
const embedded = event.payload.event;
|
|
287
|
-
const embeddedObj = Predicate.isObject(embedded) && Predicate.isObject(embedded.payload)
|
|
288
|
-
? embedded.payload
|
|
289
|
-
: {};
|
|
290
291
|
const threadId = ctx.threadId;
|
|
291
292
|
const name = Predicate.isString(tag.name) ? tag.name : 'child';
|
|
292
|
-
const error =
|
|
293
|
-
// SAFETY: embedded output/payload is JSON
|
|
294
|
-
const result = embeddedObj.output ??
|
|
295
|
-
(Predicate.isObject(embedded) ? embedded.payload : null) ??
|
|
296
|
-
null;
|
|
293
|
+
const { result, error } = waitOutcome(event.payload.event, tag);
|
|
297
294
|
return {
|
|
298
295
|
...state,
|
|
299
296
|
pendingSpawns: state.pendingSpawns.filter((item) => item.toolCallId !== toolCallId),
|
|
@@ -327,14 +324,17 @@ export const agentThread = agentModule.thread({
|
|
|
327
324
|
effects.push(invoke(callLlmEffect, {
|
|
328
325
|
turn: state.turn + 1,
|
|
329
326
|
definitionName: state.definitionName,
|
|
327
|
+
definitionVersion: state.definitionVersion ?? DEFAULT_DEFINITION_VERSION,
|
|
330
328
|
messages: state.lines,
|
|
331
329
|
input: state.input,
|
|
330
|
+
consumedSteerMessageIds: state.consumedSteerMessageIds,
|
|
332
331
|
}, `llm_turn_${state.turn + 1}`));
|
|
333
332
|
}
|
|
334
333
|
for (const toolCall of state.executingToolCalls) {
|
|
335
334
|
effects.push(invoke(executeToolEffect, {
|
|
336
335
|
turn: state.turn,
|
|
337
336
|
definitionName: state.definitionName,
|
|
337
|
+
definitionVersion: state.definitionVersion ?? DEFAULT_DEFINITION_VERSION,
|
|
338
338
|
toolCall,
|
|
339
339
|
}, `tool_${toolCall.id}`));
|
|
340
340
|
}
|
|
@@ -344,6 +344,7 @@ export const agentThread = agentModule.thread({
|
|
|
344
344
|
childThreadId: spawnReq.childThreadId,
|
|
345
345
|
kind: spawnReq.kind,
|
|
346
346
|
definitionName: spawnReq.definitionName,
|
|
347
|
+
definitionVersion: spawnReq.definitionVersion,
|
|
347
348
|
input: spawnReq.input,
|
|
348
349
|
}), wait({
|
|
349
350
|
waitId,
|
|
@@ -384,15 +385,9 @@ export function satisfiedToToolResult(event) {
|
|
|
384
385
|
if (!toolCallId) {
|
|
385
386
|
return null;
|
|
386
387
|
}
|
|
387
|
-
const embedded = event.payload.event;
|
|
388
|
-
const embeddedPayload = Predicate.isObject(embedded) && Predicate.isObject(embedded.payload) ? embedded.payload : {};
|
|
389
388
|
const threadId = event.threadId ?? null;
|
|
390
389
|
const name = Predicate.isString(tag.name) ? tag.name : 'child';
|
|
391
|
-
const error =
|
|
392
|
-
// SAFETY: embedded output/payload is JSON
|
|
393
|
-
const result = embeddedPayload.output ??
|
|
394
|
-
(Predicate.isObject(embedded) ? embedded.payload : null) ??
|
|
395
|
-
null;
|
|
390
|
+
const { result, error } = waitOutcome(event.payload.event, tag);
|
|
396
391
|
return emit({
|
|
397
392
|
type: 'agent.tool.result',
|
|
398
393
|
payload: {
|
|
@@ -1,21 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { JsonValue, SchemaInput } from '@swirls/looms/core';
|
|
1
|
+
import { type JsonValue } from '@swirls/looms/core';
|
|
3
2
|
import { type AgentToolEntry, type ToolLike } from './definitions';
|
|
4
3
|
import type { LlmToolSpec } from './llm';
|
|
5
|
-
interface StandardJsonSchemaConverter {
|
|
6
|
-
readonly input: (options: {
|
|
7
|
-
target: string;
|
|
8
|
-
}) => JsonValue;
|
|
9
|
-
}
|
|
10
|
-
interface StandardJsonSchemaHolder {
|
|
11
|
-
readonly '~standard': {
|
|
12
|
-
readonly jsonSchema?: {
|
|
13
|
-
readonly input?: StandardJsonSchemaConverter['input'];
|
|
14
|
-
};
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
type SchemaCandidate = SchemaInput | StandardJsonSchemaHolder | Schema.Codec<JsonValue>;
|
|
18
4
|
export declare function toolJsonSchema(tool: ToolLike): JsonValue;
|
|
19
5
|
export declare function toolSpecs(tools?: ReadonlyArray<AgentToolEntry>): LlmToolSpec[];
|
|
20
|
-
export declare function jsonSchemaFromStandard(schema: SchemaCandidate | null | undefined): JsonValue;
|
|
21
|
-
export {};
|
|
@@ -1,44 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsonSchemaOfInput } from '@swirls/looms/core';
|
|
2
2
|
import { normalizeTools } from './definitions.js';
|
|
3
3
|
const EMPTY_OBJECT_SCHEMA = { type: 'object' };
|
|
4
|
-
function
|
|
5
|
-
return '~standard' in value;
|
|
6
|
-
}
|
|
7
|
-
function fromStandardJsonSchema(schema) {
|
|
8
|
-
if (!isStandardJsonSchemaHolder(schema)) {
|
|
9
|
-
return undefined;
|
|
10
|
-
}
|
|
11
|
-
const input = schema['~standard'].jsonSchema?.input;
|
|
12
|
-
if (!input) {
|
|
13
|
-
return undefined;
|
|
14
|
-
}
|
|
15
|
-
try {
|
|
16
|
-
return input({ target: 'draft-2020-12' });
|
|
17
|
-
}
|
|
18
|
-
catch {
|
|
19
|
-
return undefined;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
function fromEffectSchema(schema) {
|
|
23
|
-
if (!Schema.isSchema(schema)) {
|
|
24
|
-
return undefined;
|
|
25
|
-
}
|
|
26
|
-
try {
|
|
27
|
-
// SAFETY: Effect Schema values used as tool input codecs produce Standard JSON Schema.
|
|
28
|
-
const standard = Schema.toStandardJSONSchemaV1(schema);
|
|
29
|
-
return fromStandardJsonSchema(standard);
|
|
30
|
-
}
|
|
31
|
-
catch {
|
|
32
|
-
return undefined;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
function fromInputCandidate(input) {
|
|
36
|
-
if (!input) {
|
|
37
|
-
return undefined;
|
|
38
|
-
}
|
|
39
|
-
return fromStandardJsonSchema(input) ?? fromEffectSchema(input);
|
|
40
|
-
}
|
|
41
|
-
function toolInputCandidate(tool) {
|
|
4
|
+
function toolInput(tool) {
|
|
42
5
|
switch (tool.kind) {
|
|
43
6
|
case 'function':
|
|
44
7
|
return tool.input;
|
|
@@ -53,7 +16,7 @@ function toolInputCandidate(tool) {
|
|
|
53
16
|
}
|
|
54
17
|
}
|
|
55
18
|
export function toolJsonSchema(tool) {
|
|
56
|
-
return
|
|
19
|
+
return jsonSchemaOfInput(toolInput(tool)) ?? EMPTY_OBJECT_SCHEMA;
|
|
57
20
|
}
|
|
58
21
|
export function toolSpecs(tools = []) {
|
|
59
22
|
return normalizeTools(tools).map((tool) => ({
|
|
@@ -62,6 +25,3 @@ export function toolSpecs(tools = []) {
|
|
|
62
25
|
inputJsonSchema: toolJsonSchema(tool),
|
|
63
26
|
}));
|
|
64
27
|
}
|
|
65
|
-
export function jsonSchemaFromStandard(schema) {
|
|
66
|
-
return fromInputCandidate(schema ?? undefined) ?? EMPTY_OBJECT_SCHEMA;
|
|
67
|
-
}
|
package/dist/agent/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Schema } from 'effect';
|
|
2
|
-
import type
|
|
2
|
+
import { type EventInput, type JsonValue, type RuntimeEffect } from '@swirls/looms/core';
|
|
3
3
|
export declare const ToolCallSchema: Schema.Struct<{
|
|
4
4
|
readonly id: Schema.String;
|
|
5
5
|
readonly name: Schema.String;
|
|
@@ -35,12 +35,13 @@ export declare const ConversationSchema: Schema.Struct<{
|
|
|
35
35
|
}>;
|
|
36
36
|
export type ConversationState = Schema.Schema.Type<typeof ConversationSchema>;
|
|
37
37
|
export declare const TokenUsageSchema: Schema.Struct<{
|
|
38
|
-
readonly input: Schema.
|
|
39
|
-
readonly output: Schema.
|
|
38
|
+
readonly input: Schema.Finite;
|
|
39
|
+
readonly output: Schema.Finite;
|
|
40
40
|
}>;
|
|
41
41
|
export type TokenUsage = Schema.Schema.Type<typeof TokenUsageSchema>;
|
|
42
42
|
export declare const ThreadStartedPayloadSchema: Schema.Struct<{
|
|
43
43
|
readonly definitionName: Schema.optional<Schema.String>;
|
|
44
|
+
readonly definitionVersion: Schema.withDecodingDefaultKey<Schema.String, never>;
|
|
44
45
|
readonly input: Schema.optional<Schema.Unknown>;
|
|
45
46
|
}>;
|
|
46
47
|
export interface PendingEffectTool {
|
|
@@ -51,6 +52,7 @@ export interface AgentPendingSpawn {
|
|
|
51
52
|
readonly childThreadId: string;
|
|
52
53
|
readonly kind: string;
|
|
53
54
|
readonly definitionName: string;
|
|
55
|
+
readonly definitionVersion: string;
|
|
54
56
|
readonly toolCallId: string;
|
|
55
57
|
readonly input: JsonValue;
|
|
56
58
|
}
|
|
@@ -68,6 +70,7 @@ export interface AgentPendingEmit {
|
|
|
68
70
|
}
|
|
69
71
|
export interface AgentState {
|
|
70
72
|
definitionName?: string;
|
|
73
|
+
definitionVersion?: string;
|
|
71
74
|
lines: Message[];
|
|
72
75
|
pendingToolCalls: ToolCall[];
|
|
73
76
|
executingToolCalls: ToolCall[];
|
|
@@ -83,5 +86,47 @@ export interface AgentState {
|
|
|
83
86
|
pendingEffectTools: {
|
|
84
87
|
[causingSeq: string]: PendingEffectTool;
|
|
85
88
|
};
|
|
89
|
+
consumedSteerMessageIds: string[];
|
|
90
|
+
}
|
|
91
|
+
export type AgentMessageDelivery = 'steer' | 'followUp' | 'nextTurn';
|
|
92
|
+
export type AgentSessionTurnStatus = 'completed' | 'failed' | 'cancelled';
|
|
93
|
+
export interface AgentSessionMessage {
|
|
94
|
+
readonly messageId: string;
|
|
95
|
+
readonly text: string;
|
|
96
|
+
readonly delivery?: AgentMessageDelivery;
|
|
97
|
+
readonly steeredIntoMessageId?: string;
|
|
98
|
+
}
|
|
99
|
+
export interface AgentSessionActiveTurn {
|
|
100
|
+
readonly messageId: string;
|
|
101
|
+
readonly childThreadId: string;
|
|
102
|
+
readonly text: string;
|
|
103
|
+
}
|
|
104
|
+
export interface AgentSessionClosure {
|
|
105
|
+
readonly messageId: string;
|
|
106
|
+
readonly status: AgentSessionTurnStatus;
|
|
107
|
+
readonly error?: string;
|
|
108
|
+
}
|
|
109
|
+
export interface AgentSessionState {
|
|
110
|
+
readonly definitionName: string;
|
|
111
|
+
readonly definitionVersion: string;
|
|
112
|
+
readonly pendingMessages: AgentSessionMessage[];
|
|
113
|
+
readonly nextTurnMessages: AgentSessionMessage[];
|
|
114
|
+
readonly processedMessageIds: string[];
|
|
115
|
+
readonly activeTurn: AgentSessionActiveTurn | null;
|
|
116
|
+
readonly pendingSteerDeliveries: AgentSessionMessage[];
|
|
117
|
+
readonly pendingClosures: AgentSessionClosure[];
|
|
118
|
+
readonly lastSequence: number;
|
|
119
|
+
readonly idleTimeoutMs: number;
|
|
120
|
+
readonly idleDeadlineAt: number | null;
|
|
121
|
+
readonly parked: boolean;
|
|
122
|
+
readonly cancelling: boolean;
|
|
123
|
+
}
|
|
124
|
+
export interface AgentSessionSnapshot {
|
|
125
|
+
readonly activeTurnId: string | null;
|
|
126
|
+
readonly activeChildThreadId: string | null;
|
|
127
|
+
readonly pendingMessageCount: number;
|
|
128
|
+
readonly nextTurnHeldCount: number;
|
|
129
|
+
readonly processedMessageIds: readonly string[];
|
|
130
|
+
readonly lastSequence: number;
|
|
131
|
+
readonly parked: boolean;
|
|
86
132
|
}
|
|
87
|
-
export declare const AgentStateSchema: Schema.Schema<AgentState>;
|
package/dist/agent/types.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Schema } from 'effect';
|
|
1
|
+
import { Effect, Schema } from 'effect';
|
|
2
|
+
import { DEFAULT_DEFINITION_VERSION, } from '@swirls/looms/core';
|
|
2
3
|
export const ToolCallSchema = Schema.Struct({
|
|
3
4
|
id: Schema.String,
|
|
4
5
|
name: Schema.String,
|
|
@@ -21,12 +22,11 @@ export const ConversationSchema = Schema.Struct({
|
|
|
21
22
|
lines: Schema.mutable(Schema.Array(MessageSchema)),
|
|
22
23
|
});
|
|
23
24
|
export const TokenUsageSchema = Schema.Struct({
|
|
24
|
-
input: Schema.
|
|
25
|
-
output: Schema.
|
|
25
|
+
input: Schema.Finite,
|
|
26
|
+
output: Schema.Finite,
|
|
26
27
|
});
|
|
27
28
|
export const ThreadStartedPayloadSchema = Schema.Struct({
|
|
28
29
|
definitionName: Schema.optional(Schema.String),
|
|
30
|
+
definitionVersion: Schema.String.pipe(Schema.withDecodingDefaultKey(Effect.succeed(DEFAULT_DEFINITION_VERSION))),
|
|
29
31
|
input: Schema.optional(Schema.Unknown),
|
|
30
32
|
});
|
|
31
|
-
// SAFETY: AgentState is folded by reducers; Schema.Unknown is a typed placeholder, not a decoder.
|
|
32
|
-
export const AgentStateSchema = Schema.Unknown;
|
package/dist/ai-vercel/index.js
CHANGED
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
import {} from 'ai';
|
|
2
|
+
import { Option, Predicate, Schema } from 'effect';
|
|
3
|
+
const decodeJson = Schema.decodeOption(Schema.fromJsonString(Schema.Json));
|
|
4
|
+
function toAiJson(value) {
|
|
5
|
+
if (value === null ||
|
|
6
|
+
Predicate.isString(value) ||
|
|
7
|
+
Predicate.isNumber(value) ||
|
|
8
|
+
Predicate.isBoolean(value)) {
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
if (Array.isArray(value)) {
|
|
12
|
+
return value.map(toAiJson);
|
|
13
|
+
}
|
|
14
|
+
const converted = {};
|
|
15
|
+
for (const [key, nested] of Object.entries(value)) {
|
|
16
|
+
converted[key] = toAiJson(nested);
|
|
17
|
+
}
|
|
18
|
+
return converted;
|
|
19
|
+
}
|
|
2
20
|
export function toModelMessages(messages) {
|
|
3
21
|
const converted = [];
|
|
4
22
|
for (const message of messages) {
|
|
@@ -51,13 +69,10 @@ export function toModelMessages(messages) {
|
|
|
51
69
|
return converted;
|
|
52
70
|
}
|
|
53
71
|
function parseToolOutput(content) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
catch {
|
|
59
|
-
return { type: 'text', value: content };
|
|
60
|
-
}
|
|
72
|
+
return Option.match(decodeJson(content), {
|
|
73
|
+
onNone: () => ({ type: 'text', value: content }),
|
|
74
|
+
onSome: (value) => ({ type: 'json', value: toAiJson(value) }),
|
|
75
|
+
});
|
|
61
76
|
}
|
|
62
77
|
export function toLoomsToolCalls(calls) {
|
|
63
78
|
return calls.map((call) => ({
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { experimental_evaluate } from 'ai';
|
|
2
|
+
import type { EvaluatorAdapter, EvaluatorAnswers, EvaluatorQuestions } from '@swirls/looms/evaluator';
|
|
3
|
+
type EvaluateOptions = Parameters<typeof experimental_evaluate>[0];
|
|
4
|
+
type EvaluationModel = Exclude<EvaluateOptions['model'], string>;
|
|
5
|
+
/** An AI SDK provider with evaluation models, such as `createTypeSafeAi({ apiKey })`. */
|
|
6
|
+
export interface EvaluationModelProvider {
|
|
7
|
+
readonly evaluationModel: (modelId: string) => EvaluationModel;
|
|
8
|
+
}
|
|
9
|
+
interface VercelEvaluatorBaseOptions {
|
|
10
|
+
/** Abort the hosted call after this many milliseconds. Defaults to 2000. */
|
|
11
|
+
readonly timeoutMs?: number;
|
|
12
|
+
/** Defaults to AI Gateway zero data retention when no `provider` is set. */
|
|
13
|
+
readonly providerOptions?: EvaluateOptions['providerOptions'];
|
|
14
|
+
}
|
|
15
|
+
export type VercelEvaluatorOptions = VercelEvaluatorBaseOptions & ({
|
|
16
|
+
/** AI Gateway model id. Defaults to TypeSafe Jev (`typesafe-ai/jev`). */
|
|
17
|
+
readonly model?: string;
|
|
18
|
+
readonly provider?: undefined;
|
|
19
|
+
} | {
|
|
20
|
+
/** Default model id for `provider`. A definition's own `model` takes precedence. */
|
|
21
|
+
readonly model: string;
|
|
22
|
+
/** Resolves model ids with your own provider and key instead of the AI Gateway. */
|
|
23
|
+
readonly provider: EvaluationModelProvider;
|
|
24
|
+
});
|
|
25
|
+
interface EvaluateAnswer {
|
|
26
|
+
readonly type?: 'boolean' | 'choice' | 'score';
|
|
27
|
+
readonly probability?: number;
|
|
28
|
+
readonly choice?: string;
|
|
29
|
+
readonly score?: number;
|
|
30
|
+
}
|
|
31
|
+
/** Map `experimental_evaluate` answers onto evaluator answers. Boolean items only expose probability. */
|
|
32
|
+
export declare function toEvaluatorAnswers(questions: EvaluatorQuestions, raw: {
|
|
33
|
+
readonly [name: string]: EvaluateAnswer | undefined;
|
|
34
|
+
}): EvaluatorAnswers;
|
|
35
|
+
export declare function vercelEvaluator(options?: VercelEvaluatorOptions): EvaluatorAdapter;
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { experimental_evaluate } from 'ai';
|
|
2
|
+
import { Data, Effect, Predicate } from 'effect';
|
|
3
|
+
const DEFAULT_EVALUATOR_MODEL = 'typesafe-ai/jev';
|
|
4
|
+
class VercelEvaluatorError extends Data.TaggedError('VercelEvaluatorError') {
|
|
5
|
+
constructor(cause) {
|
|
6
|
+
super({
|
|
7
|
+
cause,
|
|
8
|
+
message: cause instanceof Error ? cause.message : String(cause),
|
|
9
|
+
});
|
|
10
|
+
this.name = 'VercelEvaluatorError';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function abortSignalFor(timeoutMs, parent) {
|
|
14
|
+
const timeout = AbortSignal.timeout(timeoutMs);
|
|
15
|
+
return parent ? AbortSignal.any([parent, timeout]) : timeout;
|
|
16
|
+
}
|
|
17
|
+
/** Map `experimental_evaluate` answers onto evaluator answers. Boolean items only expose probability. */
|
|
18
|
+
export function toEvaluatorAnswers(questions, raw) {
|
|
19
|
+
const answers = {};
|
|
20
|
+
for (const [name, question] of Object.entries(questions)) {
|
|
21
|
+
const item = raw[name];
|
|
22
|
+
if (question.type === 'boolean') {
|
|
23
|
+
const probability = Predicate.isNumber(item?.probability) ? item.probability : 0;
|
|
24
|
+
answers[name] = {
|
|
25
|
+
type: 'boolean',
|
|
26
|
+
value: probability >= 0.5,
|
|
27
|
+
probability,
|
|
28
|
+
};
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (question.type === 'choice') {
|
|
32
|
+
answers[name] = {
|
|
33
|
+
type: 'choice',
|
|
34
|
+
value: Predicate.isString(item?.choice) ? item.choice : '',
|
|
35
|
+
};
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
answers[name] = {
|
|
39
|
+
type: 'score',
|
|
40
|
+
value: Predicate.isNumber(item?.score) ? item.score : 0,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return answers;
|
|
44
|
+
}
|
|
45
|
+
export function vercelEvaluator(options = {}) {
|
|
46
|
+
const timeoutMs = options.timeoutMs ?? 2000;
|
|
47
|
+
const providerOptions = options.providerOptions ??
|
|
48
|
+
(options.provider ? undefined : { gateway: { zeroDataRetention: true } });
|
|
49
|
+
function resolveModel(modelId) {
|
|
50
|
+
const id = modelId ?? options.model ?? DEFAULT_EVALUATOR_MODEL;
|
|
51
|
+
return options.provider ? options.provider.evaluationModel(id) : id;
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
evaluate: (args) => Effect.runPromise(Effect.tryPromise({
|
|
55
|
+
try: () => experimental_evaluate({
|
|
56
|
+
model: resolveModel(args.model),
|
|
57
|
+
state: args.state,
|
|
58
|
+
abortSignal: abortSignalFor(timeoutMs, args.signal),
|
|
59
|
+
maxRetries: 0,
|
|
60
|
+
providerOptions,
|
|
61
|
+
questions: args.questions,
|
|
62
|
+
}),
|
|
63
|
+
catch: (cause) => new VercelEvaluatorError(cause),
|
|
64
|
+
}).pipe(Effect.map((result) => ({
|
|
65
|
+
answers: toEvaluatorAnswers(args.questions, result.answers),
|
|
66
|
+
usage: {
|
|
67
|
+
input: result.usage.inputTokens ?? 0,
|
|
68
|
+
output: result.usage.outputTokens ?? 0,
|
|
69
|
+
},
|
|
70
|
+
raw: result,
|
|
71
|
+
})))),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
@@ -1,36 +1,51 @@
|
|
|
1
|
-
import { generateText, jsonSchema, streamText, tool } from 'ai';
|
|
1
|
+
import { generateText, jsonSchema, streamText, tool, } from 'ai';
|
|
2
|
+
import { Data, Effect, Option, Predicate, Stream } from 'effect';
|
|
3
|
+
import { asJson } from '@swirls/looms/core';
|
|
2
4
|
import { toLoomsToolCalls, toModelMessages } from './messages.js';
|
|
5
|
+
class VercelLlmError extends Data.TaggedError('VercelLlmError') {
|
|
6
|
+
constructor(cause) {
|
|
7
|
+
super({
|
|
8
|
+
cause,
|
|
9
|
+
message: cause instanceof Error ? cause.message : String(cause),
|
|
10
|
+
});
|
|
11
|
+
this.name = 'VercelLlmError';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function isJsonSchema(value) {
|
|
15
|
+
return Predicate.isReadonlyObject(value) && !Array.isArray(value);
|
|
16
|
+
}
|
|
3
17
|
function toAiTools(specs) {
|
|
4
|
-
return Object.fromEntries(specs.map((spec) =>
|
|
5
|
-
spec.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
18
|
+
return Object.fromEntries(specs.map((spec) => {
|
|
19
|
+
if (!isJsonSchema(spec.inputJsonSchema)) {
|
|
20
|
+
throw new VercelLlmError(`Invalid JSON Schema for tool "${spec.name}"`);
|
|
21
|
+
}
|
|
22
|
+
return [
|
|
23
|
+
spec.name,
|
|
24
|
+
tool({
|
|
25
|
+
description: spec.description,
|
|
26
|
+
inputSchema: jsonSchema(spec.inputJsonSchema),
|
|
27
|
+
}),
|
|
28
|
+
];
|
|
29
|
+
}));
|
|
12
30
|
}
|
|
13
31
|
function toolCallInput(call) {
|
|
14
32
|
const input = 'input' in call ? call.input : {};
|
|
15
|
-
|
|
16
|
-
return (input ?? {});
|
|
33
|
+
return asJson(input ?? {});
|
|
17
34
|
}
|
|
18
35
|
export function vercelLlm(options) {
|
|
19
36
|
const streamEnabled = options.stream !== false;
|
|
20
37
|
return {
|
|
21
|
-
|
|
38
|
+
complete: (args) => Effect.runPromise(Effect.gen(function* () {
|
|
22
39
|
const messages = toModelMessages(args.messages);
|
|
23
40
|
const tools = args.toolSpecs && args.toolSpecs.length > 0 ? toAiTools(args.toolSpecs) : undefined;
|
|
24
|
-
|
|
25
|
-
if (shouldStream) {
|
|
41
|
+
if (streamEnabled && args.onTextDelta) {
|
|
26
42
|
const result = tools
|
|
27
43
|
? streamText({
|
|
28
44
|
model: options.model,
|
|
29
45
|
instructions: args.instructions,
|
|
30
46
|
messages,
|
|
31
47
|
abortSignal: args.signal,
|
|
32
|
-
|
|
33
|
-
tools: tools,
|
|
48
|
+
tools,
|
|
34
49
|
})
|
|
35
50
|
: streamText({
|
|
36
51
|
model: options.model,
|
|
@@ -38,16 +53,21 @@ export function vercelLlm(options) {
|
|
|
38
53
|
messages,
|
|
39
54
|
abortSignal: args.signal,
|
|
40
55
|
});
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
56
|
+
yield* Stream.fromAsyncIterable(result.fullStream, (cause) => new VercelLlmError(cause)).pipe(Stream.runForEach((part) => {
|
|
57
|
+
const delta = part.type === 'text-delta' && 'text' in part ? part.text : '';
|
|
58
|
+
return delta
|
|
59
|
+
? Effect.tryPromise({
|
|
60
|
+
try: () => Promise.resolve(args.onTextDelta?.(delta)),
|
|
61
|
+
catch: (cause) => new VercelLlmError(cause),
|
|
62
|
+
})
|
|
63
|
+
: Effect.void;
|
|
64
|
+
}));
|
|
65
|
+
const streamed = yield* Effect.tryPromise({
|
|
66
|
+
try: () => Promise.all([result.text, result.toolCalls]),
|
|
67
|
+
catch: (cause) => new VercelLlmError(cause),
|
|
68
|
+
}).pipe(Effect.asSome, Effect.catchIf((error) => error.message.includes('No output generated'), () => Effect.succeedNone));
|
|
69
|
+
if (Option.isSome(streamed)) {
|
|
70
|
+
const [text, rawToolCalls] = streamed.value;
|
|
51
71
|
const toolCalls = toLoomsToolCalls(rawToolCalls.map((call) => ({
|
|
52
72
|
toolCallId: call.toolCallId,
|
|
53
73
|
toolName: call.toolName,
|
|
@@ -59,26 +79,26 @@ export function vercelLlm(options) {
|
|
|
59
79
|
usage: { input: 0, output: text.length },
|
|
60
80
|
};
|
|
61
81
|
}
|
|
62
|
-
catch (err) {
|
|
63
|
-
if (!(err instanceof Error) || !err.message.includes('No output generated')) {
|
|
64
|
-
throw err;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
82
|
}
|
|
68
83
|
const result = tools
|
|
69
|
-
?
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
84
|
+
? yield* Effect.tryPromise({
|
|
85
|
+
try: () => generateText({
|
|
86
|
+
model: options.model,
|
|
87
|
+
instructions: args.instructions,
|
|
88
|
+
messages,
|
|
89
|
+
abortSignal: args.signal,
|
|
90
|
+
tools,
|
|
91
|
+
}),
|
|
92
|
+
catch: (cause) => new VercelLlmError(cause),
|
|
76
93
|
})
|
|
77
|
-
:
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
94
|
+
: yield* Effect.tryPromise({
|
|
95
|
+
try: () => generateText({
|
|
96
|
+
model: options.model,
|
|
97
|
+
instructions: args.instructions,
|
|
98
|
+
messages,
|
|
99
|
+
abortSignal: args.signal,
|
|
100
|
+
}),
|
|
101
|
+
catch: (cause) => new VercelLlmError(cause),
|
|
82
102
|
});
|
|
83
103
|
const toolCalls = toLoomsToolCalls(result.toolCalls.map((call) => ({
|
|
84
104
|
toolCallId: call.toolCallId,
|
|
@@ -93,6 +113,6 @@ export function vercelLlm(options) {
|
|
|
93
113
|
output: result.usage?.outputTokens ?? result.text.length,
|
|
94
114
|
},
|
|
95
115
|
};
|
|
96
|
-
},
|
|
116
|
+
})),
|
|
97
117
|
};
|
|
98
118
|
}
|