@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.
Files changed (39) hide show
  1. package/README.md +1 -1
  2. package/dist/{Outcome-C2JYknCu.d.mts → Outcome-GiaNvt7i.d.mts} +2 -10
  3. package/dist/Outcome-GiaNvt7i.d.mts.map +1 -0
  4. package/dist/{ToolEvent-B2N10hr3.d.mts → ToolEvent-wTMgb2GO.d.mts} +2 -2
  5. package/dist/{ToolEvent-B2N10hr3.d.mts.map → ToolEvent-wTMgb2GO.d.mts.map} +1 -1
  6. package/dist/{Turn-rlTfuHaQ.d.mts → Turn-Bi83du4I.d.mts} +8 -19
  7. package/dist/{Turn-rlTfuHaQ.d.mts.map → Turn-Bi83du4I.d.mts.map} +1 -1
  8. package/dist/domain/Turn.d.mts +2 -2
  9. package/dist/domain/Turn.mjs +11 -7
  10. package/dist/domain/Turn.mjs.map +1 -1
  11. package/dist/index.d.mts +2 -2
  12. package/dist/language-model/LanguageModel.d.mts +1 -1
  13. package/dist/loop/Loop.d.mts +87 -2
  14. package/dist/loop/Loop.d.mts.map +1 -0
  15. package/dist/testing/MockProvider.d.mts +1 -1
  16. package/dist/tool/HistoryCheck.d.mts +1 -1
  17. package/dist/tool/Outcome.d.mts +2 -2
  18. package/dist/tool/Outcome.mjs +4 -10
  19. package/dist/tool/Outcome.mjs.map +1 -1
  20. package/dist/tool/Resolvers.d.mts +24 -22
  21. package/dist/tool/Resolvers.d.mts.map +1 -1
  22. package/dist/tool/Resolvers.mjs +45 -44
  23. package/dist/tool/Resolvers.mjs.map +1 -1
  24. package/dist/tool/ToolEvent.d.mts +1 -1
  25. package/dist/tool/ToolEvent.mjs.map +1 -1
  26. package/dist/tool/Toolkit.d.mts +9 -9
  27. package/dist/tool/Toolkit.d.mts.map +1 -1
  28. package/dist/tool/Toolkit.mjs +11 -10
  29. package/dist/tool/Toolkit.mjs.map +1 -1
  30. package/package.json +1 -1
  31. package/src/domain/Turn.ts +7 -17
  32. package/src/tool/Outcome.ts +3 -17
  33. package/src/tool/Resolvers.test.ts +39 -86
  34. package/src/tool/Resolvers.ts +74 -93
  35. package/src/tool/ToolEvent.ts +2 -2
  36. package/src/tool/Toolkit.ts +13 -39
  37. package/dist/Loop-CzSJo1h8.d.mts +0 -87
  38. package/dist/Loop-CzSJo1h8.d.mts.map +0 -1
  39. package/dist/Outcome-C2JYknCu.d.mts.map +0 -1
@@ -1,29 +1,52 @@
1
1
  /**
2
- * Ready-made `Resolver`s for the two transport flavors plus combinators
3
- * for layering policy on top.
2
+ * Approval helpers for the two transport flavors.
4
3
  *
5
- * - `fromVerdictQueue` : long-lived channel (WebSocket / SSE).
6
- * - `fromApprovalMap` : request-shaped (HTTP chat).
7
- * - `withPermissions` : authz wrapper.
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 resolver. The router fiber drains verdicts and resolves
39
- * pre-registered Deferreds keyed by `call_id`. Returns the resolver and
40
- * a stream of `ApprovalRequested` events for the gated calls; the recipe
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 resolve: Resolver
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 resolve: Resolver = (call) => {
80
- if (!predicate(call)) return Effect.succeed(execute)
81
- const d = deferreds.get(call.call_id)!
82
- return Deferred.await(d).pipe(
83
- Effect.map((v) =>
84
- v.decision === "approve" ? execute : reject(denied(call, v.reason)),
85
- ),
86
- )
87
- }
88
-
89
- const announce = Stream.fromIterable<ToolEvent>(
90
- gated.map((call) => ({
91
- _tag: "ApprovalRequested",
92
- call_id: call.call_id,
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
- return { resolve, announce }
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
- ): Resolver =>
115
- (call) => {
116
- if (!predicate(call)) return Effect.succeed(execute)
117
- const v = approvals.get(call.call_id)
118
- if (v === undefined) return Effect.succeed(reject(cancelled(call)))
119
- return Effect.succeed(
120
- v.decision === "approve" ? execute : reject(denied(call, v.reason)),
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
 
@@ -1,7 +1,7 @@
1
1
  /**
2
- * The event type emitted by `Toolkit.executeAllWithResolver`.
2
+ * The event type emitted while handling tool calls.
3
3
  *
4
- * - ApprovalRequested : gated calls before resolver returns
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
  *
@@ -1,4 +1,4 @@
1
- import { Array as Arr, Effect, Match, Ref, Stream } from "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
- // Resolver-based executor. Streams `ToolEvent`s in real time, dispatches
54
- // streaming and plain tools uniformly, and lets the caller decide what
55
- // happens to each call (Execute or Reject) before execution.
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
- export const executeAllWithResolver = (
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
- (call) =>
76
- Stream.unwrap(
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
- /** No-resolver shortcut: every call gets `Execute`. */
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 dispatch = (
92
- tools: ReadonlyArray<AnyKindTool>,
93
- call: FunctionCall,
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",
@@ -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"}