@swirls/looms 0.2.0 → 0.4.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 +31 -0
- package/dist/actor/host.js +4 -6
- package/dist/actor/index.d.ts +1 -1
- package/dist/actor/index.js +1 -1
- package/dist/actor/routing.d.ts +5 -0
- package/dist/actor/routing.js +14 -0
- package/dist/agent/agent-session.js +1 -0
- package/dist/agent/debugger/agent-chat.js +45 -38
- package/dist/agent/debugger/streaming-text.d.ts +6 -0
- package/dist/agent/debugger/streaming-text.js +33 -0
- package/dist/agent/debugger/summarize.js +2 -0
- package/dist/agent/effects.d.ts +30 -0
- package/dist/agent/events.d.ts +2 -0
- package/dist/agent/events.js +2 -0
- package/dist/agent/llm.js +1 -8
- package/dist/agent/module.d.ts +230 -160
- package/dist/agent/module.js +11 -7
- package/dist/agent/projections.d.ts +5 -0
- package/dist/agent/projections.js +43 -2
- package/dist/agent/scope.d.ts +2 -0
- package/dist/agent/signals.d.ts +5 -0
- package/dist/agent/signals.js +7 -0
- package/dist/agent/threads.js +35 -21
- package/dist/agent/transcript.d.ts +7 -0
- package/dist/agent/transcript.js +19 -0
- package/dist/agent/types.d.ts +10 -0
- package/dist/agent/types.js +4 -0
- package/dist/approval/debugger/approvals-view.js +5 -3
- package/dist/approval/effects.d.ts +12 -0
- package/dist/approval/module.d.ts +24 -0
- package/dist/client/client.d.ts +292 -0
- package/dist/client/client.js +17 -1
- package/dist/cloudflare/router.d.ts +1 -1
- package/dist/cloudflare/router.js +6 -8
- package/dist/core/attempts.d.ts +8 -0
- package/dist/core/attempts.js +27 -0
- package/dist/core/effects.d.ts +7 -0
- package/dist/core/effects.js +1 -0
- package/dist/core/fold.js +12 -6
- package/dist/core/fork.d.ts +35 -0
- package/dist/core/fork.js +129 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.js +2 -0
- package/dist/core/module-scope.d.ts +1 -0
- package/dist/core/module.d.ts +2 -2
- package/dist/core/projection.d.ts +5 -4
- package/dist/core/projection.js +1 -0
- package/dist/core/protocol.d.ts +10 -1
- package/dist/core/protocol.js +11 -0
- package/dist/{react → core}/register.d.ts +9 -8
- package/dist/core/replay.d.ts +8 -0
- package/dist/core/snapshots.js +3 -17
- package/dist/core/state.d.ts +14 -0
- package/dist/core/state.js +25 -2
- package/dist/core/store.d.ts +1 -0
- package/dist/debugger/app/assets/index-CgDzWJg7.css +2 -0
- package/dist/debugger/app/assets/index-D--9esm9.js +22 -0
- package/dist/debugger/app/assets/routes-Dakrdusf.js +47 -0
- package/dist/debugger/app/index.html +2 -2
- package/dist/debugger/components/composer.d.ts +5 -2
- package/dist/debugger/components/composer.js +5 -4
- package/dist/debugger/components/run-tree.js +2 -5
- package/dist/debugger/events/catalog.js +1 -3
- package/dist/debugger/events/protocol-summarize.js +7 -0
- package/dist/debugger/lib/event-counts.d.ts +2 -2
- package/dist/debugger/lib/event-counts.js +5 -9
- package/dist/debugger/shell/debugger-shell.js +1 -1
- package/dist/debugger/shell/run-controls.d.ts +2 -1
- package/dist/debugger/shell/run-controls.js +40 -13
- package/dist/debugger/shell/run-search.js +1 -3
- package/dist/evaluator/effects.d.ts +45 -33
- package/dist/evaluator/module.d.ts +90 -66
- package/dist/projectors/index-model.d.ts +13 -7
- package/dist/projectors/index-model.js +21 -26
- package/dist/projectors/memory.js +19 -11
- package/dist/projectors/postgres.js +20 -19
- package/dist/projectors/schema.js +20 -18
- package/dist/projectors/sqlite.js +32 -27
- package/dist/react/derived.d.ts +26 -8
- package/dist/react/derived.js +23 -26
- package/dist/react/index.d.ts +3 -3
- package/dist/react/index.js +2 -2
- package/dist/react/materialize.js +16 -11
- package/dist/react/react.d.ts +12 -9
- package/dist/react/react.js +9 -6
- package/dist/react/store.d.ts +4 -5
- package/dist/react/tables.d.ts +3 -2
- package/dist/runtime/cancellation.js +14 -27
- package/dist/runtime/errors.d.ts +39 -0
- package/dist/runtime/errors.js +32 -0
- package/dist/runtime/helpers.d.ts +2 -0
- package/dist/runtime/helpers.js +23 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/looms.d.ts +4 -0
- package/dist/runtime/looms.js +1 -0
- package/dist/runtime/run-start.js +1 -3
- package/dist/runtime/runtime.d.ts +1 -1
- package/dist/runtime/runtime.js +45 -18
- package/dist/runtime/server/http.d.ts +2 -0
- package/dist/runtime/server/http.js +17 -2
- package/dist/runtime/server/routes/runs.js +35 -2
- package/dist/runtime/types.d.ts +8 -0
- package/dist/runtime/wake-engine.js +5 -2
- package/dist/s2/snapshot-store.js +2 -6
- package/dist/workflow/effects.d.ts +24 -0
- package/dist/workflow/effects.js +1 -0
- package/dist/workflow/module.d.ts +48 -0
- package/package.json +2 -2
- package/dist/debugger/app/assets/index-B3Ah8WAE.css +0 -2
- package/dist/debugger/app/assets/index-Qb371t_O.js +0 -22
- package/dist/debugger/app/assets/routes-CjtEHgPQ.js +0 -47
- /package/dist/{react → core}/register.js +0 -0
package/dist/client/client.d.ts
CHANGED
|
@@ -37,6 +37,10 @@ export declare function createLoomsClient(options?: LoomsClientOptions): {
|
|
|
37
37
|
readonly idempotencyKey: string | null;
|
|
38
38
|
readonly rootThreadId: string;
|
|
39
39
|
} | null;
|
|
40
|
+
readonly forkedFrom: {
|
|
41
|
+
readonly runId: string;
|
|
42
|
+
readonly seq: number;
|
|
43
|
+
} | null;
|
|
40
44
|
readonly threads: {
|
|
41
45
|
readonly [x: string]: {
|
|
42
46
|
readonly threadId: string;
|
|
@@ -160,6 +164,10 @@ export declare function createLoomsClient(options?: LoomsClientOptions): {
|
|
|
160
164
|
readonly idempotencyKey: string | null;
|
|
161
165
|
readonly rootThreadId: string;
|
|
162
166
|
} | null;
|
|
167
|
+
readonly forkedFrom: {
|
|
168
|
+
readonly runId: string;
|
|
169
|
+
readonly seq: number;
|
|
170
|
+
} | null;
|
|
163
171
|
readonly threads: {
|
|
164
172
|
readonly [x: string]: {
|
|
165
173
|
readonly threadId: string;
|
|
@@ -281,6 +289,10 @@ export declare function createLoomsClient(options?: LoomsClientOptions): {
|
|
|
281
289
|
readonly idempotencyKey: string | null;
|
|
282
290
|
readonly rootThreadId: string;
|
|
283
291
|
} | null;
|
|
292
|
+
readonly forkedFrom: {
|
|
293
|
+
readonly runId: string;
|
|
294
|
+
readonly seq: number;
|
|
295
|
+
} | null;
|
|
284
296
|
readonly threads: {
|
|
285
297
|
readonly [x: string]: {
|
|
286
298
|
readonly threadId: string;
|
|
@@ -402,6 +414,10 @@ export declare function createLoomsClient(options?: LoomsClientOptions): {
|
|
|
402
414
|
readonly idempotencyKey: string | null;
|
|
403
415
|
readonly rootThreadId: string;
|
|
404
416
|
} | null;
|
|
417
|
+
readonly forkedFrom: {
|
|
418
|
+
readonly runId: string;
|
|
419
|
+
readonly seq: number;
|
|
420
|
+
} | null;
|
|
405
421
|
readonly threads: {
|
|
406
422
|
readonly [x: string]: {
|
|
407
423
|
readonly threadId: string;
|
|
@@ -553,6 +569,10 @@ export declare function createLoomsClient(options?: LoomsClientOptions): {
|
|
|
553
569
|
readonly idempotencyKey: string | null;
|
|
554
570
|
readonly rootThreadId: string;
|
|
555
571
|
} | null;
|
|
572
|
+
readonly forkedFrom: {
|
|
573
|
+
readonly runId: string;
|
|
574
|
+
readonly seq: number;
|
|
575
|
+
} | null;
|
|
556
576
|
readonly threads: {
|
|
557
577
|
readonly [x: string]: {
|
|
558
578
|
readonly threadId: string;
|
|
@@ -674,6 +694,266 @@ export declare function createLoomsClient(options?: LoomsClientOptions): {
|
|
|
674
694
|
readonly idempotencyKey: string | null;
|
|
675
695
|
readonly rootThreadId: string;
|
|
676
696
|
} | null;
|
|
697
|
+
readonly forkedFrom: {
|
|
698
|
+
readonly runId: string;
|
|
699
|
+
readonly seq: number;
|
|
700
|
+
} | null;
|
|
701
|
+
readonly threads: {
|
|
702
|
+
readonly [x: string]: {
|
|
703
|
+
readonly threadId: string;
|
|
704
|
+
readonly kind: string;
|
|
705
|
+
readonly definitionName: string;
|
|
706
|
+
readonly definitionVersion: string;
|
|
707
|
+
readonly parentThreadId: string | null;
|
|
708
|
+
readonly status: "cancelled" | "completed" | "failed" | "running" | "waiting";
|
|
709
|
+
readonly input: Schema.Json;
|
|
710
|
+
readonly output: Schema.Json;
|
|
711
|
+
readonly error: string | null;
|
|
712
|
+
readonly state: Schema.Json;
|
|
713
|
+
};
|
|
714
|
+
};
|
|
715
|
+
readonly waits: {
|
|
716
|
+
readonly [x: string]: {
|
|
717
|
+
readonly waitId: string;
|
|
718
|
+
readonly threadId: string;
|
|
719
|
+
readonly on: {
|
|
720
|
+
readonly type: string | readonly string[];
|
|
721
|
+
readonly match?: Schema.Json | undefined;
|
|
722
|
+
} | {
|
|
723
|
+
readonly timerAt: number;
|
|
724
|
+
};
|
|
725
|
+
readonly tag?: Schema.Json | undefined;
|
|
726
|
+
};
|
|
727
|
+
};
|
|
728
|
+
readonly outstandingEffects: readonly {
|
|
729
|
+
readonly effectId: string;
|
|
730
|
+
readonly threadId: string;
|
|
731
|
+
readonly causingSeq: number;
|
|
732
|
+
readonly causingEventId: string;
|
|
733
|
+
readonly effect: {
|
|
734
|
+
readonly type: "runtime.spawn";
|
|
735
|
+
readonly childThreadId: string;
|
|
736
|
+
readonly kind: string;
|
|
737
|
+
readonly definitionName: string;
|
|
738
|
+
readonly definitionVersion: string;
|
|
739
|
+
readonly input: Schema.Json;
|
|
740
|
+
} | {
|
|
741
|
+
readonly type: "runtime.wait";
|
|
742
|
+
readonly waitId: string;
|
|
743
|
+
readonly on: {
|
|
744
|
+
readonly type: string | readonly string[];
|
|
745
|
+
readonly match?: Schema.Json | undefined;
|
|
746
|
+
} | {
|
|
747
|
+
readonly timerAt: number;
|
|
748
|
+
};
|
|
749
|
+
readonly tag?: Schema.Json | undefined;
|
|
750
|
+
} | {
|
|
751
|
+
readonly type: "runtime.emit";
|
|
752
|
+
readonly event: {
|
|
753
|
+
readonly type: string;
|
|
754
|
+
readonly payload: Schema.Json;
|
|
755
|
+
readonly threadId?: string | null | undefined;
|
|
756
|
+
readonly parentThreadId?: string | null | undefined;
|
|
757
|
+
readonly causationId?: string | null | undefined;
|
|
758
|
+
readonly correlationId?: string | null | undefined;
|
|
759
|
+
readonly effectId?: string | null | undefined;
|
|
760
|
+
readonly origin?: {
|
|
761
|
+
readonly type: "thread";
|
|
762
|
+
readonly threadId: string;
|
|
763
|
+
} | {
|
|
764
|
+
readonly type: "external";
|
|
765
|
+
readonly actorId?: string | undefined;
|
|
766
|
+
} | {
|
|
767
|
+
readonly type: "system";
|
|
768
|
+
} | undefined;
|
|
769
|
+
readonly ephemeral?: boolean | undefined;
|
|
770
|
+
readonly id?: string | undefined;
|
|
771
|
+
readonly ts?: number | undefined;
|
|
772
|
+
readonly idempotencyKey?: string | null | undefined;
|
|
773
|
+
};
|
|
774
|
+
readonly tag?: string | undefined;
|
|
775
|
+
} | {
|
|
776
|
+
readonly type: "runtime.complete";
|
|
777
|
+
readonly output: Schema.Json;
|
|
778
|
+
} | {
|
|
779
|
+
readonly type: "runtime.fail";
|
|
780
|
+
readonly error: string;
|
|
781
|
+
} | {
|
|
782
|
+
readonly type: "runtime.cancel";
|
|
783
|
+
readonly threadId: string;
|
|
784
|
+
readonly tag?: string | undefined;
|
|
785
|
+
} | {
|
|
786
|
+
readonly type: string;
|
|
787
|
+
readonly input: Schema.Json;
|
|
788
|
+
readonly tag?: string | undefined;
|
|
789
|
+
};
|
|
790
|
+
}[];
|
|
791
|
+
readonly effectExecutions: {
|
|
792
|
+
readonly [x: string]: {
|
|
793
|
+
readonly effectId: string;
|
|
794
|
+
readonly attempt: number;
|
|
795
|
+
readonly status: "ambiguous" | "cancel_requested" | "dispatched" | "heartbeat" | "queued" | "retry_wait" | "running" | "started" | "timed_out";
|
|
796
|
+
readonly nextAttemptAt: number | null;
|
|
797
|
+
readonly deadlineAt: number | null;
|
|
798
|
+
readonly startedAt: number | null;
|
|
799
|
+
readonly lastHeartbeatAt: number | null;
|
|
800
|
+
readonly lastError: string | null;
|
|
801
|
+
};
|
|
802
|
+
};
|
|
803
|
+
readonly completedEffectIds: readonly string[];
|
|
804
|
+
readonly processedIdempotencyKeys: readonly string[];
|
|
805
|
+
};
|
|
806
|
+
readonly appended: number;
|
|
807
|
+
}>;
|
|
808
|
+
/** Cancel a thread and its descendants; omit `threadId` to cancel the whole run. */
|
|
809
|
+
cancel: (runId: string, threadId?: string) => Promise<{
|
|
810
|
+
readonly runId: string;
|
|
811
|
+
readonly state: {
|
|
812
|
+
readonly runId: string;
|
|
813
|
+
readonly status: "cancelled" | "completed" | "failed" | "running";
|
|
814
|
+
readonly rootThreadId: string | null;
|
|
815
|
+
readonly startIdentity: {
|
|
816
|
+
readonly kind: string;
|
|
817
|
+
readonly definitionName: string;
|
|
818
|
+
readonly definitionVersion: string;
|
|
819
|
+
readonly input: Schema.Json;
|
|
820
|
+
readonly requestedThreadId: string | null;
|
|
821
|
+
readonly idempotencyKey: string | null;
|
|
822
|
+
readonly rootThreadId: string;
|
|
823
|
+
} | null;
|
|
824
|
+
readonly forkedFrom: {
|
|
825
|
+
readonly runId: string;
|
|
826
|
+
readonly seq: number;
|
|
827
|
+
} | null;
|
|
828
|
+
readonly threads: {
|
|
829
|
+
readonly [x: string]: {
|
|
830
|
+
readonly threadId: string;
|
|
831
|
+
readonly kind: string;
|
|
832
|
+
readonly definitionName: string;
|
|
833
|
+
readonly definitionVersion: string;
|
|
834
|
+
readonly parentThreadId: string | null;
|
|
835
|
+
readonly status: "cancelled" | "completed" | "failed" | "running" | "waiting";
|
|
836
|
+
readonly input: Schema.Json;
|
|
837
|
+
readonly output: Schema.Json;
|
|
838
|
+
readonly error: string | null;
|
|
839
|
+
readonly state: Schema.Json;
|
|
840
|
+
};
|
|
841
|
+
};
|
|
842
|
+
readonly waits: {
|
|
843
|
+
readonly [x: string]: {
|
|
844
|
+
readonly waitId: string;
|
|
845
|
+
readonly threadId: string;
|
|
846
|
+
readonly on: {
|
|
847
|
+
readonly type: string | readonly string[];
|
|
848
|
+
readonly match?: Schema.Json | undefined;
|
|
849
|
+
} | {
|
|
850
|
+
readonly timerAt: number;
|
|
851
|
+
};
|
|
852
|
+
readonly tag?: Schema.Json | undefined;
|
|
853
|
+
};
|
|
854
|
+
};
|
|
855
|
+
readonly outstandingEffects: readonly {
|
|
856
|
+
readonly effectId: string;
|
|
857
|
+
readonly threadId: string;
|
|
858
|
+
readonly causingSeq: number;
|
|
859
|
+
readonly causingEventId: string;
|
|
860
|
+
readonly effect: {
|
|
861
|
+
readonly type: "runtime.spawn";
|
|
862
|
+
readonly childThreadId: string;
|
|
863
|
+
readonly kind: string;
|
|
864
|
+
readonly definitionName: string;
|
|
865
|
+
readonly definitionVersion: string;
|
|
866
|
+
readonly input: Schema.Json;
|
|
867
|
+
} | {
|
|
868
|
+
readonly type: "runtime.wait";
|
|
869
|
+
readonly waitId: string;
|
|
870
|
+
readonly on: {
|
|
871
|
+
readonly type: string | readonly string[];
|
|
872
|
+
readonly match?: Schema.Json | undefined;
|
|
873
|
+
} | {
|
|
874
|
+
readonly timerAt: number;
|
|
875
|
+
};
|
|
876
|
+
readonly tag?: Schema.Json | undefined;
|
|
877
|
+
} | {
|
|
878
|
+
readonly type: "runtime.emit";
|
|
879
|
+
readonly event: {
|
|
880
|
+
readonly type: string;
|
|
881
|
+
readonly payload: Schema.Json;
|
|
882
|
+
readonly threadId?: string | null | undefined;
|
|
883
|
+
readonly parentThreadId?: string | null | undefined;
|
|
884
|
+
readonly causationId?: string | null | undefined;
|
|
885
|
+
readonly correlationId?: string | null | undefined;
|
|
886
|
+
readonly effectId?: string | null | undefined;
|
|
887
|
+
readonly origin?: {
|
|
888
|
+
readonly type: "thread";
|
|
889
|
+
readonly threadId: string;
|
|
890
|
+
} | {
|
|
891
|
+
readonly type: "external";
|
|
892
|
+
readonly actorId?: string | undefined;
|
|
893
|
+
} | {
|
|
894
|
+
readonly type: "system";
|
|
895
|
+
} | undefined;
|
|
896
|
+
readonly ephemeral?: boolean | undefined;
|
|
897
|
+
readonly id?: string | undefined;
|
|
898
|
+
readonly ts?: number | undefined;
|
|
899
|
+
readonly idempotencyKey?: string | null | undefined;
|
|
900
|
+
};
|
|
901
|
+
readonly tag?: string | undefined;
|
|
902
|
+
} | {
|
|
903
|
+
readonly type: "runtime.complete";
|
|
904
|
+
readonly output: Schema.Json;
|
|
905
|
+
} | {
|
|
906
|
+
readonly type: "runtime.fail";
|
|
907
|
+
readonly error: string;
|
|
908
|
+
} | {
|
|
909
|
+
readonly type: "runtime.cancel";
|
|
910
|
+
readonly threadId: string;
|
|
911
|
+
readonly tag?: string | undefined;
|
|
912
|
+
} | {
|
|
913
|
+
readonly type: string;
|
|
914
|
+
readonly input: Schema.Json;
|
|
915
|
+
readonly tag?: string | undefined;
|
|
916
|
+
};
|
|
917
|
+
}[];
|
|
918
|
+
readonly effectExecutions: {
|
|
919
|
+
readonly [x: string]: {
|
|
920
|
+
readonly effectId: string;
|
|
921
|
+
readonly attempt: number;
|
|
922
|
+
readonly status: "ambiguous" | "cancel_requested" | "dispatched" | "heartbeat" | "queued" | "retry_wait" | "running" | "started" | "timed_out";
|
|
923
|
+
readonly nextAttemptAt: number | null;
|
|
924
|
+
readonly deadlineAt: number | null;
|
|
925
|
+
readonly startedAt: number | null;
|
|
926
|
+
readonly lastHeartbeatAt: number | null;
|
|
927
|
+
readonly lastError: string | null;
|
|
928
|
+
};
|
|
929
|
+
};
|
|
930
|
+
readonly completedEffectIds: readonly string[];
|
|
931
|
+
readonly processedIdempotencyKeys: readonly string[];
|
|
932
|
+
};
|
|
933
|
+
}>;
|
|
934
|
+
/** Start a new run that continues where a finished run ended. */
|
|
935
|
+
fork: (sourceRunId: string, forkOptions?: {
|
|
936
|
+
runId?: string;
|
|
937
|
+
}) => Promise<{
|
|
938
|
+
readonly runId: string;
|
|
939
|
+
readonly threadId: string;
|
|
940
|
+
readonly state: {
|
|
941
|
+
readonly runId: string;
|
|
942
|
+
readonly status: "cancelled" | "completed" | "failed" | "running";
|
|
943
|
+
readonly rootThreadId: string | null;
|
|
944
|
+
readonly startIdentity: {
|
|
945
|
+
readonly kind: string;
|
|
946
|
+
readonly definitionName: string;
|
|
947
|
+
readonly definitionVersion: string;
|
|
948
|
+
readonly input: Schema.Json;
|
|
949
|
+
readonly requestedThreadId: string | null;
|
|
950
|
+
readonly idempotencyKey: string | null;
|
|
951
|
+
readonly rootThreadId: string;
|
|
952
|
+
} | null;
|
|
953
|
+
readonly forkedFrom: {
|
|
954
|
+
readonly runId: string;
|
|
955
|
+
readonly seq: number;
|
|
956
|
+
} | null;
|
|
677
957
|
readonly threads: {
|
|
678
958
|
readonly [x: string]: {
|
|
679
959
|
readonly threadId: string;
|
|
@@ -795,6 +1075,10 @@ export declare function createLoomsClient(options?: LoomsClientOptions): {
|
|
|
795
1075
|
readonly idempotencyKey: string | null;
|
|
796
1076
|
readonly rootThreadId: string;
|
|
797
1077
|
} | null;
|
|
1078
|
+
readonly forkedFrom: {
|
|
1079
|
+
readonly runId: string;
|
|
1080
|
+
readonly seq: number;
|
|
1081
|
+
} | null;
|
|
798
1082
|
readonly threads: {
|
|
799
1083
|
readonly [x: string]: {
|
|
800
1084
|
readonly threadId: string;
|
|
@@ -960,6 +1244,10 @@ export declare function createLoomsClient(options?: LoomsClientOptions): {
|
|
|
960
1244
|
readonly idempotencyKey: string | null;
|
|
961
1245
|
readonly rootThreadId: string;
|
|
962
1246
|
} | null;
|
|
1247
|
+
readonly forkedFrom: {
|
|
1248
|
+
readonly runId: string;
|
|
1249
|
+
readonly seq: number;
|
|
1250
|
+
} | null;
|
|
963
1251
|
readonly threads: {
|
|
964
1252
|
readonly [x: string]: {
|
|
965
1253
|
readonly threadId: string;
|
|
@@ -1078,6 +1366,10 @@ export declare function createLoomsClient(options?: LoomsClientOptions): {
|
|
|
1078
1366
|
readonly idempotencyKey: string | null;
|
|
1079
1367
|
readonly rootThreadId: string;
|
|
1080
1368
|
} | null;
|
|
1369
|
+
readonly forkedFrom: {
|
|
1370
|
+
readonly runId: string;
|
|
1371
|
+
readonly seq: number;
|
|
1372
|
+
} | null;
|
|
1081
1373
|
readonly threads: {
|
|
1082
1374
|
readonly [x: string]: {
|
|
1083
1375
|
readonly threadId: string;
|
package/dist/client/client.js
CHANGED
|
@@ -14,6 +14,12 @@ const StartResultSchema = Schema.Struct({
|
|
|
14
14
|
state: RunStateSchema,
|
|
15
15
|
});
|
|
16
16
|
const RunResultSchema = Schema.Struct({ runId: Schema.String, state: RunStateSchema });
|
|
17
|
+
/** `appended` counts the events the run gained while the wake ran. */
|
|
18
|
+
const WakeResultSchema = Schema.Struct({
|
|
19
|
+
runId: Schema.String,
|
|
20
|
+
state: RunStateSchema,
|
|
21
|
+
appended: Schema.Finite,
|
|
22
|
+
});
|
|
17
23
|
const EventsResultSchema = Schema.Struct({
|
|
18
24
|
runId: Schema.String,
|
|
19
25
|
events: Schema.Array(EventEnvelopeSchema),
|
|
@@ -157,7 +163,17 @@ export function createLoomsClient(options = {}) {
|
|
|
157
163
|
method: 'POST',
|
|
158
164
|
body: stringifyJson({ events }),
|
|
159
165
|
}),
|
|
160
|
-
wake: (runId) => request(`/runs/${encodeURIComponent(runId)}/wake`,
|
|
166
|
+
wake: (runId) => request(`/runs/${encodeURIComponent(runId)}/wake`, WakeResultSchema, { method: 'POST' }),
|
|
167
|
+
/** Cancel a thread and its descendants; omit `threadId` to cancel the whole run. */
|
|
168
|
+
cancel: (runId, threadId) => request(`/runs/${encodeURIComponent(runId)}/cancel`, RunResultSchema, {
|
|
169
|
+
method: 'POST',
|
|
170
|
+
body: stringifyJson(threadId === undefined ? {} : { threadId }),
|
|
171
|
+
}),
|
|
172
|
+
/** Start a new run that continues where a finished run ended. */
|
|
173
|
+
fork: (sourceRunId, forkOptions) => request(`/runs/${encodeURIComponent(sourceRunId)}/fork`, StartResultSchema, {
|
|
174
|
+
method: 'POST',
|
|
175
|
+
body: stringifyJson(forkOptions?.runId === undefined ? {} : { runId: forkOptions.runId }),
|
|
176
|
+
}),
|
|
161
177
|
workerCallback,
|
|
162
178
|
listRunSummaries: () => request('/runs/summaries', RunSummariesSchema),
|
|
163
179
|
listDefinitions: () => request('/definitions', DefinitionCatalogSchema),
|
|
@@ -6,7 +6,7 @@ export interface DurableObjectNamespaceLike<T extends DurableObjectStubLike = Du
|
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
8
|
* Routes incoming HTTP requests to the appropriate Durable Object actor cell.
|
|
9
|
-
* Handles `/health` locally, returns 501 for global run lists, and forwards
|
|
9
|
+
* Handles `/health` locally, returns 501 for global run lists and forks, and forwards
|
|
10
10
|
* all other run and event-stream requests to `namespace.getByName(runId)`.
|
|
11
11
|
*/
|
|
12
12
|
export declare function routeToDurableObject(namespace: DurableObjectNamespaceLike, req: Request): Promise<Response | null>;
|
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
import { resolveRunTarget, RunTargetError } from '@swirls/looms/actor';
|
|
1
|
+
import { crossRunResponse, resolveRunTarget, RunTargetError } from '@swirls/looms/actor';
|
|
2
2
|
/**
|
|
3
3
|
* Routes incoming HTTP requests to the appropriate Durable Object actor cell.
|
|
4
|
-
* Handles `/health` locally, returns 501 for global run lists, and forwards
|
|
4
|
+
* Handles `/health` locally, returns 501 for global run lists and forks, and forwards
|
|
5
5
|
* all other run and event-stream requests to `namespace.getByName(runId)`.
|
|
6
6
|
*/
|
|
7
7
|
export function routeToDurableObject(namespace, req) {
|
|
8
|
-
|
|
9
|
-
if (url.pathname === '/health') {
|
|
8
|
+
if (new URL(req.url).pathname === '/health') {
|
|
10
9
|
return Promise.resolve(Response.json({ ok: true }));
|
|
11
10
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}, { status: 501 }));
|
|
11
|
+
const unsupported = crossRunResponse(req, 'the Durable Object backend');
|
|
12
|
+
if (unsupported) {
|
|
13
|
+
return Promise.resolve(unsupported);
|
|
16
14
|
}
|
|
17
15
|
return resolveRunTarget(req)
|
|
18
16
|
.then(({ runId, request }) => namespace.getByName(runId).fetch(request))
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AnyEventEnvelope } from './register';
|
|
2
|
+
/** The effect a `runtime.effect.retry.scheduled` event retries, or `undefined` for other events. */
|
|
3
|
+
export declare function retriedEffectId(event: AnyEventEnvelope): string | undefined;
|
|
4
|
+
/**
|
|
5
|
+
* Drops ephemeral events from effect attempts that a later retry in `events` superseded. Durable
|
|
6
|
+
* events and ephemeral events from the current attempt are kept.
|
|
7
|
+
*/
|
|
8
|
+
export declare function dropSupersededAttempts<E extends AnyEventEnvelope>(events: readonly E[]): readonly E[];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Schema } from 'effect';
|
|
2
|
+
import { protocolCatalog } from './protocol.js';
|
|
3
|
+
const RETRY_SCHEDULED = 'runtime.effect.retry.scheduled';
|
|
4
|
+
const isRetryPayload = Schema.is(protocolCatalog.entries['effect.retry.scheduled']);
|
|
5
|
+
/** The effect a `runtime.effect.retry.scheduled` event retries, or `undefined` for other events. */
|
|
6
|
+
export function retriedEffectId(event) {
|
|
7
|
+
return event.type === RETRY_SCHEDULED && isRetryPayload(event.payload)
|
|
8
|
+
? event.payload.effectId
|
|
9
|
+
: undefined;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Drops ephemeral events from effect attempts that a later retry in `events` superseded. Durable
|
|
13
|
+
* events and ephemeral events from the current attempt are kept.
|
|
14
|
+
*/
|
|
15
|
+
export function dropSupersededAttempts(events) {
|
|
16
|
+
const lastRetry = new Map();
|
|
17
|
+
events.forEach((event, index) => {
|
|
18
|
+
const effectId = retriedEffectId(event);
|
|
19
|
+
if (effectId !== undefined) {
|
|
20
|
+
lastRetry.set(effectId, index);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
if (lastRetry.size === 0) {
|
|
24
|
+
return events;
|
|
25
|
+
}
|
|
26
|
+
return events.filter((event, index) => !event.ephemeral || !event.effectId || (lastRetry.get(event.effectId) ?? -1) < index);
|
|
27
|
+
}
|
package/dist/core/effects.d.ts
CHANGED
|
@@ -166,6 +166,11 @@ export interface EffectDefinition<TInput = JsonValue, R = Context.Service.Any, E
|
|
|
166
166
|
readonly execution?: EffectExecution;
|
|
167
167
|
/** Whether `execute` runs a user handler. Without one, the effect can only complete through a worker. */
|
|
168
168
|
readonly hasHandler: boolean;
|
|
169
|
+
/**
|
|
170
|
+
* The outcome follows from the input alone, like scheduling from state already folded. Forking
|
|
171
|
+
* a failed run retries the effect that produced the failure, not a deterministic one passing it on.
|
|
172
|
+
*/
|
|
173
|
+
readonly deterministic?: boolean;
|
|
169
174
|
readonly [effectInputType]?: (input: TInput) => TInput;
|
|
170
175
|
execute(input: JsonValue, ctx: EffectContext): Effect.Effect<ReadonlyArray<E>, InvalidInputError | EffectHandlerError, R>;
|
|
171
176
|
}
|
|
@@ -182,6 +187,7 @@ export declare function defineEffect<TSchema extends SchemaInput, R = never, E e
|
|
|
182
187
|
input: TSchema;
|
|
183
188
|
retry?: RetryPolicy;
|
|
184
189
|
execution?: EffectExecution;
|
|
190
|
+
deterministic?: boolean;
|
|
185
191
|
execute?: (input: InferDefinedSchema<TSchema>, ctx: EffectContext) => EffectHandlerResult<R, E, HandlerError>;
|
|
186
192
|
}): EffectDefinition<InferDefinedSchema<TSchema>, R, E>;
|
|
187
193
|
export declare function defineEffect<R = never, E extends EventInput = EventInput, HandlerError = never>(def: {
|
|
@@ -189,6 +195,7 @@ export declare function defineEffect<R = never, E extends EventInput = EventInpu
|
|
|
189
195
|
input?: undefined;
|
|
190
196
|
retry?: RetryPolicy;
|
|
191
197
|
execution?: EffectExecution;
|
|
198
|
+
deterministic?: boolean;
|
|
192
199
|
execute?: (input: JsonValue, ctx: EffectContext) => EffectHandlerResult<R, E, HandlerError>;
|
|
193
200
|
}): EffectDefinition<JsonValue, R, E>;
|
|
194
201
|
export declare function spawn(args: {
|
package/dist/core/effects.js
CHANGED
|
@@ -106,6 +106,7 @@ export function defineEffect(def) {
|
|
|
106
106
|
retry: def.retry,
|
|
107
107
|
execution: def.execution,
|
|
108
108
|
hasHandler: handler !== undefined,
|
|
109
|
+
deterministic: def.deterministic,
|
|
109
110
|
execute: (raw, ctx) => Effect.gen(function* () {
|
|
110
111
|
const input = schema ? yield* validateInputEffect(schema, raw) : raw;
|
|
111
112
|
return handler ? yield* liftHandlerResult(handler(input, ctx)) : noOutput;
|
package/dist/core/fold.js
CHANGED
|
@@ -2,7 +2,7 @@ import { Option, Predicate, Schema, Stream } from 'effect';
|
|
|
2
2
|
import { isWithdrawnError, WaitConditionSchema } from './effects.js';
|
|
3
3
|
import { createEffectId } from './ids.js';
|
|
4
4
|
import { DEFAULT_DEFINITION_VERSION } from './module.js';
|
|
5
|
-
import { emptyRunState } from './state.js';
|
|
5
|
+
import { completedRunStatus, emptyRunState } from './state.js';
|
|
6
6
|
import { isTerminalStatus } from './thread.js';
|
|
7
7
|
const decodeWaitCondition = Schema.decodeUnknownOption(WaitConditionSchema);
|
|
8
8
|
function payloadObject(event) {
|
|
@@ -25,6 +25,7 @@ function cloneState(state) {
|
|
|
25
25
|
status: state.status,
|
|
26
26
|
rootThreadId: state.rootThreadId,
|
|
27
27
|
startIdentity: state.startIdentity,
|
|
28
|
+
forkedFrom: state.forkedFrom,
|
|
28
29
|
threads: { ...state.threads },
|
|
29
30
|
waits: { ...state.waits },
|
|
30
31
|
outstandingEffects: [...state.outstandingEffects],
|
|
@@ -104,13 +105,18 @@ function applyProtocol(state, event, registry) {
|
|
|
104
105
|
status: 'running',
|
|
105
106
|
};
|
|
106
107
|
}
|
|
107
|
-
case 'runtime.run.completed':
|
|
108
|
-
|
|
109
|
-
const status = Predicate.isString(error) && error.length > 0 ? 'failed' : 'completed';
|
|
110
|
-
return { ...state, status };
|
|
111
|
-
}
|
|
108
|
+
case 'runtime.run.completed':
|
|
109
|
+
return { ...state, status: completedRunStatus(payload) };
|
|
112
110
|
case 'runtime.run.cancelled':
|
|
113
111
|
return { ...state, status: 'cancelled' };
|
|
112
|
+
case 'runtime.run.forked': {
|
|
113
|
+
const sourceRunId = readString(payload, 'sourceRunId');
|
|
114
|
+
const sourceSeq = payload.sourceSeq;
|
|
115
|
+
// Attempts recorded in the copied history belong to the source run's processes.
|
|
116
|
+
return sourceRunId && Predicate.isNumber(sourceSeq)
|
|
117
|
+
? { ...state, forkedFrom: { runId: sourceRunId, seq: sourceSeq }, effectExecutions: {} }
|
|
118
|
+
: state;
|
|
119
|
+
}
|
|
114
120
|
case 'runtime.thread.started': {
|
|
115
121
|
const threadId = readString(payload, 'threadId') ?? event.threadId;
|
|
116
122
|
const kind = readString(payload, 'kind');
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Effect } from 'effect';
|
|
2
|
+
import { type EffectDefinition } from './effects';
|
|
3
|
+
import { type EventEnvelope } from './envelope';
|
|
4
|
+
import { type FoldRegistry } from './fold';
|
|
5
|
+
declare const ForkSourceError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
6
|
+
readonly _tag: "ForkSourceError";
|
|
7
|
+
} & Readonly<A>;
|
|
8
|
+
export declare class ForkSourceError extends ForkSourceError_base<{
|
|
9
|
+
readonly runId: string;
|
|
10
|
+
readonly message: string;
|
|
11
|
+
}> {
|
|
12
|
+
constructor(runId: string, message: string);
|
|
13
|
+
}
|
|
14
|
+
export interface ForkRegistry extends FoldRegistry {
|
|
15
|
+
readonly effects: ReadonlyMap<string, Pick<EffectDefinition, 'deterministic'>>;
|
|
16
|
+
}
|
|
17
|
+
export interface ForkPlan {
|
|
18
|
+
/** The fork's history: the copied prefix, keeping source seqs, then the `runtime.run.forked` marker. */
|
|
19
|
+
readonly events: readonly EventEnvelope[];
|
|
20
|
+
/** Last source seq the fork copied. */
|
|
21
|
+
readonly sourceSeq: number;
|
|
22
|
+
readonly rootThreadId: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Plan a new run that continues where the source run ended. The fork copies the source's
|
|
26
|
+
* history up to the point the run finished, keeping sequence numbers so effect ids still
|
|
27
|
+
* line up, and its next wake re-issues whatever effects were outstanding there.
|
|
28
|
+
*/
|
|
29
|
+
export declare function planFork(input: {
|
|
30
|
+
readonly sourceRunId: string;
|
|
31
|
+
readonly runId: string;
|
|
32
|
+
readonly events: readonly EventEnvelope[];
|
|
33
|
+
readonly registry: ForkRegistry;
|
|
34
|
+
}): Effect.Effect<ForkPlan, ForkSourceError>;
|
|
35
|
+
export {};
|