@effect-uai/core 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/README.md +1 -1
- package/dist/{Outcome-C2JYknCu.d.mts → Outcome-GiaNvt7i.d.mts} +2 -10
- package/dist/Outcome-GiaNvt7i.d.mts.map +1 -0
- package/dist/{ToolEvent-B2N10hr3.d.mts → ToolEvent-wTMgb2GO.d.mts} +2 -2
- package/dist/{ToolEvent-B2N10hr3.d.mts.map → ToolEvent-wTMgb2GO.d.mts.map} +1 -1
- package/dist/{Turn-rlTfuHaQ.d.mts → Turn-Bi83du4I.d.mts} +8 -19
- package/dist/{Turn-rlTfuHaQ.d.mts.map → Turn-Bi83du4I.d.mts.map} +1 -1
- package/dist/domain/Turn.d.mts +2 -2
- package/dist/domain/Turn.mjs +11 -7
- package/dist/domain/Turn.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/language-model/LanguageModel.d.mts +1 -1
- package/dist/loop/Loop.d.mts +87 -2
- package/dist/loop/Loop.d.mts.map +1 -0
- package/dist/testing/MockProvider.d.mts +1 -1
- package/dist/tool/HistoryCheck.d.mts +1 -1
- package/dist/tool/Outcome.d.mts +2 -2
- package/dist/tool/Outcome.mjs +4 -10
- package/dist/tool/Outcome.mjs.map +1 -1
- package/dist/tool/Resolvers.d.mts +24 -22
- package/dist/tool/Resolvers.d.mts.map +1 -1
- package/dist/tool/Resolvers.mjs +45 -44
- package/dist/tool/Resolvers.mjs.map +1 -1
- package/dist/tool/ToolEvent.d.mts +1 -1
- package/dist/tool/ToolEvent.mjs.map +1 -1
- package/dist/tool/Toolkit.d.mts +9 -9
- package/dist/tool/Toolkit.d.mts.map +1 -1
- package/dist/tool/Toolkit.mjs +11 -10
- package/dist/tool/Toolkit.mjs.map +1 -1
- package/package.json +1 -1
- package/src/domain/Turn.ts +7 -17
- package/src/tool/Outcome.ts +3 -17
- package/src/tool/Resolvers.test.ts +39 -86
- package/src/tool/Resolvers.ts +74 -93
- package/src/tool/ToolEvent.ts +2 -2
- package/src/tool/Toolkit.ts +13 -39
- package/dist/Loop-CzSJo1h8.d.mts +0 -87
- package/dist/Loop-CzSJo1h8.d.mts.map +0 -1
- package/dist/Outcome-C2JYknCu.d.mts.map +0 -1
package/src/tool/Resolvers.ts
CHANGED
|
@@ -1,29 +1,52 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* for layering policy on top.
|
|
2
|
+
* Approval helpers for the two transport flavors.
|
|
4
3
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* - `withFallback` : recovery wrapper.
|
|
9
|
-
*
|
|
10
|
-
* None of these know about the executor's stream shape; they just produce
|
|
11
|
-
* `Effect<ToolDecision>`s a `Resolver` can return.
|
|
4
|
+
* These helpers only decide which calls are approved and which synthetic
|
|
5
|
+
* results must be returned to the model. Tool execution stays explicit at
|
|
6
|
+
* the recipe boundary via `Toolkit.executeAll`.
|
|
12
7
|
*/
|
|
13
8
|
import { Deferred, Effect, Queue, Scope, Stream } from "effect"
|
|
14
9
|
import type { FunctionCall } from "../domain/Items.js"
|
|
15
|
-
import {
|
|
16
|
-
type ToolDecision,
|
|
17
|
-
type ToolResult,
|
|
18
|
-
cancelled,
|
|
19
|
-
denied,
|
|
20
|
-
execute,
|
|
21
|
-
reject,
|
|
22
|
-
rejected,
|
|
23
|
-
} from "./Outcome.js"
|
|
24
|
-
import type { Resolver } from "./Toolkit.js"
|
|
10
|
+
import { type ToolResult, cancelled, denied } from "./Outcome.js"
|
|
25
11
|
import type { ToolEvent } from "./ToolEvent.js"
|
|
26
12
|
|
|
13
|
+
export interface ToolCallPlan {
|
|
14
|
+
readonly approved: ReadonlyArray<FunctionCall>
|
|
15
|
+
readonly rejected: ReadonlyArray<ToolResult>
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type ToolCallDecision =
|
|
19
|
+
| { readonly _tag: "Approved"; readonly call: FunctionCall }
|
|
20
|
+
| { readonly _tag: "Rejected"; readonly result: ToolResult }
|
|
21
|
+
|
|
22
|
+
export const approve = (call: FunctionCall): ToolCallDecision => ({
|
|
23
|
+
_tag: "Approved",
|
|
24
|
+
call,
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
export const reject = (result: ToolResult): ToolCallDecision => ({
|
|
28
|
+
_tag: "Rejected",
|
|
29
|
+
result,
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
export const splitToolCallDecisions = (
|
|
33
|
+
decisions: ReadonlyArray<ToolCallDecision>,
|
|
34
|
+
): ToolCallPlan =>
|
|
35
|
+
decisions.reduce<ToolCallPlan>(
|
|
36
|
+
(acc, decision) =>
|
|
37
|
+
decision._tag === "Approved"
|
|
38
|
+
? { ...acc, approved: [...acc.approved, decision.call] }
|
|
39
|
+
: { ...acc, rejected: [...acc.rejected, decision.result] },
|
|
40
|
+
{ approved: [], rejected: [] },
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
export const approvalRequested = (call: FunctionCall): ToolEvent => ({
|
|
44
|
+
_tag: "ApprovalRequested",
|
|
45
|
+
call_id: call.call_id,
|
|
46
|
+
tool: call.name,
|
|
47
|
+
arguments: call.arguments,
|
|
48
|
+
})
|
|
49
|
+
|
|
27
50
|
// ---------------------------------------------------------------------------
|
|
28
51
|
// Verdict queue (WebSocket-style transport).
|
|
29
52
|
// ---------------------------------------------------------------------------
|
|
@@ -35,10 +58,9 @@ export interface Verdict {
|
|
|
35
58
|
}
|
|
36
59
|
|
|
37
60
|
/**
|
|
38
|
-
* Queue-backed
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* merges the announce stream into its consumer view.
|
|
61
|
+
* Queue-backed approval planner. Safe calls are returned immediately in
|
|
62
|
+
* `approved`; gated calls emit `ApprovalRequested` events and later produce
|
|
63
|
+
* one `ToolCallDecision` when their matching verdict arrives.
|
|
42
64
|
*/
|
|
43
65
|
export const fromVerdictQueue =
|
|
44
66
|
(
|
|
@@ -49,7 +71,8 @@ export const fromVerdictQueue =
|
|
|
49
71
|
calls: ReadonlyArray<FunctionCall>,
|
|
50
72
|
): Effect.Effect<
|
|
51
73
|
{
|
|
52
|
-
readonly
|
|
74
|
+
readonly approved: ReadonlyArray<FunctionCall>
|
|
75
|
+
readonly decisions: Stream.Stream<ToolCallDecision>
|
|
53
76
|
readonly announce: Stream.Stream<ToolEvent>
|
|
54
77
|
},
|
|
55
78
|
never,
|
|
@@ -57,6 +80,7 @@ export const fromVerdictQueue =
|
|
|
57
80
|
> =>
|
|
58
81
|
Effect.gen(function* () {
|
|
59
82
|
const gated = calls.filter(predicate)
|
|
83
|
+
const approved = calls.filter((call) => !predicate(call))
|
|
60
84
|
|
|
61
85
|
const entries = yield* Effect.forEach(gated, (call) =>
|
|
62
86
|
Deferred.make<Verdict>().pipe(Effect.map((d) => [call.call_id, d] as const)),
|
|
@@ -76,26 +100,25 @@ export const fromVerdictQueue =
|
|
|
76
100
|
),
|
|
77
101
|
)
|
|
78
102
|
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
tool: call.name,
|
|
94
|
-
arguments: call.arguments,
|
|
95
|
-
})),
|
|
103
|
+
const decisions = Stream.fromIterable(gated).pipe(
|
|
104
|
+
Stream.flatMap(
|
|
105
|
+
(call) => {
|
|
106
|
+
const d = deferreds.get(call.call_id)!
|
|
107
|
+
return Stream.fromEffect(
|
|
108
|
+
Deferred.await(d).pipe(
|
|
109
|
+
Effect.map((v) =>
|
|
110
|
+
v.decision === "approve" ? approve(call) : reject(denied(call, v.reason)),
|
|
111
|
+
),
|
|
112
|
+
),
|
|
113
|
+
)
|
|
114
|
+
},
|
|
115
|
+
{ concurrency: "unbounded" },
|
|
116
|
+
),
|
|
96
117
|
)
|
|
97
118
|
|
|
98
|
-
|
|
119
|
+
const announce = Stream.fromIterable<ToolEvent>(gated.map(approvalRequested))
|
|
120
|
+
|
|
121
|
+
return { approved, decisions, announce }
|
|
99
122
|
})
|
|
100
123
|
|
|
101
124
|
// ---------------------------------------------------------------------------
|
|
@@ -111,56 +134,14 @@ export const fromApprovalMap =
|
|
|
111
134
|
(
|
|
112
135
|
predicate: (call: FunctionCall) => boolean,
|
|
113
136
|
approvals: ReadonlyMap<string, ApprovalMapEntry>,
|
|
114
|
-
)
|
|
115
|
-
(
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
// ---------------------------------------------------------------------------
|
|
125
|
-
// Combinators - compose policy onto an inner resolver.
|
|
126
|
-
// ---------------------------------------------------------------------------
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Authz gate. `canApprove` runs BEFORE the inner resolver; failures
|
|
130
|
-
* short-circuit to a `permission_denied` rejection. Override `onForbidden`
|
|
131
|
-
* if your audit format wants a different kind or reason.
|
|
132
|
-
*/
|
|
133
|
-
export const withPermissions =
|
|
134
|
-
(
|
|
135
|
-
inner: Resolver,
|
|
136
|
-
canApprove: (call: FunctionCall) => Effect.Effect<boolean>,
|
|
137
|
-
onForbidden: (call: FunctionCall) => ToolResult = (call) =>
|
|
138
|
-
rejected(call, "permission_denied", "missing permissions"),
|
|
139
|
-
): Resolver =>
|
|
140
|
-
(call) =>
|
|
141
|
-
canApprove(call).pipe(
|
|
142
|
-
Effect.flatMap((allowed) =>
|
|
143
|
-
allowed ? inner(call) : Effect.succeed(reject(onForbidden(call))),
|
|
144
|
-
),
|
|
145
|
-
)
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Fallback gate. If `inner` returns a Reject whose result matches the
|
|
149
|
-
* `recoverable` predicate, run `fallback(call)` instead and use that
|
|
150
|
-
* decision. Otherwise pass the original Reject through.
|
|
151
|
-
*/
|
|
152
|
-
export const withFallback =
|
|
153
|
-
(
|
|
154
|
-
inner: Resolver,
|
|
155
|
-
recoverable: (result: ToolResult) => boolean,
|
|
156
|
-
fallback: (call: FunctionCall) => Effect.Effect<ToolDecision>,
|
|
157
|
-
): Resolver =>
|
|
158
|
-
(call) =>
|
|
159
|
-
inner(call).pipe(
|
|
160
|
-
Effect.flatMap((decision) =>
|
|
161
|
-
decision._tag === "Reject" && recoverable(decision.result)
|
|
162
|
-
? fallback(call)
|
|
163
|
-
: Effect.succeed(decision),
|
|
164
|
-
),
|
|
137
|
+
) =>
|
|
138
|
+
(calls: ReadonlyArray<FunctionCall>): ToolCallPlan =>
|
|
139
|
+
splitToolCallDecisions(
|
|
140
|
+
calls.map((call) => {
|
|
141
|
+
if (!predicate(call)) return approve(call)
|
|
142
|
+
const v = approvals.get(call.call_id)
|
|
143
|
+
if (v === undefined) return reject(cancelled(call))
|
|
144
|
+
return v.decision === "approve" ? approve(call) : reject(denied(call, v.reason))
|
|
145
|
+
}),
|
|
165
146
|
)
|
|
166
147
|
|
package/src/tool/ToolEvent.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The event type emitted
|
|
2
|
+
* The event type emitted while handling tool calls.
|
|
3
3
|
*
|
|
4
|
-
* - ApprovalRequested : gated calls
|
|
4
|
+
* - ApprovalRequested : gated calls waiting for approval
|
|
5
5
|
* - Intermediate : per-element passthrough from a streaming tool's run
|
|
6
6
|
* - Output : terminal result (carries a structured ToolResult)
|
|
7
7
|
*
|
package/src/tool/Toolkit.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Array as Arr, Effect,
|
|
1
|
+
import { Array as Arr, Effect, Ref, Stream } from "effect"
|
|
2
2
|
import * as Loop from "../loop/Loop.js"
|
|
3
3
|
import type { FunctionCall } from "../domain/Items.js"
|
|
4
4
|
import {
|
|
@@ -10,9 +10,7 @@ import {
|
|
|
10
10
|
type ToolDescriptor,
|
|
11
11
|
} from "./Tool.js"
|
|
12
12
|
import {
|
|
13
|
-
type ToolDecision,
|
|
14
13
|
type ToolResult,
|
|
15
|
-
execute as executeDecision,
|
|
16
14
|
executionError,
|
|
17
15
|
rejected,
|
|
18
16
|
} from "./Outcome.js"
|
|
@@ -50,56 +48,32 @@ export const toDescriptors = <Tools extends ReadonlyArray<AnyTool>>(
|
|
|
50
48
|
})
|
|
51
49
|
|
|
52
50
|
// ---------------------------------------------------------------------------
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
//
|
|
57
|
-
// `executeAllWithResolver` is the general primitive. `executeAllStream` is
|
|
58
|
-
// the no-resolver shortcut.
|
|
51
|
+
// Tool executor. Streams `ToolEvent`s in real time and dispatches streaming
|
|
52
|
+
// and plain tools uniformly. Policy stays outside this module: callers pass
|
|
53
|
+
// only the calls they have already decided should run.
|
|
59
54
|
// ---------------------------------------------------------------------------
|
|
60
55
|
|
|
61
|
-
export type Resolver = (call: FunctionCall) => Effect.Effect<ToolDecision>
|
|
62
|
-
|
|
63
56
|
export interface ExecuteOptions {
|
|
64
57
|
readonly concurrency?: number | "unbounded"
|
|
65
58
|
}
|
|
66
59
|
|
|
67
|
-
|
|
60
|
+
/** Execute every provided call. Approval/rejection policy belongs upstream. */
|
|
61
|
+
export const executeAll = (
|
|
68
62
|
tools: ReadonlyArray<AnyKindTool>,
|
|
69
63
|
calls: ReadonlyArray<FunctionCall>,
|
|
70
|
-
resolve: Resolver,
|
|
71
64
|
options?: ExecuteOptions,
|
|
72
65
|
): Stream.Stream<ToolEvent> =>
|
|
73
66
|
Stream.fromIterable(calls).pipe(
|
|
74
|
-
Stream.flatMap(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
resolve(call).pipe(Effect.map((decision) => dispatch(tools, call, decision))),
|
|
78
|
-
),
|
|
79
|
-
{ concurrency: options?.concurrency ?? "unbounded" },
|
|
80
|
-
),
|
|
67
|
+
Stream.flatMap((call) => runOne(tools, call), {
|
|
68
|
+
concurrency: options?.concurrency ?? "unbounded",
|
|
69
|
+
}),
|
|
81
70
|
)
|
|
82
71
|
|
|
83
|
-
|
|
84
|
-
export const executeAll = (
|
|
85
|
-
tools: ReadonlyArray<AnyKindTool>,
|
|
86
|
-
calls: ReadonlyArray<FunctionCall>,
|
|
87
|
-
options?: ExecuteOptions,
|
|
88
|
-
): Stream.Stream<ToolEvent> =>
|
|
89
|
-
executeAllWithResolver(tools, calls, () => Effect.succeed(executeDecision), options)
|
|
72
|
+
export const outputEvent = (result: ToolResult): ToolEvent => ({ _tag: "Output", result })
|
|
90
73
|
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
decision: ToolDecision,
|
|
95
|
-
): Stream.Stream<ToolEvent> =>
|
|
96
|
-
Match.value(decision).pipe(
|
|
97
|
-
Match.tag("Execute", () => runOne(tools, call)),
|
|
98
|
-
Match.tag("Reject", (d) =>
|
|
99
|
-
Stream.succeed<ToolEvent>({ _tag: "Output", result: d.result }),
|
|
100
|
-
),
|
|
101
|
-
Match.exhaustive,
|
|
102
|
-
)
|
|
74
|
+
export const outputEvents = (
|
|
75
|
+
results: ReadonlyArray<ToolResult>,
|
|
76
|
+
): Stream.Stream<ToolEvent> => Stream.fromIterable(results.map(outputEvent))
|
|
103
77
|
|
|
104
78
|
const valueResult = (call: FunctionCall, tool: string, value: unknown): ToolResult => ({
|
|
105
79
|
_tag: "Value",
|
package/dist/Loop-CzSJo1h8.d.mts
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { l as IncompleteTurn } from "./AiError-CqmYjXyx.mjs";
|
|
2
|
-
import { a as TurnEvent, i as Turn } from "./Turn-rlTfuHaQ.mjs";
|
|
3
|
-
import { Data, Effect, Stream } from "effect";
|
|
4
|
-
|
|
5
|
-
//#region src/loop/Loop.d.ts
|
|
6
|
-
declare namespace Loop_d_exports {
|
|
7
|
-
export { Event, loop, next, nextAfter, nextAfterFold, stop, stopAfter, stopEvent, streamUntilComplete, value };
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* The tagged union a body emits per pull. `Value` carries a payload that
|
|
11
|
-
* flows downstream. `Next` ends the current iteration and continues with a
|
|
12
|
-
* new state. `Stop` ends the loop entirely.
|
|
13
|
-
*/
|
|
14
|
-
type Event<A, S> = Data.TaggedEnum<{
|
|
15
|
-
Value: {
|
|
16
|
-
readonly value: A;
|
|
17
|
-
};
|
|
18
|
-
Next: {
|
|
19
|
-
readonly state: S;
|
|
20
|
-
};
|
|
21
|
-
Stop: {};
|
|
22
|
-
}>;
|
|
23
|
-
/** Wrap a value so it flows through the loop to downstream consumers. */
|
|
24
|
-
declare const value: <A>(a: A) => Event<A, never>;
|
|
25
|
-
/** End the current iteration and continue with a new state. */
|
|
26
|
-
declare const next: <S>(state: S) => Event<never, S>;
|
|
27
|
-
/** The terminal `Stop` event. Use `stop` (the Stream) to end a loop body. */
|
|
28
|
-
declare const stopEvent: Event<never, never>;
|
|
29
|
-
/**
|
|
30
|
-
* A single-element stream that ends the loop. Return this from a body when
|
|
31
|
-
* there's nothing else to emit; equivalent to `stopAfter(Stream.empty)` but
|
|
32
|
-
* named for the common case.
|
|
33
|
-
*/
|
|
34
|
-
declare const stop: Stream.Stream<Event<never, never>>;
|
|
35
|
-
/**
|
|
36
|
-
* Pipe a raw `Stream<A>` into the loop's emit shape, then terminate the
|
|
37
|
-
* iteration with `next(state)`. Common shape for "stream this turn's
|
|
38
|
-
* deltas, then continue with updated history."
|
|
39
|
-
*/
|
|
40
|
-
declare const nextAfter: <S, A, E, R>(stream: Stream.Stream<A, E, R>, state: S) => Stream.Stream<Event<A, S>, E, R>;
|
|
41
|
-
/**
|
|
42
|
-
* Pipe a raw `Stream<A>` into the loop's emit shape, then terminate the
|
|
43
|
-
* loop. Common shape for "stream this turn's deltas, then we're done."
|
|
44
|
-
*/
|
|
45
|
-
declare const stopAfter: <A, E, R>(stream: Stream.Stream<A, E, R>) => Stream.Stream<Event<A, never>, E, R>;
|
|
46
|
-
/**
|
|
47
|
-
* General `nextAfter` variant: drain `stream` to the consumer, fold elements
|
|
48
|
-
* into an accumulator, and at end-of-stream emit one `next(build(finalAcc))`.
|
|
49
|
-
*
|
|
50
|
-
* Subsumes `nextAfter` when state is constant (`reduce: (s, _) => s`,
|
|
51
|
-
* `build: (s) => s`). Used by `Toolkit.nextStateFrom` to collect tool
|
|
52
|
-
* results and build next state without exposing a Ref to recipes.
|
|
53
|
-
*/
|
|
54
|
-
declare const nextAfterFold: <A, B, S, E, R>(stream: Stream.Stream<A, E, R>, initial: B, reduce: (acc: B, a: A) => B, build: (b: B) => S) => Stream.Stream<Event<A, S>, E, R>;
|
|
55
|
-
/**
|
|
56
|
-
* Lift a provider's `Stream<TurnEvent>` into a loop body's `Stream<Event<TurnEvent | A, S>>`.
|
|
57
|
-
* Each delta passes through as `value(delta)` (including the terminal
|
|
58
|
-
* `turn_complete`, so the consumer sees turn boundaries naturally). Once
|
|
59
|
-
* the terminal arrives, `then(turn)` runs and its returned stream of loop
|
|
60
|
-
* events (typically tool outputs followed by `next(state)` or `stop`) is
|
|
61
|
-
* concatenated.
|
|
62
|
-
*
|
|
63
|
-
* Pre-pipe transforms (`Stream.tap` / `Stream.map` / `Stream.filter`) on
|
|
64
|
-
* the raw delta stream cover anything an `emit`-style callback would do.
|
|
65
|
-
*
|
|
66
|
-
* If the upstream ends without a `turn_complete`, the resulting stream
|
|
67
|
-
* fails with `AiError.IncompleteTurn`. Catch it via `Stream.catchTag` if
|
|
68
|
-
* you want to recover.
|
|
69
|
-
*/
|
|
70
|
-
declare const streamUntilComplete: <S, A, E2 = never, R2 = never>(then: (turn: Turn) => Effect.Effect<Stream.Stream<Event<A, S>, E2, R2>, E2, R2>) => <E, R>(deltas: Stream.Stream<TurnEvent, E, R>) => Stream.Stream<Event<TurnEvent | A, S>, E | E2 | IncompleteTurn, R | R2>;
|
|
71
|
-
type LoopBody<S, A, E, R> = (state: S) => Stream.Stream<Event<A, S>, E, R> | Effect.Effect<Stream.Stream<Event<A, S>, E, R>, E, R>;
|
|
72
|
-
/**
|
|
73
|
-
* Drive a state-threaded loop body. Each iteration runs `body(state)` to get
|
|
74
|
-
* a `Stream<Event<A, S>>`; values flow downstream, `next(s)` continues with
|
|
75
|
-
* a new state, `stop` ends the loop. See the file header for the full
|
|
76
|
-
* pull-based execution model.
|
|
77
|
-
*
|
|
78
|
-
* Dual: data-first `loop(initial, body)` and data-last `loop(body)(initial)`
|
|
79
|
-
* (or `pipe(initial, loop(body))`) both work.
|
|
80
|
-
*/
|
|
81
|
-
declare const loop: {
|
|
82
|
-
<S, A, E, R>(body: LoopBody<S, A, E, R>): (initial: S) => Stream.Stream<A, E, R>;
|
|
83
|
-
<S, A, E, R>(initial: S, body: LoopBody<S, A, E, R>): Stream.Stream<A, E, R>;
|
|
84
|
-
};
|
|
85
|
-
//#endregion
|
|
86
|
-
export { nextAfter as a, stopAfter as c, value as d, next as i, stopEvent as l, Loop_d_exports as n, nextAfterFold as o, loop as r, stop as s, Event as t, streamUntilComplete as u };
|
|
87
|
-
//# sourceMappingURL=Loop-CzSJo1h8.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Loop-CzSJo1h8.d.mts","names":[],"sources":["../src/loop/Loop.ts"],"mappings":";;;;;;;;;;;;;KAgCY,KAAA,SAAc,IAAA,CAAK,UAAA;EAC7B,KAAA;IAAA,SAAkB,KAAA,EAAO,CAAA;EAAA;EACzB,IAAA;IAAA,SAAiB,KAAA,EAAO,CAAA;EAAA;EACxB,IAAA;AAAA;;cAUW,KAAA,MAAY,CAAA,EAAG,CAAA,KAAI,KAAA,CAAM,CAAA;;cAGzB,IAAA,MAAW,KAAA,EAAO,CAAA,KAAI,KAAA,QAAa,CAAA;;cAGnC,SAAA,EAAW,KAAA;;;;;;cAOX,IAAA,EAAM,MAAA,CAAO,MAAA,CAAO,KAAA;;;;;;cAOpB,SAAA,eACX,MAAA,EAAQ,MAAA,CAAO,MAAA,CAAO,CAAA,EAAG,CAAA,EAAG,CAAA,GAC5B,KAAA,EAAO,CAAA,KACN,MAAA,CAAO,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA;AApBjC;;;;AAAA,cA2Ba,SAAA,YACX,MAAA,EAAQ,MAAA,CAAO,MAAA,CAAO,CAAA,EAAG,CAAA,EAAG,CAAA,MAC3B,MAAA,CAAO,MAAA,CAAO,KAAA,CAAM,CAAA,UAAW,CAAA,EAAG,CAAA;;;;;;;;;cAWxB,aAAA,kBACX,MAAA,EAAQ,MAAA,CAAO,MAAA,CAAO,CAAA,EAAG,CAAA,EAAG,CAAA,GAC5B,OAAA,EAAS,CAAA,EACT,MAAA,GAAS,GAAA,EAAK,CAAA,EAAG,CAAA,EAAG,CAAA,KAAM,CAAA,EAC1B,KAAA,GAAQ,CAAA,EAAG,CAAA,KAAM,CAAA,KAChB,MAAA,CAAO,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA;;AA1CjC;;;;;AAOA;;;;;;;;;cAqEa,mBAAA,iCAET,IAAA,GAAO,IAAA,EAAM,IAAA,KAAS,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,EAAA,GAAK,EAAA,EAAI,EAAA,aAG5E,MAAA,EAAQ,MAAA,CAAO,MAAA,CAAO,SAAA,EAAW,CAAA,EAAG,CAAA,MACnC,MAAA,CAAO,MAAA,CAAO,KAAA,CAAM,SAAA,GAAY,CAAA,EAAG,CAAA,GAAI,CAAA,GAAI,EAAA,GAAK,cAAA,EAAgB,CAAA,GAAI,EAAA;AAAA,KAkEpE,QAAA,gBACH,KAAA,EAAO,CAAA,KACJ,MAAA,CAAO,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA;;;;;;;;;;cAW9E,IAAA;EAAA,aACE,IAAA,EAAM,QAAA,CAAS,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,KAAM,OAAA,EAAS,CAAA,KAAM,MAAA,CAAO,MAAA,CAAO,CAAA,EAAG,CAAA,EAAG,CAAA;EAAA,aACjE,OAAA,EAAS,CAAA,EAAG,IAAA,EAAM,QAAA,CAAS,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,IAAK,MAAA,CAAO,MAAA,CAAO,CAAA,EAAG,CAAA,EAAG,CAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Outcome-C2JYknCu.d.mts","names":[],"sources":["../src/tool/Outcome.ts"],"mappings":";;;KAsBY,UAAA;EAAA,SAEG,IAAA;EAAA,SACA,OAAA;EAAA,SACA,IAAA;EAAA,SACA,KAAA;AAAA;EAAA,SAGA,IAAA;EAAA,SACA,OAAA;EAAA,SACA,IAAA;EAAA,SACA,IAAA;EAAA,SACA,MAAA;AAAA;AAAA,cAGF,OAAA,GAAW,CAAA,EAAG,UAAA,KAAa,CAAA,IAAK,OAAA,CAAQ,UAAA;EAAc,IAAA;AAAA;AAAA,cAGtD,SAAA,GAAa,CAAA,EAAG,UAAA,KAAa,CAAA,IAAK,OAAA,CAAQ,UAAA;EAAc,IAAA;AAAA;AAAA,KAOzD,YAAA;EAAA,SACG,IAAA;AAAA;EAAA,SACA,IAAA;EAAA,SAAyB,MAAA,EAAQ,UAAA;AAAA;AAAA,cAEnC,OAAA,EAAS,YAAA;AAAA,cAET,MAAA,GAAU,MAAA,EAAQ,UAAA,KAAa,YAAA;AAAA,cAO/B,QAAA,GACX,IAAA,EAAM,YAAA,EACN,IAAA,UACA,MAAA,cACC,UAAA;;cASU,MAAA,GAAU,IAAA,EAAM,YAAA,EAAc,MAAA,cAAkB,UAAA;;cAIhD,SAAA,GAAa,IAAA,EAAM,YAAA,EAAc,MAAA,cAAkB,UAAA;;cAInD,cAAA,GAAkB,IAAA,EAAM,YAAA,EAAc,MAAA,aAAiB,UAAA;AAAA,cAOvD,oBAAA,GAAwB,CAAA,EAAG,UAAA,KAAa,kBAAA"}
|