@effect-uai/core 0.5.0 → 0.5.2
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/dist/{Items-DqbaJoz7.d.mts → Items-BH8xUkoR.d.mts} +6 -6
- package/dist/{Items-DqbaJoz7.d.mts.map → Items-BH8xUkoR.d.mts.map} +1 -1
- package/dist/{Tool-Y0__Py1H.d.mts → Tool-87ViKCCO.d.mts} +2 -2
- package/dist/{Tool-Y0__Py1H.d.mts.map → Tool-87ViKCCO.d.mts.map} +1 -1
- package/dist/{Turn-ChbL2foc.d.mts → Turn-0CwCAyVe.d.mts} +2 -2
- package/dist/{Turn-ChbL2foc.d.mts.map → Turn-0CwCAyVe.d.mts.map} +1 -1
- package/dist/domain/Items.d.mts +1 -1
- package/dist/domain/Turn.d.mts +1 -1
- package/dist/index.d.mts +5 -4
- package/dist/index.mjs +2 -1
- package/dist/language-model/LanguageModel.d.mts +27 -25
- package/dist/language-model/LanguageModel.d.mts.map +1 -1
- package/dist/language-model/LanguageModel.mjs +16 -25
- package/dist/language-model/LanguageModel.mjs.map +1 -1
- package/dist/language-model/LanguageModel.test.mjs +10 -81
- package/dist/language-model/LanguageModel.test.mjs.map +1 -1
- package/dist/loop/Loop.d.mts +1 -1
- package/dist/retry/Retry.d.mts +64 -0
- package/dist/retry/Retry.d.mts.map +1 -0
- package/dist/retry/Retry.mjs +69 -0
- package/dist/retry/Retry.mjs.map +1 -0
- package/dist/retry/Retry.test.d.mts +1 -0
- package/dist/retry/Retry.test.mjs +142 -0
- package/dist/retry/Retry.test.mjs.map +1 -0
- package/dist/testing/MockProvider.d.mts +2 -2
- package/dist/testing/MockProvider.d.mts.map +1 -1
- package/dist/testing/MockProvider.mjs +14 -8
- package/dist/testing/MockProvider.mjs.map +1 -1
- package/dist/tool/HistoryCheck.d.mts +1 -1
- package/dist/tool/Outcome.d.mts +1 -1
- package/dist/tool/Resolvers.d.mts +1 -1
- package/dist/tool/Tool.d.mts +1 -1
- package/dist/tool/Toolkit.d.mts +2 -2
- package/package.json +5 -1
- package/src/index.ts +1 -0
- package/src/language-model/LanguageModel.test.ts +21 -102
- package/src/language-model/LanguageModel.ts +33 -56
- package/src/retry/Retry.test.ts +163 -0
- package/src/retry/Retry.ts +84 -0
- package/src/testing/MockProvider.ts +10 -5
|
@@ -74,8 +74,8 @@ declare const Annotation: Schema.Union<readonly [Schema.Struct<{
|
|
|
74
74
|
}>]>;
|
|
75
75
|
type Annotation = typeof Annotation.Type;
|
|
76
76
|
declare const isUrlCitation: <I>(input: I) => input is I & {
|
|
77
|
-
readonly type: "url_citation";
|
|
78
77
|
readonly url: string;
|
|
78
|
+
readonly type: "url_citation";
|
|
79
79
|
readonly start_index: number;
|
|
80
80
|
readonly end_index: number;
|
|
81
81
|
readonly title: string;
|
|
@@ -309,8 +309,8 @@ declare const isOutputText: <I>(input: I) => input is I & {
|
|
|
309
309
|
readonly type: "output_text";
|
|
310
310
|
readonly text: string;
|
|
311
311
|
readonly annotations?: readonly ({
|
|
312
|
-
readonly type: "url_citation";
|
|
313
312
|
readonly url: string;
|
|
313
|
+
readonly type: "url_citation";
|
|
314
314
|
readonly start_index: number;
|
|
315
315
|
readonly end_index: number;
|
|
316
316
|
readonly title: string;
|
|
@@ -346,8 +346,8 @@ declare const isMessage: <I>(input: I) => input is I & {
|
|
|
346
346
|
readonly type: "output_text";
|
|
347
347
|
readonly text: string;
|
|
348
348
|
readonly annotations?: readonly ({
|
|
349
|
-
readonly type: "url_citation";
|
|
350
349
|
readonly url: string;
|
|
350
|
+
readonly type: "url_citation";
|
|
351
351
|
readonly start_index: number;
|
|
352
352
|
readonly end_index: number;
|
|
353
353
|
readonly title: string;
|
|
@@ -374,15 +374,15 @@ declare const isMessage: <I>(input: I) => input is I & {
|
|
|
374
374
|
readonly providerData?: unknown;
|
|
375
375
|
};
|
|
376
376
|
declare const isFunctionCall: <I>(input: I) => input is I & {
|
|
377
|
-
readonly call_id: string;
|
|
378
377
|
readonly type: "function_call";
|
|
378
|
+
readonly call_id: string;
|
|
379
379
|
readonly name: string;
|
|
380
380
|
readonly arguments: string;
|
|
381
381
|
readonly providerData?: unknown;
|
|
382
382
|
};
|
|
383
383
|
declare const isFunctionCallOutput: <I>(input: I) => input is I & {
|
|
384
|
-
readonly call_id: string;
|
|
385
384
|
readonly type: "function_call_output";
|
|
385
|
+
readonly call_id: string;
|
|
386
386
|
readonly output: string;
|
|
387
387
|
readonly providerData?: unknown;
|
|
388
388
|
};
|
|
@@ -421,4 +421,4 @@ declare const assistantText: (text: string) => Message;
|
|
|
421
421
|
declare const functionCallOutput: (call_id: string, output: string) => FunctionCallOutput;
|
|
422
422
|
//#endregion
|
|
423
423
|
export { isInputText as A, functionCallOutput as C, isFunctionCall as D, isFilePath as E, isUrlCitation as F, systemText as I, userText as L, isOutputText as M, isReasoning as N, isFunctionCallOutput as O, isRefusal as P, assistantText as S, isFileCitation as T, Refusal as _, FilePath as a, UrlCitation as b, InputImage as c, Item as d, Items_d_exports as f, Reasoning as g, OutputTokensDetails as h, FileCitation as i, isMessage as j, isInputImage as k, InputText as l, OutputText as m, ContainerFileCitation as n, FunctionCall as o, Message as p, ContentBlock as r, FunctionCallOutput as s, Annotation as t, InputTokensDetails as u, Role as v, isContainerFileCitation as w, Usage as x, StopReason as y };
|
|
424
|
-
//# sourceMappingURL=Items-
|
|
424
|
+
//# sourceMappingURL=Items-BH8xUkoR.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Items-
|
|
1
|
+
{"version":3,"file":"Items-BH8xUkoR.d.mts","names":[],"sources":["../src/domain/Items.ts"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { o as FunctionCall, s as FunctionCallOutput } from "./Items-
|
|
1
|
+
import { o as FunctionCall, s as FunctionCallOutput } from "./Items-BH8xUkoR.mjs";
|
|
2
2
|
import { Effect, Schema, Stream } from "effect";
|
|
3
3
|
import * as _$effect_Cause0 from "effect/Cause";
|
|
4
4
|
import { StandardJSONSchemaV1, StandardSchemaV1 } from "@standard-schema/spec";
|
|
@@ -99,4 +99,4 @@ declare const toDescriptors: <R>(tools: ReadonlyArray<AnyKindTool<R>>) => Readon
|
|
|
99
99
|
declare const execute: <Name extends string, Input, Output, R>(tool: Tool<Name, Input, Output, R>, call: FunctionCall) => Effect.Effect<FunctionCallOutput, ToolError, R>;
|
|
100
100
|
//#endregion
|
|
101
101
|
export { Tool as a, ToolInputSchema as c, fromEffectSchema as d, fromStandardSchema as f, toDescriptors as g, streaming as h, StreamingTool as i, Tool_d_exports as l, make as m, AnyPlainTool as n, ToolDescriptor as o, isStreamingTool as p, AnyStreamingTool as r, ToolError as s, AnyKindTool as t, execute as u };
|
|
102
|
-
//# sourceMappingURL=Tool-
|
|
102
|
+
//# sourceMappingURL=Tool-87ViKCCO.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tool-
|
|
1
|
+
{"version":3,"file":"Tool-87ViKCCO.d.mts","names":[],"sources":["../src/tool/Tool.ts"],"mappings":";;;;;;;;;cAE0E,cAAA;;;;;;cAG7D,SAAA,SAAkB,cAAA;;;;;;;;;;KAmBnB,eAAA,oBAAmC,gBAAA,UAA0B,KAAA,IACvE,oBAAA,UAA8B,KAAA;;;;AAvB0C;;cA8B7D,gBAAA,aAA8B,MAAA,CAAO,KAAA,wBAChD,MAAA,EAAQ,CAAA,KACP,CAAA,GAAI,eAAA,CAAgB,CAAA;;;;;;;;;;;;;;;;cAmBV,kBAAA,aAAgC,gBAAA,GAAmB,oBAAA,EAC9D,MAAA,EAAQ,CAAA,KACP,CAAA,GAAI,eAAA,CAAgB,gBAAA,CAAiB,WAAA,CAAY,CAAA;AAAA,KAGxC,IAAA;EAAA,SACD,IAAA,EAAM,IAAA;EAAA,SACN,WAAA;EAAA,SACA,WAAA,EAAa,eAAA,CAAgB,KAAA;EAAA,SAC7B,GAAA,GAAM,KAAA,EAAO,KAAA,KAAU,MAAA,CAAO,MAAA,CAAO,MAAA,WAAiB,CAAA;;;;;;;WAOtD,MAAA;AAAA;;;;;AAhEX;KAwEY,cAAA;EAAA,SACD,IAAA;EAAA,SACA,WAAA;EAAA,SACA,WAAA,EAAa,MAAA;EAAA,SACb,MAAA;AAAA;AAAA,cAGE,IAAA,kDACX,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,CAAA,MAC/B,IAAA,CAAK,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,CAAA;AAAA,KAWjB,aAAA;EAAA,SACD,KAAA;EAAA,SACA,IAAA,EAAM,IAAA;EAAA,SACN,WAAA;EAAA,SACA,WAAA,EAAa,eAAA,CAAgB,KAAA;EAAA,SAC7B,GAAA,GAAM,KAAA,EAAO,KAAA,KAAU,MAAA,CAAO,MAAA,CAAO,KAAA,WAAgB,CAAA;EAAA,SACrD,QAAA,GAAW,MAAA,EAAQ,aAAA,CAAc,KAAA,MAAW,MAAA;EAAA,SAC5C,MAAA;AAAA;AAAA,cAGE,SAAA,yDACX,IAAA,EAAM,IAAA,CAAK,aAAA,CAAc,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,MAAA,EAAQ,CAAA,gBACpD,aAAA,CAAc,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,MAAA,EAAQ,CAAA;AAAA,KAEjC,gBAAA,YAA4B,aAAA,wBAAqC,CAAA;AAAA,KACjE,YAAA,YAAwB,IAAA,mBAAuB,CAAA;AAAA,KAC/C,WAAA,YAAuB,gBAAA,CAAiB,CAAA,IAAK,YAAA,CAAa,CAAA;AAAA,cAEzD,eAAA,MAAsB,CAAA,EAAG,WAAA,CAAY,CAAA,MAAK,CAAA,IAAK,gBAAA,CAAiB,CAAA;;;;;;cAQhE,aAAA,MACX,KAAA,EAAO,aAAA,CAAc,WAAA,CAAY,CAAA,OAChC,aAAA,CAAc,cAAA;;;;;;cAkBJ,OAAA,0CACX,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,CAAA,GAChC,IAAA,EAAM,YAAA,KACL,MAAA,CAAO,MAAA,CAAO,kBAAA,EAAoB,SAAA,EAAW,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as ImageSource } from "./Image-HNmMpMTh.mjs";
|
|
2
|
-
import { d as Item, g as Reasoning, o as FunctionCall, p as Message, s as FunctionCallOutput, x as Usage } from "./Items-
|
|
2
|
+
import { d as Item, g as Reasoning, o as FunctionCall, p as Message, s as FunctionCallOutput, x as Usage } from "./Items-BH8xUkoR.mjs";
|
|
3
3
|
import { i as StructuredFormat, n as JsonParseError, r as StructuredDecodeError } from "./StructuredFormat-BbN4dosH.mjs";
|
|
4
4
|
import { Data, Effect, Schema, Stream } from "effect";
|
|
5
5
|
import * as _$effect_Types0 from "effect/Types";
|
|
@@ -385,4 +385,4 @@ declare class RefusalRejected extends RefusalRejected_base<{
|
|
|
385
385
|
declare const toStructured: <A>(turn: Turn, format: StructuredFormat<A>) => Effect.Effect<A, RefusalRejected | JsonParseError | StructuredDecodeError>;
|
|
386
386
|
//#endregion
|
|
387
387
|
export { Turn_d_exports as a, assistantText as c, isTurnComplete as d, reasonings as f, TurnEvent as i, assistantTexts as l, toStructured as m, RefusalRejected as n, appendTurn as o, textDeltas as p, Turn as r, assistantMessages as s, InteractionEvent as t, functionCalls as u };
|
|
388
|
-
//# sourceMappingURL=Turn-
|
|
388
|
+
//# sourceMappingURL=Turn-0CwCAyVe.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Turn-
|
|
1
|
+
{"version":3,"file":"Turn-0CwCAyVe.d.mts","names":[],"sources":["../src/domain/Turn.ts"],"mappings":";;;;;;;;;;;;;;;;;cAmBa,IAAA,EAAI,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAKL,IAAA,UAAc,IAAA,CAAK,IAAA;;;;;;;;;;;;;;;;;;;;KAqBnB,SAAA,GAAY,IAAA,CAAK,UAAA;EAC3B,SAAA;IAAA,SAAsB,IAAA;EAAA;EACtB,cAAA;IAAA,SAA2B,IAAA;IAAA,SAAuB,IAAA;EAAA;EAClD,YAAA;IAAA,SAAyB,IAAA;EAAA;EACzB,aAAA;IAAA,SAA0B,OAAA;IAAA,SAA0B,IAAA;EAAA;EACpD,iBAAA;IAAA,SAA8B,OAAA;IAAA,SAA0B,KAAA;EAAA;EACxD,WAAA;IAAA,SAAwB,KAAA,EAAO,KAAA;EAAA;EAC/B,YAAA;IAAA,SAAyB,IAAA,EAAM,IAAA;EAAA;AAAA;AAAA,cAGpB,SAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;oBAJoB,KAAA;EAAA;EAAA;;mBACA,IAAA;EAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBADA,KAAA;EAAA;IAAA;;;mBACA,IAAA;EAAA;IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBADA,KAAA;MAAA;MAAA;;uBACA,IAAA;MAAA;IAAA;;;;;;;;;;;;;;;;;;;;sBADA,KAAA;IAAA;MAAA;qBACA,IAAA;IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;wBADA,KAAA;MAAA;MAAA;;uBACA,IAAA;MAAA;IAAA;;;;;;;;;;;;;;;;;;;;sBADA,KAAA;IAAA;MAAA;qBACA,IAAA;IAAA;;;;;;;;;KAWrB,gBAAA,GAAmB,SAAA,GAAY,kBAAA;AAAA,cAE9B,cAAA,GAAc,CAAA,cAAA,CAAA;EAAA;iBAbM,IAAA;AAAA;AAAA,cAepB,aAAA,GAAiB,IAAA,EAAM,IAAA,KAAO,aAAA,CAAc,YAAA;AAAA,cAG5C,UAAA,GAAc,IAAA,EAAM,IAAA,KAAO,aAAA,CAAc,SAAA;AAAA,cAGzC,iBAAA,GAAqB,IAAA,EAAM,IAAA,KAAO,aAAA,CAAc,OAAA;;;;;;;;cAUhD,cAAA,GAAkB,IAAA,EAAM,IAAA,KAAO,aAAA;;;;;;cAW/B,aAAA,GAAiB,IAAA,EAAM,IAAA;;;;;AAjDpC;cAwDa,UAAA;EAAA,SAAmC,OAAA,EAAS,aAAA,CAAc,IAAA;AAAA,GACrE,KAAA,EAAO,CAAA,EACP,IAAA,EAAM,IAAA,EACN,KAAA,GAAO,aAAA,CAAc,IAAA,MACpB,CAAA;;;;;;cAcU,UAAA,SACX,IAAA,EAAM,MAAA,CAAO,MAAA,CAAO,SAAA,EAAW,CAAA,EAAG,CAAA,MACjC,MAAA,CAAO,MAAA,SAAe,CAAA,EAAG,CAAA;AAAA,cAGzB,oBAAA;;;;;;;;cAWU,eAAA,SAAwB,oBAAA;EAAA,SAC1B,IAAA,EAAM,IAAA;AAAA;;;;;;;;;;AAjFjB;cA0Ga,YAAA,MACX,IAAA,EAAM,IAAA,EACN,MAAA,EAAQ,gBAAA,CAAkC,CAAA,MACzC,MAAA,CAAO,MAAA,CACR,CAAA,EACA,eAAA,GAAkB,cAAA,GAAkC,qBAAA"}
|
package/dist/domain/Items.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as isInputText, C as functionCallOutput, D as isFunctionCall, E as isFilePath, F as isUrlCitation, I as systemText, L as userText, M as isOutputText, N as isReasoning, O as isFunctionCallOutput, P as isRefusal, S as assistantText, T as isFileCitation, _ as Refusal, a as FilePath, b as UrlCitation, c as InputImage, d as Item, g as Reasoning, h as OutputTokensDetails, i as FileCitation, j as isMessage, k as isInputImage, l as InputText, m as OutputText, n as ContainerFileCitation, o as FunctionCall, p as Message, r as ContentBlock, s as FunctionCallOutput, t as Annotation, u as InputTokensDetails, v as Role, w as isContainerFileCitation, x as Usage, y as StopReason } from "../Items-
|
|
1
|
+
import { A as isInputText, C as functionCallOutput, D as isFunctionCall, E as isFilePath, F as isUrlCitation, I as systemText, L as userText, M as isOutputText, N as isReasoning, O as isFunctionCallOutput, P as isRefusal, S as assistantText, T as isFileCitation, _ as Refusal, a as FilePath, b as UrlCitation, c as InputImage, d as Item, g as Reasoning, h as OutputTokensDetails, i as FileCitation, j as isMessage, k as isInputImage, l as InputText, m as OutputText, n as ContainerFileCitation, o as FunctionCall, p as Message, r as ContentBlock, s as FunctionCallOutput, t as Annotation, u as InputTokensDetails, v as Role, w as isContainerFileCitation, x as Usage, y as StopReason } from "../Items-BH8xUkoR.mjs";
|
|
2
2
|
export { Annotation, ContainerFileCitation, ContentBlock, FileCitation, FilePath, FunctionCall, FunctionCallOutput, InputImage, InputText, InputTokensDetails, Item, Message, OutputText, OutputTokensDetails, Reasoning, Refusal, Role, StopReason, UrlCitation, Usage, assistantText, functionCallOutput, isContainerFileCitation, isFileCitation, isFilePath, isFunctionCall, isFunctionCallOutput, isInputImage, isInputText, isMessage, isOutputText, isReasoning, isRefusal, isUrlCitation, systemText, userText };
|
package/dist/domain/Turn.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { c as assistantText, d as isTurnComplete, f as reasonings, i as TurnEvent, l as assistantTexts, m as toStructured, n as RefusalRejected, o as appendTurn, p as textDeltas, r as Turn, s as assistantMessages, t as InteractionEvent, u as functionCalls } from "../Turn-
|
|
1
|
+
import { c as assistantText, d as isTurnComplete, f as reasonings, i as TurnEvent, l as assistantTexts, m as toStructured, n as RefusalRejected, o as appendTurn, p as textDeltas, r as Turn, s as assistantMessages, t as InteractionEvent, u as functionCalls } from "../Turn-0CwCAyVe.mjs";
|
|
2
2
|
export { InteractionEvent, RefusalRejected, Turn, TurnEvent, appendTurn, assistantMessages, assistantText, assistantTexts, functionCalls, isTurnComplete, reasonings, textDeltas, toStructured };
|
package/dist/index.d.mts
CHANGED
|
@@ -2,20 +2,21 @@ import { n as AiError_d_exports } from "./AiError-CAX_48RU.mjs";
|
|
|
2
2
|
import { a as Media_d_exports } from "./Media-D_CpcM1Z.mjs";
|
|
3
3
|
import { o as Audio_d_exports } from "./Audio-BfCTGnH3.mjs";
|
|
4
4
|
import { o as Image_d_exports } from "./Image-HNmMpMTh.mjs";
|
|
5
|
-
import { f as Items_d_exports } from "./Items-
|
|
5
|
+
import { f as Items_d_exports } from "./Items-BH8xUkoR.mjs";
|
|
6
6
|
import { t as Music_d_exports } from "./domain/Music.mjs";
|
|
7
7
|
import { t as Transcript_d_exports } from "./domain/Transcript.mjs";
|
|
8
8
|
import { a as StructuredFormat_d_exports } from "./StructuredFormat-BbN4dosH.mjs";
|
|
9
|
-
import { a as Turn_d_exports } from "./Turn-
|
|
9
|
+
import { a as Turn_d_exports } from "./Turn-0CwCAyVe.mjs";
|
|
10
10
|
import { t as Embedding_d_exports } from "./embedding-model/Embedding.mjs";
|
|
11
11
|
import { t as EmbeddingModel_d_exports } from "./embedding-model/EmbeddingModel.mjs";
|
|
12
|
-
import { l as Tool_d_exports } from "./Tool-
|
|
12
|
+
import { l as Tool_d_exports } from "./Tool-87ViKCCO.mjs";
|
|
13
13
|
import { t as LanguageModel_d_exports } from "./language-model/LanguageModel.mjs";
|
|
14
14
|
import { t as MusicGenerator_d_exports } from "./music-generator/MusicGenerator.mjs";
|
|
15
15
|
import { t as SpeechSynthesizer_d_exports } from "./speech-synthesizer/SpeechSynthesizer.mjs";
|
|
16
16
|
import { t as Transcriber_d_exports } from "./transcriber/Transcriber.mjs";
|
|
17
17
|
import { t as Vector_d_exports } from "./math/Vector.mjs";
|
|
18
18
|
import { t as Loop_d_exports } from "./loop/Loop.mjs";
|
|
19
|
+
import { t as Retry_d_exports } from "./retry/Retry.mjs";
|
|
19
20
|
import { t as Outcome_d_exports } from "./tool/Outcome.mjs";
|
|
20
21
|
import { t as ToolEvent_d_exports } from "./tool/ToolEvent.mjs";
|
|
21
22
|
import { t as Toolkit_d_exports } from "./tool/Toolkit.mjs";
|
|
@@ -25,4 +26,4 @@ import { t as JSONL_d_exports } from "./streaming/JSONL.mjs";
|
|
|
25
26
|
import { t as Lines_d_exports } from "./streaming/Lines.mjs";
|
|
26
27
|
import { t as SSE_d_exports } from "./streaming/SSE.mjs";
|
|
27
28
|
import { t as Metrics_d_exports } from "./observability/Metrics.mjs";
|
|
28
|
-
export { AiError_d_exports as AiError, Audio_d_exports as Audio, Embedding_d_exports as Embedding, EmbeddingModel_d_exports as EmbeddingModel, HistoryCheck_d_exports as HistoryCheck, Image_d_exports as Image, Items_d_exports as Items, JSONL_d_exports as JSONL, LanguageModel_d_exports as LanguageModel, Lines_d_exports as Lines, Loop_d_exports as Loop, Media_d_exports as Media, Metrics_d_exports as Metrics, Music_d_exports as Music, MusicGenerator_d_exports as MusicGenerator, Outcome_d_exports as Outcome, Resolvers_d_exports as Resolvers, SSE_d_exports as SSE, SpeechSynthesizer_d_exports as SpeechSynthesizer, StructuredFormat_d_exports as StructuredFormat, Tool_d_exports as Tool, ToolEvent_d_exports as ToolEvent, Toolkit_d_exports as Toolkit, Transcriber_d_exports as Transcriber, Transcript_d_exports as Transcript, Turn_d_exports as Turn, Vector_d_exports as Vector };
|
|
29
|
+
export { AiError_d_exports as AiError, Audio_d_exports as Audio, Embedding_d_exports as Embedding, EmbeddingModel_d_exports as EmbeddingModel, HistoryCheck_d_exports as HistoryCheck, Image_d_exports as Image, Items_d_exports as Items, JSONL_d_exports as JSONL, LanguageModel_d_exports as LanguageModel, Lines_d_exports as Lines, Loop_d_exports as Loop, Media_d_exports as Media, Metrics_d_exports as Metrics, Music_d_exports as Music, MusicGenerator_d_exports as MusicGenerator, Outcome_d_exports as Outcome, Resolvers_d_exports as Resolvers, Retry_d_exports as Retry, SSE_d_exports as SSE, SpeechSynthesizer_d_exports as SpeechSynthesizer, StructuredFormat_d_exports as StructuredFormat, Tool_d_exports as Tool, ToolEvent_d_exports as ToolEvent, Toolkit_d_exports as Toolkit, Transcriber_d_exports as Transcriber, Transcript_d_exports as Transcript, Turn_d_exports as Turn, Vector_d_exports as Vector };
|
package/dist/index.mjs
CHANGED
|
@@ -15,6 +15,7 @@ import { t as SpeechSynthesizer_exports } from "./speech-synthesizer/SpeechSynth
|
|
|
15
15
|
import { t as Transcriber_exports } from "./transcriber/Transcriber.mjs";
|
|
16
16
|
import { t as Vector_exports } from "./math/Vector.mjs";
|
|
17
17
|
import { t as Loop_exports } from "./loop/Loop.mjs";
|
|
18
|
+
import { t as Retry_exports } from "./retry/Retry.mjs";
|
|
18
19
|
import { t as Tool_exports } from "./tool/Tool.mjs";
|
|
19
20
|
import { t as Outcome_exports } from "./tool/Outcome.mjs";
|
|
20
21
|
import { t as ToolEvent_exports } from "./tool/ToolEvent.mjs";
|
|
@@ -25,4 +26,4 @@ import { t as JSONL_exports } from "./streaming/JSONL.mjs";
|
|
|
25
26
|
import { t as Lines_exports } from "./streaming/Lines.mjs";
|
|
26
27
|
import { t as SSE_exports } from "./streaming/SSE.mjs";
|
|
27
28
|
import { t as Metrics_exports } from "./observability/Metrics.mjs";
|
|
28
|
-
export { AiError_exports as AiError, Audio_exports as Audio, Embedding_exports as Embedding, EmbeddingModel_exports as EmbeddingModel, HistoryCheck_exports as HistoryCheck, Image_exports as Image, Items_exports as Items, JSONL_exports as JSONL, LanguageModel_exports as LanguageModel, Lines_exports as Lines, Loop_exports as Loop, Media_exports as Media, Metrics_exports as Metrics, Music_exports as Music, MusicGenerator_exports as MusicGenerator, Outcome_exports as Outcome, Resolvers_exports as Resolvers, SSE_exports as SSE, SpeechSynthesizer_exports as SpeechSynthesizer, StructuredFormat_exports as StructuredFormat, Tool_exports as Tool, ToolEvent_exports as ToolEvent, Toolkit_exports as Toolkit, Transcriber_exports as Transcriber, Transcript_exports as Transcript, Turn_exports as Turn, Vector_exports as Vector };
|
|
29
|
+
export { AiError_exports as AiError, Audio_exports as Audio, Embedding_exports as Embedding, EmbeddingModel_exports as EmbeddingModel, HistoryCheck_exports as HistoryCheck, Image_exports as Image, Items_exports as Items, JSONL_exports as JSONL, LanguageModel_exports as LanguageModel, Lines_exports as Lines, Loop_exports as Loop, Media_exports as Media, Metrics_exports as Metrics, Music_exports as Music, MusicGenerator_exports as MusicGenerator, Outcome_exports as Outcome, Resolvers_exports as Resolvers, Retry_exports as Retry, SSE_exports as SSE, SpeechSynthesizer_exports as SpeechSynthesizer, StructuredFormat_exports as StructuredFormat, Tool_exports as Tool, ToolEvent_exports as ToolEvent, Toolkit_exports as Toolkit, Transcriber_exports as Transcriber, Transcript_exports as Transcript, Turn_exports as Turn, Vector_exports as Vector };
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { d as Item } from "../Items-
|
|
1
|
+
import { t as AiError } from "../AiError-CAX_48RU.mjs";
|
|
2
|
+
import { d as Item } from "../Items-BH8xUkoR.mjs";
|
|
3
3
|
import { i as StructuredFormat } from "../StructuredFormat-BbN4dosH.mjs";
|
|
4
|
-
import { i as TurnEvent, r as Turn } from "../Turn-
|
|
5
|
-
import { o as ToolDescriptor } from "../Tool-
|
|
6
|
-
import { Context, Effect,
|
|
7
|
-
import * as _$effect_Types0 from "effect/Types";
|
|
8
|
-
import * as _$effect_Cause0 from "effect/Cause";
|
|
4
|
+
import { i as TurnEvent, r as Turn } from "../Turn-0CwCAyVe.mjs";
|
|
5
|
+
import { o as ToolDescriptor } from "../Tool-87ViKCCO.mjs";
|
|
6
|
+
import { Context, Effect, Stream } from "effect";
|
|
9
7
|
|
|
10
8
|
//#region src/language-model/LanguageModel.d.ts
|
|
11
9
|
declare namespace LanguageModel_d_exports {
|
|
12
|
-
export { CommonRequest, LanguageModel, LanguageModelService,
|
|
10
|
+
export { CommonRequest, LanguageModel, LanguageModelService, streamTurn, turn, turnFromStream };
|
|
13
11
|
}
|
|
14
12
|
/**
|
|
15
13
|
* Cross-provider request shape. Every call carries its own `history` and
|
|
@@ -42,6 +40,16 @@ type CommonRequest = {
|
|
|
42
40
|
};
|
|
43
41
|
type LanguageModelService = {
|
|
44
42
|
readonly streamTurn: (request: CommonRequest) => Stream.Stream<TurnEvent, AiError>;
|
|
43
|
+
/**
|
|
44
|
+
* Drain a single turn and return the assembled `Turn` from the
|
|
45
|
+
* terminal `TurnComplete` event. Fails with `IncompleteTurn` if the
|
|
46
|
+
* stream ends without one.
|
|
47
|
+
*
|
|
48
|
+
* Most providers derive this from `streamTurn` via
|
|
49
|
+
* {@link turnFromStream}; providers with a native non-streaming
|
|
50
|
+
* endpoint may override with a cheaper direct call.
|
|
51
|
+
*/
|
|
52
|
+
readonly turn: (request: CommonRequest) => Effect.Effect<Turn, AiError>;
|
|
45
53
|
};
|
|
46
54
|
declare const LanguageModel_base: Context.ServiceClass<LanguageModel, "@betalyra/effect-uai/LanguageModel", LanguageModelService>;
|
|
47
55
|
declare class LanguageModel extends LanguageModel_base {}
|
|
@@ -50,25 +58,19 @@ declare class LanguageModel extends LanguageModel_base {}
|
|
|
50
58
|
*/
|
|
51
59
|
declare const streamTurn: (request: CommonRequest) => Stream.Stream<TurnEvent, AiError, LanguageModel>;
|
|
52
60
|
/**
|
|
53
|
-
* Drain
|
|
54
|
-
* `
|
|
55
|
-
*
|
|
61
|
+
* Drain a single turn and return the assembled `Turn`. Delegates to the
|
|
62
|
+
* service's `turn` method — providers with a native complete endpoint
|
|
63
|
+
* can override; the rest get the default streamTurn-drain via
|
|
64
|
+
* {@link turnFromStream}.
|
|
56
65
|
*/
|
|
57
|
-
declare const turn: (request: CommonRequest) => Effect.Effect<Turn, AiError
|
|
58
|
-
declare const Retryable_base: new <A extends Record<string, any> = {}>(args: _$effect_Types0.VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => _$effect_Cause0.YieldableError & {
|
|
59
|
-
readonly _tag: "RetryableAi";
|
|
60
|
-
} & Readonly<A>;
|
|
61
|
-
/** Internal wrapper around the retryable subset of `AiError`. */
|
|
62
|
-
declare class Retryable extends Retryable_base<{
|
|
63
|
-
readonly cause: RateLimited | Unavailable | Timeout;
|
|
64
|
-
}> {}
|
|
66
|
+
declare const turn: (request: CommonRequest) => Effect.Effect<Turn, AiError, LanguageModel>;
|
|
65
67
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
68
|
+
* Build a `turn` implementation from a `streamTurn` implementation.
|
|
69
|
+
* Providers without a native non-streaming endpoint use this to
|
|
70
|
+
* populate the service's `turn` field. Generic over the request type so
|
|
71
|
+
* provider-typed services (with their narrowed request) can reuse it.
|
|
70
72
|
*/
|
|
71
|
-
declare const
|
|
73
|
+
declare const turnFromStream: <Req>(streamTurn: (request: Req) => Stream.Stream<TurnEvent, AiError>) => (request: Req) => Effect.Effect<Turn, AiError>;
|
|
72
74
|
//#endregion
|
|
73
|
-
export { CommonRequest, LanguageModel, LanguageModelService,
|
|
75
|
+
export { CommonRequest, LanguageModel, LanguageModelService, streamTurn, LanguageModel_d_exports as t, turn, turnFromStream };
|
|
74
76
|
//# sourceMappingURL=LanguageModel.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LanguageModel.d.mts","names":[],"sources":["../../src/language-model/LanguageModel.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"LanguageModel.d.mts","names":[],"sources":["../../src/language-model/LanguageModel.ts"],"mappings":";;;;;;;;;;;;;;;;;KAaY,aAAA;EAAA,SACD,OAAA,EAAS,aAAA,CAAc,IAAA;;;;AADlC;WAMW,KAAA;EAAA,SACA,KAAA,GAAQ,aAAA,CAAc,cAAA;EAAA,SACtB,UAAA;IAAA,SAIM,IAAA;IAAA,SAA2B,IAAA;EAAA;EAAA,SACjC,WAAA;EAAA,SACA,IAAA;EAAA,SACA,eAAA;EAdA;;;;;;EAAA,SAqBA,UAAA,GAAa,gBAAA;AAAA;AAAA,KAGZ,oBAAA;EAAA,SACD,UAAA,GAAa,OAAA,EAAS,aAAA,KAAkB,MAAA,CAAO,MAAA,CAAO,SAAA,EAAW,OAAA;EAbjE;;;;;;;;AAYX;EAZW,SAuBA,IAAA,GAAO,OAAA,EAAS,aAAA,KAAkB,MAAA,CAAO,MAAA,CAAO,IAAA,EAAM,OAAA;AAAA;AAAA,cAChE,kBAAA;cAEY,aAAA,SAAsB,kBAAA;;;;cAOtB,UAAA,GACX,OAAA,EAAS,aAAA,KACR,MAAA,CAAO,MAAA,CAAO,SAAA,EAAW,OAAA,EAAiB,aAAA;;;;;;;cAShC,IAAA,GAAQ,OAAA,EAAS,aAAA,KAAgB,MAAA,CAAO,MAAA,CAAO,IAAA,EAAM,OAAA,EAAiB,aAAA;;;;;;;cAStE,cAAA,QACL,UAAA,GAAa,OAAA,EAAS,GAAA,KAAQ,MAAA,CAAO,MAAA,CAAO,SAAA,EAAW,OAAA,OAC5D,OAAA,EAAS,GAAA,KAAM,MAAA,CAAO,MAAA,CAAO,IAAA,EAAM,OAAA"}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { n as __exportAll } from "../chunk-uyGKjUfl.mjs";
|
|
2
2
|
import { IncompleteTurn } from "../domain/AiError.mjs";
|
|
3
3
|
import { isTurnComplete } from "../domain/Turn.mjs";
|
|
4
|
-
import { Array, Context,
|
|
4
|
+
import { Array, Context, Effect, Option, Stream } from "effect";
|
|
5
5
|
//#region src/language-model/LanguageModel.ts
|
|
6
6
|
var LanguageModel_exports = /* @__PURE__ */ __exportAll({
|
|
7
7
|
LanguageModel: () => LanguageModel,
|
|
8
|
-
Retryable: () => Retryable,
|
|
9
|
-
retry: () => retry,
|
|
10
8
|
streamTurn: () => streamTurn,
|
|
11
|
-
turn: () => turn
|
|
9
|
+
turn: () => turn,
|
|
10
|
+
turnFromStream: () => turnFromStream
|
|
12
11
|
});
|
|
13
12
|
var LanguageModel = class extends Context.Service()("@betalyra/effect-uai/LanguageModel") {};
|
|
14
13
|
/**
|
|
@@ -16,31 +15,23 @@ var LanguageModel = class extends Context.Service()("@betalyra/effect-uai/Langua
|
|
|
16
15
|
*/
|
|
17
16
|
const streamTurn = (request) => Stream.unwrap(Effect.map(LanguageModel.asEffect(), (m) => m.streamTurn(request)));
|
|
18
17
|
/**
|
|
19
|
-
* Drain
|
|
20
|
-
* `
|
|
21
|
-
*
|
|
18
|
+
* Drain a single turn and return the assembled `Turn`. Delegates to the
|
|
19
|
+
* service's `turn` method — providers with a native complete endpoint
|
|
20
|
+
* can override; the rest get the default streamTurn-drain via
|
|
21
|
+
* {@link turnFromStream}.
|
|
22
22
|
*/
|
|
23
|
-
const turn = (request) =>
|
|
23
|
+
const turn = (request) => Effect.flatMap(LanguageModel.asEffect(), (m) => m.turn(request));
|
|
24
|
+
/**
|
|
25
|
+
* Build a `turn` implementation from a `streamTurn` implementation.
|
|
26
|
+
* Providers without a native non-streaming endpoint use this to
|
|
27
|
+
* populate the service's `turn` field. Generic over the request type so
|
|
28
|
+
* provider-typed services (with their narrowed request) can reuse it.
|
|
29
|
+
*/
|
|
30
|
+
const turnFromStream = (streamTurn) => (request) => streamTurn(request).pipe(Stream.runCollect, Effect.flatMap((events) => Array.findLast(events, isTurnComplete).pipe(Option.match({
|
|
24
31
|
onNone: () => Effect.fail(new IncompleteTurn({})),
|
|
25
32
|
onSome: (e) => Effect.succeed(e.turn)
|
|
26
33
|
}))));
|
|
27
|
-
/** Internal wrapper around the retryable subset of `AiError`. */
|
|
28
|
-
var Retryable = class extends Data.TaggedError("RetryableAi") {};
|
|
29
|
-
const isRetryable = (e) => e._tag === "RateLimited" || e._tag === "Unavailable" || e._tag === "Timeout";
|
|
30
|
-
/**
|
|
31
|
-
* Retry a stream of `AiError` on the retryable subset
|
|
32
|
-
* (`RateLimited | Unavailable | Timeout`). Other failures bypass the
|
|
33
|
-
* schedule and propagate unchanged. Like all `Stream.retry`, the entire
|
|
34
|
-
* stream re-runs — deltas before the failure replay on the next attempt.
|
|
35
|
-
*/
|
|
36
|
-
const retry = (schedule) => (stream) => stream.pipe(Stream.map((value) => ({
|
|
37
|
-
_tag: "Item",
|
|
38
|
-
value
|
|
39
|
-
})), Stream.catchIf(isRetryable, (cause) => Stream.fail(new Retryable({ cause })), (cause) => Stream.succeed({
|
|
40
|
-
_tag: "Terminal",
|
|
41
|
-
cause
|
|
42
|
-
})), Stream.retry(schedule), Stream.catchTag("RetryableAi", (e) => Stream.fail(e.cause)), Stream.flatMap((item) => item._tag === "Item" ? Stream.succeed(item.value) : Stream.fail(item.cause)));
|
|
43
34
|
//#endregion
|
|
44
|
-
export { LanguageModel,
|
|
35
|
+
export { LanguageModel, streamTurn, LanguageModel_exports as t, turn, turnFromStream };
|
|
45
36
|
|
|
46
37
|
//# sourceMappingURL=LanguageModel.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LanguageModel.mjs","names":["Arr","AiError.IncompleteTurn"],"sources":["../../src/language-model/LanguageModel.ts"],"sourcesContent":["import { Array as Arr, Context,
|
|
1
|
+
{"version":3,"file":"LanguageModel.mjs","names":["Arr","AiError.IncompleteTurn"],"sources":["../../src/language-model/LanguageModel.ts"],"sourcesContent":["import { Array as Arr, Context, Effect, Option, Stream } from \"effect\"\nimport * as AiError from \"../domain/AiError.js\"\nimport type { Item } from \"../domain/Items.js\"\nimport type * as StructuredFormat from \"../structured-format/StructuredFormat.js\"\nimport type { ToolDescriptor } from \"../tool/Tool.js\"\nimport { isTurnComplete, type Turn, type TurnEvent } from \"../domain/Turn.js\"\n\n/**\n * Cross-provider request shape. Every call carries its own `history` and\n * `model` - models are not bound at layer construction. Anything specific\n * to a single provider (reasoning effort, prompt caching, store flags,\n * ...) lives in that provider's own request interface, which extends this.\n */\nexport type CommonRequest = {\n readonly history: ReadonlyArray<Item>\n /**\n * Model identifier. Each provider narrows this to its typed literal union,\n * so code that yields a typed provider tag gets autocompletion.\n */\n readonly model: string\n readonly tools?: ReadonlyArray<ToolDescriptor>\n readonly toolChoice?:\n | \"auto\"\n | \"required\"\n | \"none\"\n | { readonly type: \"function\"; readonly name: string }\n readonly temperature?: number\n readonly topP?: number\n readonly maxOutputTokens?: number\n /**\n * Schema-bound JSON output. The provider constrains the wire to match the\n * schema; pair with `Turn.toStructured` for runtime validation. Supported\n * across all current providers (OpenAI Responses json_schema, Anthropic\n * `output_config`, Gemini `responseJsonSchema`).\n */\n readonly structured?: StructuredFormat.StructuredFormat<unknown>\n}\n\nexport type LanguageModelService = {\n readonly streamTurn: (request: CommonRequest) => Stream.Stream<TurnEvent, AiError.AiError>\n /**\n * Drain a single turn and return the assembled `Turn` from the\n * terminal `TurnComplete` event. Fails with `IncompleteTurn` if the\n * stream ends without one.\n *\n * Most providers derive this from `streamTurn` via\n * {@link turnFromStream}; providers with a native non-streaming\n * endpoint may override with a cheaper direct call.\n */\n readonly turn: (request: CommonRequest) => Effect.Effect<Turn, AiError.AiError>\n}\n\nexport class LanguageModel extends Context.Service<LanguageModel, LanguageModelService>()(\n \"@betalyra/effect-uai/LanguageModel\",\n) {}\n\n/**\n * Stream the deltas of a single turn.\n */\nexport const streamTurn = (\n request: CommonRequest,\n): Stream.Stream<TurnEvent, AiError.AiError, LanguageModel> =>\n Stream.unwrap(Effect.map(LanguageModel.asEffect(), (m) => m.streamTurn(request)))\n\n/**\n * Drain a single turn and return the assembled `Turn`. Delegates to the\n * service's `turn` method — providers with a native complete endpoint\n * can override; the rest get the default streamTurn-drain via\n * {@link turnFromStream}.\n */\nexport const turn = (request: CommonRequest): Effect.Effect<Turn, AiError.AiError, LanguageModel> =>\n Effect.flatMap(LanguageModel.asEffect(), (m) => m.turn(request))\n\n/**\n * Build a `turn` implementation from a `streamTurn` implementation.\n * Providers without a native non-streaming endpoint use this to\n * populate the service's `turn` field. Generic over the request type so\n * provider-typed services (with their narrowed request) can reuse it.\n */\nexport const turnFromStream =\n <Req>(streamTurn: (request: Req) => Stream.Stream<TurnEvent, AiError.AiError>) =>\n (request: Req): Effect.Effect<Turn, AiError.AiError> =>\n streamTurn(request).pipe(\n Stream.runCollect,\n Effect.flatMap((events) =>\n Arr.findLast(events, isTurnComplete).pipe(\n Option.match({\n onNone: () => Effect.fail(new AiError.IncompleteTurn({})),\n onSome: (e) => Effect.succeed(e.turn),\n }),\n ),\n ),\n )\n"],"mappings":";;;;;;;;;;;AAoDA,IAAa,gBAAb,cAAmC,QAAQ,SAA8C,CACvF,qCACD,CAAC;;;;AAKF,MAAa,cACX,YAEA,OAAO,OAAO,OAAO,IAAI,cAAc,UAAU,GAAG,MAAM,EAAE,WAAW,QAAQ,CAAC,CAAC;;;;;;;AAQnF,MAAa,QAAQ,YACnB,OAAO,QAAQ,cAAc,UAAU,GAAG,MAAM,EAAE,KAAK,QAAQ,CAAC;;;;;;;AAQlE,MAAa,kBACL,gBACL,YACC,WAAW,QAAQ,CAAC,KAClB,OAAO,YACP,OAAO,SAAS,WACdA,MAAI,SAAS,QAAQ,eAAe,CAAC,KACnC,OAAO,MAAM;CACX,cAAc,OAAO,KAAK,IAAIC,eAAuB,EAAE,CAAC,CAAC;CACzD,SAAS,MAAM,OAAO,QAAQ,EAAE,KAAK;CACtC,CAAC,CACH,CACF,CACF"}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IncompleteTurn, RateLimited } from "../domain/AiError.mjs";
|
|
2
2
|
import { assistantText, userText } from "../domain/Items.mjs";
|
|
3
3
|
import { TurnEvent } from "../domain/Turn.mjs";
|
|
4
|
-
import { LanguageModel,
|
|
4
|
+
import { LanguageModel, turn, turnFromStream } from "./LanguageModel.mjs";
|
|
5
5
|
import { i as it, n as globalExpect, r as describe } from "../dist-DV5ISja1.mjs";
|
|
6
6
|
import { layer } from "../testing/MockProvider.mjs";
|
|
7
|
-
import { Cause, Effect, Exit, Layer, Option,
|
|
7
|
+
import { Cause, Effect, Exit, Layer, Option, Stream } from "effect";
|
|
8
8
|
//#region src/language-model/LanguageModel.test.ts
|
|
9
|
+
const serviceFromStream = (streamTurn) => ({
|
|
10
|
+
streamTurn,
|
|
11
|
+
turn: turnFromStream(streamTurn)
|
|
12
|
+
});
|
|
9
13
|
const oneTextTurn = (text) => ({
|
|
10
14
|
items: [assistantText(text)],
|
|
11
15
|
usage: {
|
|
@@ -24,7 +28,7 @@ describe("LanguageModel.turn", () => {
|
|
|
24
28
|
globalExpect(await Effect.runPromise(program.pipe(Effect.provide(layer([expected]))))).toEqual(expected);
|
|
25
29
|
});
|
|
26
30
|
it("fails with IncompleteTurn when the stream ends without TurnComplete", async () => {
|
|
27
|
-
const broken = Layer.succeed(LanguageModel,
|
|
31
|
+
const broken = Layer.succeed(LanguageModel, serviceFromStream(() => Stream.fromIterable([TurnEvent.TextDelta({ text: "partial" })])));
|
|
28
32
|
const program = turn({
|
|
29
33
|
history: [userText("hi")],
|
|
30
34
|
model: "mock"
|
|
@@ -42,7 +46,7 @@ describe("LanguageModel.turn", () => {
|
|
|
42
46
|
provider: "mock",
|
|
43
47
|
raw: null
|
|
44
48
|
});
|
|
45
|
-
const failing = Layer.succeed(LanguageModel,
|
|
49
|
+
const failing = Layer.succeed(LanguageModel, serviceFromStream(() => Stream.fail(rateLimited)));
|
|
46
50
|
const program = turn({
|
|
47
51
|
history: [],
|
|
48
52
|
model: "mock"
|
|
@@ -54,7 +58,7 @@ describe("LanguageModel.turn", () => {
|
|
|
54
58
|
it("returns the LAST TurnComplete when the stream contains multiple (defensive)", async () => {
|
|
55
59
|
const first = oneTextTurn("first");
|
|
56
60
|
const second = oneTextTurn("second");
|
|
57
|
-
const weird = Layer.succeed(LanguageModel,
|
|
61
|
+
const weird = Layer.succeed(LanguageModel, serviceFromStream(() => Stream.fromIterable([TurnEvent.TurnComplete({ turn: first }), TurnEvent.TurnComplete({ turn: second })])));
|
|
58
62
|
const program = turn({
|
|
59
63
|
history: [],
|
|
60
64
|
model: "mock"
|
|
@@ -62,81 +66,6 @@ describe("LanguageModel.turn", () => {
|
|
|
62
66
|
globalExpect(await Effect.runPromise(program.pipe(Effect.provide(weird)))).toEqual(second);
|
|
63
67
|
});
|
|
64
68
|
});
|
|
65
|
-
describe("LanguageModel.retry", () => {
|
|
66
|
-
const textDelta = (text) => TurnEvent.TextDelta({ text });
|
|
67
|
-
const textTurn = (text) => ({
|
|
68
|
-
items: [assistantText(text)],
|
|
69
|
-
usage: {
|
|
70
|
-
input_tokens: 0,
|
|
71
|
-
output_tokens: 0
|
|
72
|
-
},
|
|
73
|
-
stop_reason: "stop"
|
|
74
|
-
});
|
|
75
|
-
const completeEvent = (text) => TurnEvent.TurnComplete({ turn: textTurn(text) });
|
|
76
|
-
const attemptStream = (attempts, plan) => Stream.unwrap(Ref.getAndUpdate(attempts, (n) => n + 1).pipe(Effect.map((n) => plan[Math.min(n, plan.length - 1)])));
|
|
77
|
-
it("retries on RateLimited and yields the success on the next attempt", async () => {
|
|
78
|
-
const program = Effect.gen(function* () {
|
|
79
|
-
const attempts = yield* Ref.make(0);
|
|
80
|
-
const stream = attemptStream(attempts, [Stream.fail(new RateLimited({
|
|
81
|
-
provider: "mock",
|
|
82
|
-
raw: null
|
|
83
|
-
})), Stream.fromIterable([textDelta("ok"), completeEvent("ok")])]).pipe(retry(Schedule.recurs(3)));
|
|
84
|
-
const events = yield* Stream.runCollect(stream);
|
|
85
|
-
const count = yield* Ref.get(attempts);
|
|
86
|
-
return {
|
|
87
|
-
events: Array.from(events),
|
|
88
|
-
count
|
|
89
|
-
};
|
|
90
|
-
});
|
|
91
|
-
const { events, count } = await Effect.runPromise(program);
|
|
92
|
-
globalExpect(count).toBe(2);
|
|
93
|
-
globalExpect(events.map((e) => e._tag)).toEqual(["TextDelta", "TurnComplete"]);
|
|
94
|
-
});
|
|
95
|
-
it("surfaces the underlying retryable failure when retries are exhausted", async () => {
|
|
96
|
-
const cause = new Unavailable({
|
|
97
|
-
provider: "mock",
|
|
98
|
-
raw: null
|
|
99
|
-
});
|
|
100
|
-
const stream = Stream.fail(cause).pipe(retry(Schedule.recurs(2)));
|
|
101
|
-
const exit = await Effect.runPromise(Effect.exit(Stream.runCollect(stream)));
|
|
102
|
-
globalExpect(Exit.isFailure(exit)).toBe(true);
|
|
103
|
-
if (Exit.isFailure(exit)) globalExpect(Cause.findErrorOption(exit.cause)).toEqual(Option.some(cause));
|
|
104
|
-
});
|
|
105
|
-
it("bypasses retry for non-retryable AiError (ContentFiltered)", async () => {
|
|
106
|
-
const program = Effect.gen(function* () {
|
|
107
|
-
const attempts = yield* Ref.make(0);
|
|
108
|
-
const cause = new ContentFiltered({
|
|
109
|
-
provider: "mock",
|
|
110
|
-
raw: null
|
|
111
|
-
});
|
|
112
|
-
const stream = attemptStream(attempts, [Stream.fail(cause)]).pipe(retry(Schedule.recurs(5)));
|
|
113
|
-
return {
|
|
114
|
-
exit: yield* Effect.exit(Stream.runCollect(stream)),
|
|
115
|
-
count: yield* Ref.get(attempts),
|
|
116
|
-
cause
|
|
117
|
-
};
|
|
118
|
-
});
|
|
119
|
-
const { exit, count, cause } = await Effect.runPromise(program);
|
|
120
|
-
globalExpect(count).toBe(1);
|
|
121
|
-
globalExpect(Exit.isFailure(exit)).toBe(true);
|
|
122
|
-
if (Exit.isFailure(exit)) globalExpect(Cause.findErrorOption(exit.cause)).toEqual(Option.some(cause));
|
|
123
|
-
});
|
|
124
|
-
it("preserves deltas emitted before a retryable failure (and replays on retry)", async () => {
|
|
125
|
-
const program = Effect.gen(function* () {
|
|
126
|
-
const stream = attemptStream(yield* Ref.make(0), [Stream.concat(Stream.succeed(textDelta("partial")), Stream.fail(new Timeout({
|
|
127
|
-
provider: "mock",
|
|
128
|
-
raw: null
|
|
129
|
-
}))), Stream.fromIterable([textDelta("partial"), completeEvent("done")])]).pipe(retry(Schedule.recurs(1)));
|
|
130
|
-
const events = yield* Stream.runCollect(stream);
|
|
131
|
-
return Array.from(events);
|
|
132
|
-
});
|
|
133
|
-
globalExpect((await Effect.runPromise(program)).map((e) => e._tag)).toEqual([
|
|
134
|
-
"TextDelta",
|
|
135
|
-
"TextDelta",
|
|
136
|
-
"TurnComplete"
|
|
137
|
-
]);
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
69
|
//#endregion
|
|
141
70
|
export {};
|
|
142
71
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LanguageModel.test.mjs","names":["Items.assistantText","Items.userText","MockProvider.layer","AiError.IncompleteTurn","AiError.RateLimited","AiError.Unavailable","AiError.ContentFiltered","AiError.Timeout"],"sources":["../../src/language-model/LanguageModel.test.ts"],"sourcesContent":["import { Cause, Effect, Exit, Layer, Option, Ref, Schedule, Stream } from \"effect\"\nimport { describe, expect, it } from \"vitest\"\nimport * as AiError from \"../domain/AiError.js\"\nimport * as Items from \"../domain/Items.js\"\nimport { type Turn, TurnEvent } from \"../domain/Turn.js\"\nimport { LanguageModel, retry, turn } from \"./LanguageModel.js\"\nimport * as MockProvider from \"../testing/MockProvider.js\"\n\nconst oneTextTurn = (text: string): Turn => ({\n items: [Items.assistantText(text)],\n usage: { input_tokens: 1, output_tokens: 1 },\n stop_reason: \"stop\",\n})\n\ndescribe(\"LanguageModel.turn\", () => {\n it(\"returns the assembled Turn from the terminal TurnComplete event\", async () => {\n const expected = oneTextTurn(\"hello world\")\n const program = turn({ history: [Items.userText(\"hi\")], model: \"mock\" })\n\n const result = await Effect.runPromise(\n program.pipe(Effect.provide(MockProvider.layer([expected]))),\n )\n\n expect(result).toEqual(expected)\n })\n\n it(\"fails with IncompleteTurn when the stream ends without TurnComplete\", async () => {\n // Custom service whose stream emits a single TextDelta and then ends.\n const broken = Layer.succeed(LanguageModel, {\n streamTurn: () => Stream.fromIterable<TurnEvent>([TurnEvent.TextDelta({ text: \"partial\" })]),\n })\n\n const program = turn({ history: [Items.userText(\"hi\")], model: \"mock\" })\n const exit = await Effect.runPromise(Effect.exit(program.pipe(Effect.provide(broken))))\n\n expect(Exit.isFailure(exit)).toBe(true)\n if (Exit.isFailure(exit)) {\n const failure = Cause.findErrorOption(exit.cause)\n expect(Option.isSome(failure)).toBe(true)\n if (Option.isSome(failure)) {\n expect(failure.value).toBeInstanceOf(AiError.IncompleteTurn)\n }\n }\n })\n\n it(\"propagates an AiError raised by streamTurn\", async () => {\n const rateLimited = new AiError.RateLimited({ provider: \"mock\", raw: null })\n const failing = Layer.succeed(LanguageModel, {\n streamTurn: () => Stream.fail<AiError.AiError>(rateLimited),\n })\n\n const program = turn({ history: [], model: \"mock\" })\n const exit = await Effect.runPromise(Effect.exit(program.pipe(Effect.provide(failing))))\n\n expect(Exit.isFailure(exit)).toBe(true)\n if (Exit.isFailure(exit)) {\n expect(Cause.findErrorOption(exit.cause)).toEqual(Option.some(rateLimited))\n }\n })\n\n it(\"returns the LAST TurnComplete when the stream contains multiple (defensive)\", async () => {\n // A misbehaving provider might emit two TurnComplete events; turn\n // should pick the last one (the most recent assembled Turn).\n const first = oneTextTurn(\"first\")\n const second = oneTextTurn(\"second\")\n const weird = Layer.succeed(LanguageModel, {\n streamTurn: () =>\n Stream.fromIterable<TurnEvent>([\n TurnEvent.TurnComplete({ turn: first }),\n TurnEvent.TurnComplete({ turn: second }),\n ]),\n })\n\n const program = turn({ history: [], model: \"mock\" })\n const result = await Effect.runPromise(program.pipe(Effect.provide(weird)))\n\n expect(result).toEqual(second)\n })\n})\n\ndescribe(\"LanguageModel.retry\", () => {\n const textDelta = (text: string): TurnEvent => TurnEvent.TextDelta({ text })\n const textTurn = (text: string): Turn => ({\n items: [Items.assistantText(text)],\n usage: { input_tokens: 0, output_tokens: 0 },\n stop_reason: \"stop\",\n })\n const completeEvent = (text: string): TurnEvent =>\n TurnEvent.TurnComplete({ turn: textTurn(text) })\n\n // Builds a stream that emits a failure or success based on attempt counter.\n // Each call to the returned Effect produces a fresh attempt stream.\n const attemptStream = (\n attempts: Ref.Ref<number>,\n plan: ReadonlyArray<Stream.Stream<TurnEvent, AiError.AiError>>,\n ): Stream.Stream<TurnEvent, AiError.AiError> =>\n Stream.unwrap(\n Ref.getAndUpdate(attempts, (n) => n + 1).pipe(\n Effect.map((n) => plan[Math.min(n, plan.length - 1)]!),\n ),\n )\n\n it(\"retries on RateLimited and yields the success on the next attempt\", async () => {\n const program = Effect.gen(function* () {\n const attempts = yield* Ref.make(0)\n const stream = attemptStream(attempts, [\n Stream.fail(new AiError.RateLimited({ provider: \"mock\", raw: null })),\n Stream.fromIterable([textDelta(\"ok\"), completeEvent(\"ok\")]),\n ]).pipe(retry(Schedule.recurs(3)))\n const events = yield* Stream.runCollect(stream)\n const count = yield* Ref.get(attempts)\n return { events: Array.from(events), count }\n })\n\n const { events, count } = await Effect.runPromise(program)\n expect(count).toBe(2)\n expect(events.map((e) => e._tag)).toEqual([\"TextDelta\", \"TurnComplete\"])\n })\n\n it(\"surfaces the underlying retryable failure when retries are exhausted\", async () => {\n const cause = new AiError.Unavailable({ provider: \"mock\", raw: null })\n const stream = Stream.fail<AiError.AiError>(cause).pipe(retry(Schedule.recurs(2)))\n\n const exit = await Effect.runPromise(Effect.exit(Stream.runCollect(stream)))\n expect(Exit.isFailure(exit)).toBe(true)\n if (Exit.isFailure(exit)) {\n expect(Cause.findErrorOption(exit.cause)).toEqual(Option.some(cause))\n }\n })\n\n it(\"bypasses retry for non-retryable AiError (ContentFiltered)\", async () => {\n const program = Effect.gen(function* () {\n const attempts = yield* Ref.make(0)\n const cause = new AiError.ContentFiltered({ provider: \"mock\", raw: null })\n const stream = attemptStream(attempts, [Stream.fail(cause)]).pipe(retry(Schedule.recurs(5)))\n const exit = yield* Effect.exit(Stream.runCollect(stream))\n const count = yield* Ref.get(attempts)\n return { exit, count, cause }\n })\n\n const { exit, count, cause } = await Effect.runPromise(program)\n expect(count).toBe(1) // no retry happened\n expect(Exit.isFailure(exit)).toBe(true)\n if (Exit.isFailure(exit)) {\n expect(Cause.findErrorOption(exit.cause)).toEqual(Option.some(cause))\n }\n })\n\n it(\"preserves deltas emitted before a retryable failure (and replays on retry)\", async () => {\n // Documents the 'replays on retry' caveat in the JSDoc — first attempt\n // emits a delta then fails; second attempt is a clean success. Consumer\n // sees the first delta twice (once from the failed attempt, once from\n // the replay).\n const program = Effect.gen(function* () {\n const attempts = yield* Ref.make(0)\n const stream = attemptStream(attempts, [\n Stream.concat(\n Stream.succeed<TurnEvent>(textDelta(\"partial\")),\n Stream.fail(new AiError.Timeout({ provider: \"mock\", raw: null })),\n ),\n Stream.fromIterable([textDelta(\"partial\"), completeEvent(\"done\")]),\n ]).pipe(retry(Schedule.recurs(1)))\n const events = yield* Stream.runCollect(stream)\n return Array.from(events)\n })\n\n const events = await Effect.runPromise(program)\n expect(events.map((e) => e._tag)).toEqual([\"TextDelta\", \"TextDelta\", \"TurnComplete\"])\n })\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LanguageModel.test.mjs","names":["Items.assistantText","Items.userText","MockProvider.layer","AiError.IncompleteTurn","AiError.RateLimited"],"sources":["../../src/language-model/LanguageModel.test.ts"],"sourcesContent":["import { Cause, Effect, Exit, Layer, Option, Stream } from \"effect\"\nimport { describe, expect, it } from \"vitest\"\nimport * as AiError from \"../domain/AiError.js\"\nimport * as Items from \"../domain/Items.js\"\nimport { type Turn, TurnEvent } from \"../domain/Turn.js\"\nimport { LanguageModel, type LanguageModelService, turn, turnFromStream } from \"./LanguageModel.js\"\n\nconst serviceFromStream = (\n streamTurn: LanguageModelService[\"streamTurn\"],\n): LanguageModelService => ({ streamTurn, turn: turnFromStream(streamTurn) })\nimport * as MockProvider from \"../testing/MockProvider.js\"\n\nconst oneTextTurn = (text: string): Turn => ({\n items: [Items.assistantText(text)],\n usage: { input_tokens: 1, output_tokens: 1 },\n stop_reason: \"stop\",\n})\n\ndescribe(\"LanguageModel.turn\", () => {\n it(\"returns the assembled Turn from the terminal TurnComplete event\", async () => {\n const expected = oneTextTurn(\"hello world\")\n const program = turn({ history: [Items.userText(\"hi\")], model: \"mock\" })\n\n const result = await Effect.runPromise(\n program.pipe(Effect.provide(MockProvider.layer([expected]))),\n )\n\n expect(result).toEqual(expected)\n })\n\n it(\"fails with IncompleteTurn when the stream ends without TurnComplete\", async () => {\n // Custom service whose stream emits a single TextDelta and then ends.\n const broken = Layer.succeed(\n LanguageModel,\n serviceFromStream(() =>\n Stream.fromIterable<TurnEvent>([TurnEvent.TextDelta({ text: \"partial\" })]),\n ),\n )\n\n const program = turn({ history: [Items.userText(\"hi\")], model: \"mock\" })\n const exit = await Effect.runPromise(Effect.exit(program.pipe(Effect.provide(broken))))\n\n expect(Exit.isFailure(exit)).toBe(true)\n if (Exit.isFailure(exit)) {\n const failure = Cause.findErrorOption(exit.cause)\n expect(Option.isSome(failure)).toBe(true)\n if (Option.isSome(failure)) {\n expect(failure.value).toBeInstanceOf(AiError.IncompleteTurn)\n }\n }\n })\n\n it(\"propagates an AiError raised by streamTurn\", async () => {\n const rateLimited = new AiError.RateLimited({ provider: \"mock\", raw: null })\n const failing = Layer.succeed(\n LanguageModel,\n serviceFromStream(() => Stream.fail<AiError.AiError>(rateLimited)),\n )\n\n const program = turn({ history: [], model: \"mock\" })\n const exit = await Effect.runPromise(Effect.exit(program.pipe(Effect.provide(failing))))\n\n expect(Exit.isFailure(exit)).toBe(true)\n if (Exit.isFailure(exit)) {\n expect(Cause.findErrorOption(exit.cause)).toEqual(Option.some(rateLimited))\n }\n })\n\n it(\"returns the LAST TurnComplete when the stream contains multiple (defensive)\", async () => {\n // A misbehaving provider might emit two TurnComplete events; turn\n // should pick the last one (the most recent assembled Turn).\n const first = oneTextTurn(\"first\")\n const second = oneTextTurn(\"second\")\n const weird = Layer.succeed(\n LanguageModel,\n serviceFromStream(() =>\n Stream.fromIterable<TurnEvent>([\n TurnEvent.TurnComplete({ turn: first }),\n TurnEvent.TurnComplete({ turn: second }),\n ]),\n ),\n )\n\n const program = turn({ history: [], model: \"mock\" })\n const result = await Effect.runPromise(program.pipe(Effect.provide(weird)))\n\n expect(result).toEqual(second)\n })\n})\n"],"mappings":";;;;;;;;AAOA,MAAM,qBACJ,gBAC0B;CAAE;CAAY,MAAM,eAAe,WAAW;CAAE;AAG5E,MAAM,eAAe,UAAwB;CAC3C,OAAO,CAACA,cAAoB,KAAK,CAAC;CAClC,OAAO;EAAE,cAAc;EAAG,eAAe;EAAG;CAC5C,aAAa;CACd;AAED,SAAS,4BAA4B;AACnC,IAAG,mEAAmE,YAAY;EAChF,MAAM,WAAW,YAAY,cAAc;EAC3C,MAAM,UAAU,KAAK;GAAE,SAAS,CAACC,SAAe,KAAK,CAAC;GAAE,OAAO;GAAQ,CAAC;AAMxE,eAAO,MAJc,OAAO,WAC1B,QAAQ,KAAK,OAAO,QAAQC,MAAmB,CAAC,SAAS,CAAC,CAAC,CAAC,CAC7D,CAEa,CAAC,QAAQ,SAAS;GAChC;AAEF,IAAG,uEAAuE,YAAY;EAEpF,MAAM,SAAS,MAAM,QACnB,eACA,wBACE,OAAO,aAAwB,CAAC,UAAU,UAAU,EAAE,MAAM,WAAW,CAAC,CAAC,CAAC,CAC3E,CACF;EAED,MAAM,UAAU,KAAK;GAAE,SAAS,CAACD,SAAe,KAAK,CAAC;GAAE,OAAO;GAAQ,CAAC;EACxE,MAAM,OAAO,MAAM,OAAO,WAAW,OAAO,KAAK,QAAQ,KAAK,OAAO,QAAQ,OAAO,CAAC,CAAC,CAAC;AAEvF,eAAO,KAAK,UAAU,KAAK,CAAC,CAAC,KAAK,KAAK;AACvC,MAAI,KAAK,UAAU,KAAK,EAAE;GACxB,MAAM,UAAU,MAAM,gBAAgB,KAAK,MAAM;AACjD,gBAAO,OAAO,OAAO,QAAQ,CAAC,CAAC,KAAK,KAAK;AACzC,OAAI,OAAO,OAAO,QAAQ,CACxB,cAAO,QAAQ,MAAM,CAAC,eAAeE,eAAuB;;GAGhE;AAEF,IAAG,8CAA8C,YAAY;EAC3D,MAAM,cAAc,IAAIC,YAAoB;GAAE,UAAU;GAAQ,KAAK;GAAM,CAAC;EAC5E,MAAM,UAAU,MAAM,QACpB,eACA,wBAAwB,OAAO,KAAsB,YAAY,CAAC,CACnE;EAED,MAAM,UAAU,KAAK;GAAE,SAAS,EAAE;GAAE,OAAO;GAAQ,CAAC;EACpD,MAAM,OAAO,MAAM,OAAO,WAAW,OAAO,KAAK,QAAQ,KAAK,OAAO,QAAQ,QAAQ,CAAC,CAAC,CAAC;AAExF,eAAO,KAAK,UAAU,KAAK,CAAC,CAAC,KAAK,KAAK;AACvC,MAAI,KAAK,UAAU,KAAK,CACtB,cAAO,MAAM,gBAAgB,KAAK,MAAM,CAAC,CAAC,QAAQ,OAAO,KAAK,YAAY,CAAC;GAE7E;AAEF,IAAG,+EAA+E,YAAY;EAG5F,MAAM,QAAQ,YAAY,QAAQ;EAClC,MAAM,SAAS,YAAY,SAAS;EACpC,MAAM,QAAQ,MAAM,QAClB,eACA,wBACE,OAAO,aAAwB,CAC7B,UAAU,aAAa,EAAE,MAAM,OAAO,CAAC,EACvC,UAAU,aAAa,EAAE,MAAM,QAAQ,CAAC,CACzC,CAAC,CACH,CACF;EAED,MAAM,UAAU,KAAK;GAAE,SAAS,EAAE;GAAE,OAAO;GAAQ,CAAC;AAGpD,eAAO,MAFc,OAAO,WAAW,QAAQ,KAAK,OAAO,QAAQ,MAAM,CAAC,CAAC,CAE7D,CAAC,QAAQ,OAAO;GAC9B;EACF"}
|
package/dist/loop/Loop.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { l as IncompleteTurn } from "../AiError-CAX_48RU.mjs";
|
|
2
|
-
import { i as TurnEvent, r as Turn } from "../Turn-
|
|
2
|
+
import { i as TurnEvent, r as Turn } from "../Turn-0CwCAyVe.mjs";
|
|
3
3
|
import { Data, Effect, Stream, SubscriptionRef } from "effect";
|
|
4
4
|
|
|
5
5
|
//#region src/loop/Loop.d.ts
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { d as RateLimited, m as Unavailable, p as Timeout, t as AiError } from "../AiError-CAX_48RU.mjs";
|
|
2
|
+
import { Effect, Schedule, Stream } from "effect";
|
|
3
|
+
import * as _$effect_Types0 from "effect/Types";
|
|
4
|
+
import * as _$effect_Cause0 from "effect/Cause";
|
|
5
|
+
|
|
6
|
+
//#region src/retry/Retry.d.ts
|
|
7
|
+
declare namespace Retry_d_exports {
|
|
8
|
+
export { Retryable, effect, isRetryable, stream };
|
|
9
|
+
}
|
|
10
|
+
declare const Retryable_base: new <A extends Record<string, any> = {}>(args: _$effect_Types0.VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => _$effect_Cause0.YieldableError & {
|
|
11
|
+
readonly _tag: "RetryableAi";
|
|
12
|
+
} & Readonly<A>;
|
|
13
|
+
/**
|
|
14
|
+
* Subset-aware retry helpers for `AiError`.
|
|
15
|
+
*
|
|
16
|
+
* Effect's own `Effect.retry` / `Stream.retry` apply the schedule to
|
|
17
|
+
* every failure. For AI calls that's the wrong policy — replaying a
|
|
18
|
+
* `ContentFiltered` or `InvalidRequest` won't change the outcome and
|
|
19
|
+
* just wastes quota. These helpers gate the schedule on the
|
|
20
|
+
* {@link Retryable} subset (rate limits, transport hiccups, timeouts);
|
|
21
|
+
* everything else propagates unchanged.
|
|
22
|
+
*
|
|
23
|
+
* Two carriers:
|
|
24
|
+
* - {@link stream} — for `Stream<A, AiError, R>` (e.g. `streamTurn`,
|
|
25
|
+
* `streamSynthesis`, `streamTranscriptionFrom`). Caveat: the entire
|
|
26
|
+
* stream re-runs on retry, so deltas before the failure replay on
|
|
27
|
+
* the next attempt.
|
|
28
|
+
* - {@link effect} — for `Effect<A, AiError, R>` (e.g. `turn`, `embed`,
|
|
29
|
+
* `embedMany`, `synthesize`, `transcribe`). At-most-once.
|
|
30
|
+
*
|
|
31
|
+
* Composes with `Stream.retry` / `Effect.retry` directly (no naming
|
|
32
|
+
* collision since these live under the `Retry` namespace).
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* Wrapper around the retryable subset of `AiError`. Internal to the
|
|
36
|
+
* lift/retry/unlift dance — exported so callers can build their own
|
|
37
|
+
* variants if needed (e.g. a custom schedule that observes `cause`).
|
|
38
|
+
*/
|
|
39
|
+
declare class Retryable extends Retryable_base<{
|
|
40
|
+
readonly cause: RateLimited | Unavailable | Timeout;
|
|
41
|
+
}> {}
|
|
42
|
+
/** Type-narrowing predicate for the retryable subset. */
|
|
43
|
+
declare const isRetryable: (e: AiError) => e is RateLimited | Unavailable | Timeout;
|
|
44
|
+
/**
|
|
45
|
+
* Retry a `Stream<A, AiError, R>` on the retryable subset. Other
|
|
46
|
+
* failures bypass the schedule and propagate unchanged. The whole
|
|
47
|
+
* stream replays on each attempt — deltas emitted before the failure
|
|
48
|
+
* are re-emitted on the next try.
|
|
49
|
+
*/
|
|
50
|
+
declare const stream: <Out>(schedule: Schedule.Schedule<Out, Retryable>) => <A, R>(s: Stream.Stream<A, AiError, R>) => Stream.Stream<A, AiError, R>;
|
|
51
|
+
/**
|
|
52
|
+
* Retry an `Effect<A, AiError, R>` on the retryable subset. Other
|
|
53
|
+
* failures bypass the schedule and propagate unchanged. At-most-once
|
|
54
|
+
* — the underlying call only re-runs if the previous attempt failed
|
|
55
|
+
* with a retryable tag.
|
|
56
|
+
*
|
|
57
|
+
* Skips the lift/unlift dance the Stream variant needs: `Effect.retry`
|
|
58
|
+
* exposes a `while:` predicate so the error channel stays a plain
|
|
59
|
+
* `AiError` throughout.
|
|
60
|
+
*/
|
|
61
|
+
declare const effect: <Out>(schedule: Schedule.Schedule<Out, AiError>) => <A, R>(eff: Effect.Effect<A, AiError, R>) => Effect.Effect<A, AiError, R>;
|
|
62
|
+
//#endregion
|
|
63
|
+
export { Retryable, effect, isRetryable, stream, Retry_d_exports as t };
|
|
64
|
+
//# sourceMappingURL=Retry.d.mts.map
|