@swirls/looms 0.1.0 → 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 +15 -0
- package/dist/actor/host.js +2 -1
- 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.d.ts +3 -11
- package/dist/agent/definitions.js +5 -6
- package/dist/agent/signals.d.ts +2 -0
- package/dist/agent/signals.js +18 -16
- package/dist/agent/tool-schema.d.ts +1 -17
- package/dist/agent/tool-schema.js +3 -42
- package/dist/ai-vercel/index.d.ts +1 -1
- package/dist/ai-vercel/vercel-evaluator.d.ts +21 -8
- package/dist/ai-vercel/vercel-evaluator.js +7 -2
- 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/client/client.d.ts +18 -0
- package/dist/client/client.js +3 -1
- package/dist/cloudflare/router.d.ts +1 -1
- package/dist/cloudflare/router.js +2 -2
- package/dist/core/compose.js +1 -0
- package/dist/core/debugger-host.d.ts +16 -0
- package/dist/core/debugger-host.js +1 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +1 -0
- package/dist/core/module.d.ts +2 -0
- package/dist/core/published.d.ts +43 -0
- package/dist/core/published.js +44 -0
- package/dist/core/schema.d.ts +3 -1
- package/dist/core/schema.js +38 -0
- package/dist/core/snapshot-store.d.ts +4 -0
- package/dist/core/snapshot-store.js +7 -0
- package/dist/core/sqlite-store.js +39 -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 +12 -71
- 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 +29 -37
- 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 -11
- 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/react/store.d.ts +1 -1
- package/dist/react/store.js +1 -1
- package/dist/runtime/looms.d.ts +9 -1
- package/dist/runtime/looms.js +4 -2
- package/dist/runtime/repository.js +16 -1
- package/dist/runtime/runtime.js +16 -1
- package/dist/runtime/server/auth.d.ts +1 -0
- package/dist/runtime/server/auth.js +5 -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 +5 -1
- package/dist/runtime/server/fetch-handler.js +24 -13
- package/dist/runtime/server/http.d.ts +1 -0
- package/dist/runtime/server/http.js +4 -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/runs.js +8 -1
- package/dist/runtime/server.d.ts +3 -1
- package/dist/runtime/server.js +3 -1
- package/dist/runtime/types.d.ts +3 -1
- package/dist/s2/snapshot-store.js +43 -1
- 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/package.json +20 -1
- 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
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Effect } from 'effect';
|
|
2
|
+
import { publishDefinition } from '@swirls/looms/core';
|
|
3
|
+
import { route } from '../route-table.js';
|
|
4
|
+
export function definitionRoutes({ runtime }) {
|
|
5
|
+
return [
|
|
6
|
+
route({
|
|
7
|
+
method: 'GET',
|
|
8
|
+
path: '/definitions',
|
|
9
|
+
name: 'definitions.list',
|
|
10
|
+
access: 'read',
|
|
11
|
+
handle: () => {
|
|
12
|
+
const catalog = {
|
|
13
|
+
definitions: runtime.registry.definitions.map(publishDefinition),
|
|
14
|
+
projections: [...runtime.registry.projections.keys()],
|
|
15
|
+
};
|
|
16
|
+
return Effect.succeed(Response.json(catalog));
|
|
17
|
+
},
|
|
18
|
+
}),
|
|
19
|
+
];
|
|
20
|
+
}
|
|
@@ -72,7 +72,14 @@ export function runRoutes({ runtime, store }) {
|
|
|
72
72
|
path: '/runs',
|
|
73
73
|
name: 'runs.list',
|
|
74
74
|
access: 'read',
|
|
75
|
-
handle: () => provideStore(runtime.listRuns
|
|
75
|
+
handle: () => provideStore(runtime.listRuns.pipe(Effect.map((runIds) => Response.json({ runIds }))), store),
|
|
76
|
+
}),
|
|
77
|
+
route({
|
|
78
|
+
method: 'GET',
|
|
79
|
+
path: '/runs/summaries',
|
|
80
|
+
name: 'runs.summaries',
|
|
81
|
+
access: 'read',
|
|
82
|
+
handle: () => provideStore(runtime.listRunSummaries.pipe(Effect.map((runs) => Response.json({ runs }))), store),
|
|
76
83
|
}),
|
|
77
84
|
route({
|
|
78
85
|
method: 'POST',
|
package/dist/runtime/server.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
export { createFetchHandler,
|
|
1
|
+
export { createFetchHandler, handlesPath, type FetchHandlerOptions } from './server/fetch-handler';
|
|
2
|
+
export { isLoomsApiPath } from './server/http';
|
|
3
|
+
export { mountDebugger, type DebuggerMount } from './server/debugger-host';
|
|
2
4
|
export { authAllowed, authDenied, bearerAuth, defaultAuthorize, type AuthDecision, type AuthorizedAccess, type Authorize, type BearerTokens, type RouteAccess, type RouteInfo, } from './server/auth';
|
|
3
5
|
export interface RunningServer {
|
|
4
6
|
port: number;
|
package/dist/runtime/server.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
export { createFetchHandler,
|
|
1
|
+
export { createFetchHandler, handlesPath } from './server/fetch-handler.js';
|
|
2
|
+
export { isLoomsApiPath } from './server/http.js';
|
|
3
|
+
export { mountDebugger } from './server/debugger-host.js';
|
|
2
4
|
export { authAllowed, authDenied, bearerAuth, defaultAuthorize, } from './server/auth.js';
|
|
3
5
|
export function serveHttp(fetchHandler, options) {
|
|
4
6
|
const port = options?.port ?? 8787;
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Effect } from 'effect';
|
|
2
|
-
import type { AnyRuntimeModule, ComposedRegistry, EventEnvelope, EventInput, WorkerCallbackInput, EventStore, EventStoreAppendError, EventStoreError, EventStoreFencedError, EventStoreTag, EventStoreTrimCoverage, EventStoreTruncationError, JsonValue, ProjectionDefinition, ReplayStep, RunState, SnapshotStore } from '@swirls/looms/core';
|
|
2
|
+
import type { AnyRuntimeModule, ComposedRegistry, EventEnvelope, EventInput, WorkerCallbackInput, EventStore, EventStoreAppendError, EventStoreError, EventStoreFencedError, EventStoreTag, EventStoreTrimCoverage, EventStoreTruncationError, JsonValue, ProjectionDefinition, ReplayStep, RunState, RunSummary, SnapshotStore, SnapshotStoreError } from '@swirls/looms/core';
|
|
3
3
|
import type { EventStoreTrimmedError } from '@swirls/looms/core';
|
|
4
4
|
import type { DuplicateEffectDispatchError, MaxWakeIterationsError } from './errors';
|
|
5
5
|
import type { RuntimeObserver } from './observer';
|
|
@@ -108,6 +108,8 @@ export interface LoomsRuntime<TModules extends readonly AnyRuntimeModule[] = rea
|
|
|
108
108
|
/** Applies a worker's report about one effect attempt; stale or foreign reports are ignored. */
|
|
109
109
|
workerCallback(runId: string, input: WorkerCallbackInput): Effect.Effect<RunState, Error | EventStoreAppendError | EventStoreError, EventStoreTag>;
|
|
110
110
|
readonly listRuns: Effect.Effect<string[], EventStoreError, EventStoreTag>;
|
|
111
|
+
/** Indexed run rows. Folds a run only when its header has not been written yet. */
|
|
112
|
+
readonly listRunSummaries: Effect.Effect<readonly RunSummary[], EventStoreError | EventStoreTrimmedError | EventStoreTruncationError | SnapshotStoreError, EventStoreTag>;
|
|
111
113
|
readonly rescanTimers: Effect.Effect<number, EventStoreTruncationError | EventStoreTrimmedError | EventStoreError, EventStoreTag>;
|
|
112
114
|
/** Reschedule every durable timer and effect deadline after restart or repair. */
|
|
113
115
|
readonly recoverDeadlines: Effect.Effect<number, EventStoreTruncationError | EventStoreTrimmedError | EventStoreError, EventStoreTag>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AppendInput, AppendRecord, S2, S2Endpoints, S2Error } from '@s2-dev/streamstore';
|
|
2
2
|
import { Effect, Layer, Option, Schema, Stream } from 'effect';
|
|
3
|
-
import { createKeyedSerializer, assertSnapshotByteLimit, RunStateSchema, SnapshotStoreError, SnapshotPayloadTooLargeError, SnapshotStoreTag, } from '@swirls/looms/core';
|
|
3
|
+
import { createKeyedSerializer, assertSnapshotByteLimit, RunStateSchema, RunSummarySchema, SnapshotStoreError, SnapshotPayloadTooLargeError, SnapshotStoreTag, } from '@swirls/looms/core';
|
|
4
4
|
import { S2ConfigSchema } from './config.js';
|
|
5
5
|
import { paginateS2Stream } from './pagination.js';
|
|
6
6
|
const DEFAULT_PREFIX = 'snapshots';
|
|
@@ -18,6 +18,9 @@ const SnapshotFrameSchema = Schema.Struct({
|
|
|
18
18
|
const SnapshotFrameJson = Schema.fromJsonString(SnapshotFrameSchema);
|
|
19
19
|
const decodeFrame = Schema.decodeSync(SnapshotFrameJson);
|
|
20
20
|
const encodeFrame = Schema.encodeSync(SnapshotFrameJson);
|
|
21
|
+
const HeaderJson = Schema.fromJsonString(RunSummarySchema);
|
|
22
|
+
const decodeHeader = Schema.decodeUnknownOption(HeaderJson);
|
|
23
|
+
const encodeHeader = Schema.encodeSync(HeaderJson);
|
|
21
24
|
export function frameSnapshot(snapshot, maxChunkBytes = DEFAULT_MAX_CHUNK_BYTES) {
|
|
22
25
|
const json = JSON.stringify(snapshot.state);
|
|
23
26
|
const chunks = Math.max(1, Math.ceil(json.length / maxChunkBytes));
|
|
@@ -171,7 +174,9 @@ export function s2SnapshotStore(config) {
|
|
|
171
174
|
const prefix = parsed.snapshotPrefix ?? DEFAULT_PREFIX;
|
|
172
175
|
const appends = createKeyedSerializer();
|
|
173
176
|
const ensured = new Set();
|
|
177
|
+
const headers = new Map();
|
|
174
178
|
let basinEnsured = false;
|
|
179
|
+
let headersLoaded = false;
|
|
175
180
|
const streamName = (runId) => `${prefix}/${runId}`;
|
|
176
181
|
const ensureBasin = Effect.suspend(() => {
|
|
177
182
|
if (basinEnsured) {
|
|
@@ -297,6 +302,43 @@ export function s2SnapshotStore(config) {
|
|
|
297
302
|
catch: (cause) => toSnapshotError(cause, `Failed to prune snapshots for ${runId}`),
|
|
298
303
|
});
|
|
299
304
|
}),
|
|
305
|
+
saveHeader: (header) => Effect.gen(function* () {
|
|
306
|
+
const stream = yield* ensureStream('__headers');
|
|
307
|
+
yield* Effect.tryPromise({
|
|
308
|
+
try: () => appends.run('__headers', () => stream.append(AppendInput.create([AppendRecord.string({ body: encodeHeader(header) })]))),
|
|
309
|
+
catch: (cause) => toSnapshotError(cause, `Failed to save run header for ${header.runId}`),
|
|
310
|
+
});
|
|
311
|
+
headers.set(header.runId, header);
|
|
312
|
+
}),
|
|
313
|
+
listHeaders: Effect.gen(function* () {
|
|
314
|
+
if (headersLoaded) {
|
|
315
|
+
return [...headers.values()];
|
|
316
|
+
}
|
|
317
|
+
const stream = yield* ensureStream('__headers');
|
|
318
|
+
const records = yield* paginateS2Stream((cursor, count) => Effect.tryPromise({
|
|
319
|
+
try: () => stream.read({
|
|
320
|
+
start: { from: { seqNum: cursor }, clamp: true },
|
|
321
|
+
stop: { limits: { count } },
|
|
322
|
+
ignoreCommandRecords: true,
|
|
323
|
+
}),
|
|
324
|
+
catch: (cause) => toSnapshotError(cause, 'Failed to read run headers'),
|
|
325
|
+
}).pipe(Effect.catchIf((error) => error.cause instanceof S2Error &&
|
|
326
|
+
(error.cause.status === 404 || error.cause.status === 416), () => Effect.succeed(null)))).pipe(Stream.runCollect);
|
|
327
|
+
const loaded = new Map();
|
|
328
|
+
for (const record of records) {
|
|
329
|
+
const decoded = decodeHeader(record.body);
|
|
330
|
+
if (Option.isSome(decoded)) {
|
|
331
|
+
loaded.set(decoded.value.runId, decoded.value);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
for (const [runId, header] of loaded) {
|
|
335
|
+
if (!headers.has(runId)) {
|
|
336
|
+
headers.set(runId, header);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
headersLoaded = true;
|
|
340
|
+
return [...headers.values()];
|
|
341
|
+
}),
|
|
300
342
|
};
|
|
301
343
|
return service;
|
|
302
344
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { nodes } from '../projections.js';
|
|
2
|
+
import { WorkflowNodesView } from './nodes-view.js';
|
|
3
|
+
import { summarizeWorkflowEvent } from './summarize.js';
|
|
4
|
+
export const workflowDebugger = {
|
|
5
|
+
name: 'workflow',
|
|
6
|
+
families: [
|
|
7
|
+
{ family: 'workflow', color: 'oklch(0.76 0.12 300)', summarize: summarizeWorkflowEvent },
|
|
8
|
+
],
|
|
9
|
+
projections: [{ name: nodes.name, component: WorkflowNodesView }],
|
|
10
|
+
};
|
|
11
|
+
export { WorkflowNodesView };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { asJson } from '@swirls/looms/core';
|
|
3
|
+
import { JsonTree, StatusBadge } from '@swirls/looms/debugger';
|
|
4
|
+
import { useProjection, useRunStore } from '@swirls/looms/react';
|
|
5
|
+
import { nodes } from '../projections.js';
|
|
6
|
+
export function WorkflowNodesView({ runId }) {
|
|
7
|
+
const state = useProjection(useRunStore(runId), nodes);
|
|
8
|
+
const entries = Object.entries(state.nodes);
|
|
9
|
+
if (entries.length === 0) {
|
|
10
|
+
return _jsx("p", { className: "text-muted-foreground text-xs", children: "No nodes yet." });
|
|
11
|
+
}
|
|
12
|
+
return (_jsx("ul", { className: "grid gap-2", children: entries.map(([id, node]) => (_jsxs("li", { className: "border-border bg-card/60 rounded-lg border p-2.5 text-xs", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "min-w-0 flex-1 truncate font-mono font-medium", children: id }), _jsx(StatusBadge, { status: node.status })] }), node.result !== null ? (_jsx(JsonTree, { value: asJson(node.result), className: "mt-1.5" })) : null, node.error ? _jsx("p", { className: "text-status-failed mt-1.5", children: node.error }) : null] }, id))) }));
|
|
13
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { compactJson, jsonFields, jsonText, } from '@swirls/looms/debugger';
|
|
2
|
+
export function summarizeWorkflowEvent(event) {
|
|
3
|
+
const payload = jsonFields(event.payload);
|
|
4
|
+
switch (event.type) {
|
|
5
|
+
case 'workflow.node.started':
|
|
6
|
+
return { title: 'node started', detail: jsonText(payload.nodeId) };
|
|
7
|
+
case 'workflow.node.finished':
|
|
8
|
+
return {
|
|
9
|
+
title: jsonText(payload.error) ? 'node failed' : 'node finished',
|
|
10
|
+
detail: jsonText(payload.error) ??
|
|
11
|
+
`${jsonText(payload.nodeId) ?? ''} ${compactJson(payload.result ?? null)}`,
|
|
12
|
+
};
|
|
13
|
+
case 'workflow.node.skipped':
|
|
14
|
+
return {
|
|
15
|
+
title: 'node skipped',
|
|
16
|
+
detail: `${jsonText(payload.nodeId) ?? ''} · ${jsonText(payload.reason) ?? ''}`,
|
|
17
|
+
};
|
|
18
|
+
case 'workflow.spawn.requested':
|
|
19
|
+
return {
|
|
20
|
+
title: 'workflow spawn',
|
|
21
|
+
detail: `${jsonText(payload.definitionName) ?? 'unknown'} from ${jsonText(payload.nodeId) ?? ''}`,
|
|
22
|
+
};
|
|
23
|
+
case 'workflow.sleep.requested':
|
|
24
|
+
return { title: 'sleep', detail: jsonText(payload.nodeId) };
|
|
25
|
+
case 'workflow.effects.requested':
|
|
26
|
+
return { title: 'workflow effects', detail: jsonText(payload.nodeId) };
|
|
27
|
+
default:
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@swirls/looms",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Pluggable event-sourced runtime for durable agents and workflows",
|
|
5
5
|
"homepage": "https://github.com/ByteSliceHQ/looms#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -37,6 +37,10 @@
|
|
|
37
37
|
"types": "./dist/agent/index.d.ts",
|
|
38
38
|
"import": "./dist/agent/index.js"
|
|
39
39
|
},
|
|
40
|
+
"./agent/debugger": {
|
|
41
|
+
"types": "./dist/agent/debugger/index.d.ts",
|
|
42
|
+
"import": "./dist/agent/debugger/index.js"
|
|
43
|
+
},
|
|
40
44
|
"./ai-vercel": {
|
|
41
45
|
"types": "./dist/ai-vercel/index.d.ts",
|
|
42
46
|
"import": "./dist/ai-vercel/index.js"
|
|
@@ -45,6 +49,10 @@
|
|
|
45
49
|
"types": "./dist/approval/index.d.ts",
|
|
46
50
|
"import": "./dist/approval/index.js"
|
|
47
51
|
},
|
|
52
|
+
"./approval/debugger": {
|
|
53
|
+
"types": "./dist/approval/debugger/index.d.ts",
|
|
54
|
+
"import": "./dist/approval/debugger/index.js"
|
|
55
|
+
},
|
|
48
56
|
"./cli": {
|
|
49
57
|
"types": "./dist/cli/index.d.ts",
|
|
50
58
|
"import": "./dist/cli/index.js"
|
|
@@ -65,6 +73,10 @@
|
|
|
65
73
|
"types": "./dist/debugger/index.d.ts",
|
|
66
74
|
"import": "./dist/debugger/index.js"
|
|
67
75
|
},
|
|
76
|
+
"./debugger/server": {
|
|
77
|
+
"types": "./dist/debugger/server/index.d.ts",
|
|
78
|
+
"import": "./dist/debugger/server/index.js"
|
|
79
|
+
},
|
|
68
80
|
"./evaluator": {
|
|
69
81
|
"types": "./dist/evaluator/index.d.ts",
|
|
70
82
|
"import": "./dist/evaluator/index.js"
|
|
@@ -93,6 +105,10 @@
|
|
|
93
105
|
"types": "./dist/workflow/index.d.ts",
|
|
94
106
|
"import": "./dist/workflow/index.js"
|
|
95
107
|
},
|
|
108
|
+
"./workflow/debugger": {
|
|
109
|
+
"types": "./dist/workflow/debugger/index.d.ts",
|
|
110
|
+
"import": "./dist/workflow/debugger/index.js"
|
|
111
|
+
},
|
|
96
112
|
"./core/sqlite-store": {
|
|
97
113
|
"types": "./dist/core/sqlite-store.d.ts",
|
|
98
114
|
"import": "./dist/core/sqlite-store.js"
|
|
@@ -132,9 +148,11 @@
|
|
|
132
148
|
"@standard-schema/spec": "^1.1.0",
|
|
133
149
|
"@tanstack/react-virtual": "^3.14.11",
|
|
134
150
|
"clsx": "^2.1.1",
|
|
151
|
+
"cmdk": "^1.1.1",
|
|
135
152
|
"effect": "4.0.0-rc.112",
|
|
136
153
|
"lucide-react": "^1.43.0",
|
|
137
154
|
"radix-ui": "^1.6.7",
|
|
155
|
+
"react-resizable-panels": "^4.13.3",
|
|
138
156
|
"tailwind-merge": "^3.6.0"
|
|
139
157
|
},
|
|
140
158
|
"devDependencies": {
|
|
@@ -148,6 +166,7 @@
|
|
|
148
166
|
"@looms/cloudflare": "workspace:*",
|
|
149
167
|
"@looms/core": "workspace:*",
|
|
150
168
|
"@looms/debugger": "workspace:*",
|
|
169
|
+
"@looms/debugger-app": "workspace:*",
|
|
151
170
|
"@looms/evaluator": "workspace:*",
|
|
152
171
|
"@looms/projectors": "workspace:*",
|
|
153
172
|
"@looms/react": "workspace:*",
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { isJsonNumber, isJsonObject, isJsonString } from '@swirls/looms/core';
|
|
2
|
-
import { compactJson } from '../lib/cn.js';
|
|
3
|
-
function obj(value) {
|
|
4
|
-
return isJsonObject(value) ? value : {};
|
|
5
|
-
}
|
|
6
|
-
function text(value) {
|
|
7
|
-
return isJsonString(value) ? value : undefined;
|
|
8
|
-
}
|
|
9
|
-
function numeric(value) {
|
|
10
|
-
return isJsonNumber(value) ? String(value) : undefined;
|
|
11
|
-
}
|
|
12
|
-
function messageContent(payload) {
|
|
13
|
-
const message = obj(payload ?? null).message;
|
|
14
|
-
return isJsonObject(message) && isJsonString(message.content) ? message.content : undefined;
|
|
15
|
-
}
|
|
16
|
-
function toolCallSummary(payload) {
|
|
17
|
-
const call = obj(payload ?? null).toolCall;
|
|
18
|
-
if (!isJsonObject(call)) {
|
|
19
|
-
return { name: 'tool', args: null };
|
|
20
|
-
}
|
|
21
|
-
const summary = {
|
|
22
|
-
name: isJsonString(call.name) ? call.name : 'tool',
|
|
23
|
-
args: call.arguments ?? null,
|
|
24
|
-
};
|
|
25
|
-
return summary;
|
|
26
|
-
}
|
|
27
|
-
export function summarizeDomainEvent(event) {
|
|
28
|
-
const payload = obj(event.payload);
|
|
29
|
-
switch (event.type) {
|
|
30
|
-
case 'agent.message.received':
|
|
31
|
-
return { title: 'user message', detail: messageContent(event.payload) };
|
|
32
|
-
case 'agent.turn.started':
|
|
33
|
-
return { title: 'turn started', detail: `turn ${numeric(payload.turn) ?? ''}` };
|
|
34
|
-
case 'agent.turn.text_delta':
|
|
35
|
-
return { title: 'text delta', detail: text(payload.delta) };
|
|
36
|
-
case 'agent.message':
|
|
37
|
-
return { title: 'agent message', detail: messageContent(event.payload) };
|
|
38
|
-
case 'agent.tool_call.requested': {
|
|
39
|
-
const call = toolCallSummary(event.payload);
|
|
40
|
-
return { title: `tool ${call.name}`, detail: compactJson(call.args) };
|
|
41
|
-
}
|
|
42
|
-
case 'agent.tool.result':
|
|
43
|
-
return {
|
|
44
|
-
title: text(payload.error)
|
|
45
|
-
? `tool error ${text(payload.name)}`
|
|
46
|
-
: `tool result ${text(payload.name)}`,
|
|
47
|
-
detail: text(payload.error) ?? compactJson(payload.result ?? null),
|
|
48
|
-
};
|
|
49
|
-
case 'agent.steered':
|
|
50
|
-
return { title: 'steered', detail: messageContent(event.payload) };
|
|
51
|
-
case 'agent.spawn.requested':
|
|
52
|
-
return {
|
|
53
|
-
title: 'agent spawn',
|
|
54
|
-
detail: `${text(payload.kind) ?? 'agent'}:${text(payload.definitionName) ?? 'unknown'}`,
|
|
55
|
-
};
|
|
56
|
-
case 'agent.effects.requested':
|
|
57
|
-
return { title: 'agent effects', detail: text(payload.toolCallId) };
|
|
58
|
-
case 'workflow.node.started':
|
|
59
|
-
return { title: 'node started', detail: text(payload.nodeId) };
|
|
60
|
-
case 'workflow.node.finished':
|
|
61
|
-
return {
|
|
62
|
-
title: text(payload.error) ? 'node failed' : 'node finished',
|
|
63
|
-
detail: text(payload.error) ??
|
|
64
|
-
`${text(payload.nodeId) ?? ''} ${compactJson(payload.result ?? null)}`,
|
|
65
|
-
};
|
|
66
|
-
case 'workflow.node.skipped':
|
|
67
|
-
return {
|
|
68
|
-
title: 'node skipped',
|
|
69
|
-
detail: `${text(payload.nodeId) ?? ''} · ${text(payload.reason) ?? ''}`,
|
|
70
|
-
};
|
|
71
|
-
case 'workflow.spawn.requested':
|
|
72
|
-
return {
|
|
73
|
-
title: 'workflow spawn',
|
|
74
|
-
detail: `${text(payload.definitionName) ?? 'unknown'} from ${text(payload.nodeId) ?? ''}`,
|
|
75
|
-
};
|
|
76
|
-
case 'workflow.sleep.requested':
|
|
77
|
-
return { title: 'sleep', detail: text(payload.nodeId) };
|
|
78
|
-
case 'workflow.effects.requested':
|
|
79
|
-
return { title: 'workflow effects', detail: text(payload.nodeId) };
|
|
80
|
-
case 'approval.requested':
|
|
81
|
-
return { title: 'approval requested', detail: text(payload.title) };
|
|
82
|
-
case 'approval.decided':
|
|
83
|
-
return {
|
|
84
|
-
title: `approval ${text(payload.outcome) ?? 'decided'}`,
|
|
85
|
-
detail: text(payload.approvalId),
|
|
86
|
-
};
|
|
87
|
-
case 'approval.timed_out':
|
|
88
|
-
return { title: 'approval timed out', detail: text(payload.approvalId) };
|
|
89
|
-
case 'payments.charge.requested':
|
|
90
|
-
return {
|
|
91
|
-
title: 'charge requested',
|
|
92
|
-
detail: `${numeric(payload.amount) ?? ''} ${text(payload.currency) ?? ''}`.trim(),
|
|
93
|
-
};
|
|
94
|
-
case 'payments.charge.authorized':
|
|
95
|
-
return {
|
|
96
|
-
title: 'charge authorized',
|
|
97
|
-
detail: `${numeric(payload.amount) ?? ''} ${text(payload.currency) ?? ''}`.trim(),
|
|
98
|
-
};
|
|
99
|
-
case 'payments.charge.declined':
|
|
100
|
-
return {
|
|
101
|
-
title: 'charge declined',
|
|
102
|
-
detail: `${numeric(payload.amount) ?? ''} ${text(payload.currency) ?? ''} · ${text(payload.reason) ?? ''}`.trim(),
|
|
103
|
-
};
|
|
104
|
-
default:
|
|
105
|
-
return undefined;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export declare const DEFAULT_FAMILIES: readonly ['runtime', 'agent', 'workflow', 'approval', 'payments', 'wait'];
|
|
2
|
-
export type EventFamily = (typeof DEFAULT_FAMILIES)[number];
|
|
3
|
-
export type EventSummary = {
|
|
4
|
-
title: string;
|
|
5
|
-
detail?: string;
|
|
6
|
-
};
|
|
7
|
-
export declare function familyFromPrefix(type: string): EventFamily;
|
|
8
|
-
export declare function familyClass(family: string): string;
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
export const DEFAULT_FAMILIES = [
|
|
2
|
-
'runtime',
|
|
3
|
-
'agent',
|
|
4
|
-
'workflow',
|
|
5
|
-
'approval',
|
|
6
|
-
'payments',
|
|
7
|
-
'wait',
|
|
8
|
-
];
|
|
9
|
-
export function familyFromPrefix(type) {
|
|
10
|
-
if (type.startsWith('agent.')) {
|
|
11
|
-
return 'agent';
|
|
12
|
-
}
|
|
13
|
-
if (type.startsWith('workflow.')) {
|
|
14
|
-
return 'workflow';
|
|
15
|
-
}
|
|
16
|
-
if (type.startsWith('approval.')) {
|
|
17
|
-
return 'approval';
|
|
18
|
-
}
|
|
19
|
-
if (type.startsWith('payments.')) {
|
|
20
|
-
return 'payments';
|
|
21
|
-
}
|
|
22
|
-
if (type.startsWith('runtime.wait')) {
|
|
23
|
-
return 'wait';
|
|
24
|
-
}
|
|
25
|
-
return 'runtime';
|
|
26
|
-
}
|
|
27
|
-
export function familyClass(family) {
|
|
28
|
-
switch (family) {
|
|
29
|
-
case 'agent':
|
|
30
|
-
return 'bg-family-agent';
|
|
31
|
-
case 'workflow':
|
|
32
|
-
return 'bg-family-workflow';
|
|
33
|
-
case 'approval':
|
|
34
|
-
return 'bg-family-approval';
|
|
35
|
-
case 'payments':
|
|
36
|
-
return 'bg-family-payments';
|
|
37
|
-
case 'wait':
|
|
38
|
-
return 'bg-family-wait';
|
|
39
|
-
case 'runtime':
|
|
40
|
-
return 'bg-family-runtime';
|
|
41
|
-
default:
|
|
42
|
-
return 'bg-family-runtime';
|
|
43
|
-
}
|
|
44
|
-
}
|