@effect-uai/core 0.10.0 → 0.12.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/dist/{Image-BZmKfIdq.d.mts → Image-C4vuBmu0.d.mts} +11 -11
- package/dist/{Image-BZmKfIdq.d.mts.map → Image-C4vuBmu0.d.mts.map} +1 -1
- package/dist/{Items-BnIduEV2.d.mts → Items-BKQgqJ8A.d.mts} +136 -97
- package/dist/Items-BKQgqJ8A.d.mts.map +1 -0
- package/dist/{Tool-2lC_XMth.d.mts → Tool-u5bag8SO.d.mts} +42 -9
- package/dist/Tool-u5bag8SO.d.mts.map +1 -0
- package/dist/{ToolEvent-cWZ2BnbS.d.mts → ToolEvent-BBfOdhF_.d.mts} +2 -2
- package/dist/{ToolEvent-cWZ2BnbS.d.mts.map → ToolEvent-BBfOdhF_.d.mts.map} +1 -1
- package/dist/{ToolResult-CL4hK_9z.d.mts → ToolResult-CRpmkBXR.d.mts} +2 -2
- package/dist/{ToolResult-CL4hK_9z.d.mts.map → ToolResult-CRpmkBXR.d.mts.map} +1 -1
- package/dist/{Toolkit-Dr9l_hNy.d.mts → Toolkit-D4mQvhjq.d.mts} +6 -6
- package/dist/Toolkit-D4mQvhjq.d.mts.map +1 -0
- package/dist/browser/Browser.mjs +4 -4
- package/dist/browser/Browser.mjs.map +1 -1
- package/dist/browser/BrowserTool.d.mts +34 -33
- package/dist/browser/BrowserTool.d.mts.map +1 -1
- package/dist/{dist-DWgRbDN3.mjs → dist-C0m0QnUP.mjs} +71 -30
- package/dist/dist-C0m0QnUP.mjs.map +1 -0
- package/dist/{dist-B04dlFHg.mjs → dist-CcRV3-A5.mjs} +8 -8
- package/dist/{dist-B04dlFHg.mjs.map → dist-CcRV3-A5.mjs.map} +1 -1
- package/dist/domain/Citation.d.mts +60 -0
- package/dist/domain/Citation.d.mts.map +1 -0
- package/dist/domain/Citation.mjs +7 -0
- package/dist/domain/Citation.mjs.map +1 -0
- package/dist/domain/Image.d.mts +1 -1
- package/dist/domain/Items.d.mts +1 -1
- package/dist/domain/Items.mjs +28 -4
- package/dist/domain/Items.mjs.map +1 -1
- package/dist/domain/Research.d.mts +37 -0
- package/dist/domain/Research.d.mts.map +1 -0
- package/dist/domain/Research.mjs +7 -0
- package/dist/domain/Research.mjs.map +1 -0
- package/dist/domain/Turn.d.mts +92 -9
- package/dist/domain/Turn.d.mts.map +1 -1
- package/dist/domain/Turn.mjs +8 -1
- package/dist/domain/Turn.mjs.map +1 -1
- package/dist/domain/Turn.test.mjs +1 -1
- package/dist/embedding-model/Embedding.d.mts +1 -1
- package/dist/embedding-model/EmbeddingModel.mjs +2 -2
- package/dist/embedding-model/EmbeddingModel.mjs.map +1 -1
- package/dist/embedding-model/EmbeddingModel.test.mjs +1 -1
- package/dist/index.d.mts +12 -8
- package/dist/index.mjs +5 -1
- package/dist/job/Job.d.mts +80 -0
- package/dist/job/Job.d.mts.map +1 -0
- package/dist/job/Job.mjs +49 -0
- package/dist/job/Job.mjs.map +1 -0
- package/dist/language-model/LanguageModel.d.mts +2 -2
- package/dist/language-model/LanguageModel.mjs +2 -2
- package/dist/language-model/LanguageModel.mjs.map +1 -1
- package/dist/language-model/LanguageModel.test.mjs +1 -1
- package/dist/loop/Loop.test.mjs +1 -1
- package/dist/music-generator/MusicGenerator.mjs +4 -4
- package/dist/music-generator/MusicGenerator.mjs.map +1 -1
- package/dist/music-generator/MusicGenerator.test.mjs +1 -1
- package/dist/observability/Metrics.d.mts +13 -5
- package/dist/observability/Metrics.d.mts.map +1 -1
- package/dist/observability/Metrics.mjs +30 -7
- package/dist/observability/Metrics.mjs.map +1 -1
- package/dist/observability/Metrics.test.mjs +44 -2
- package/dist/observability/Metrics.test.mjs.map +1 -1
- package/dist/observability/Telemetry.test.mjs +2 -2
- package/dist/research/DeepResearch.d.mts +71 -0
- package/dist/research/DeepResearch.d.mts.map +1 -0
- package/dist/research/DeepResearch.mjs +61 -0
- package/dist/research/DeepResearch.mjs.map +1 -0
- package/dist/retry/Retry.d.mts +3 -3
- package/dist/retry/Retry.d.mts.map +1 -1
- package/dist/retry/Retry.mjs +30 -1
- package/dist/retry/Retry.mjs.map +1 -1
- package/dist/retry/Retry.test.mjs +1 -1
- package/dist/sandbox/Sandbox.mjs +18 -18
- package/dist/sandbox/Sandbox.mjs.map +1 -1
- package/dist/speech-synthesizer/SpeechSynthesizer.mjs +8 -8
- package/dist/speech-synthesizer/SpeechSynthesizer.mjs.map +1 -1
- package/dist/speech-synthesizer/SpeechSynthesizer.test.mjs +1 -1
- package/dist/streaming/JSONL.d.mts +3 -1
- package/dist/streaming/JSONL.d.mts.map +1 -1
- package/dist/streaming/JSONL.mjs +5 -11
- package/dist/streaming/JSONL.mjs.map +1 -1
- package/dist/streaming/JSONL.test.mjs +10 -1
- package/dist/streaming/JSONL.test.mjs.map +1 -1
- package/dist/streaming/SSE.d.mts +5 -3
- package/dist/streaming/SSE.d.mts.map +1 -1
- package/dist/streaming/SSE.mjs +28 -38
- package/dist/streaming/SSE.mjs.map +1 -1
- package/dist/streaming/SSE.test.mjs +54 -4
- package/dist/streaming/SSE.test.mjs.map +1 -1
- package/dist/structured-format/StructuredFormat.test.mjs +1 -1
- package/dist/testing/MockProvider.d.mts +1 -1
- package/dist/testing/MockSandbox.d.mts +1 -1
- package/dist/tool/Approval.d.mts +3 -3
- package/dist/tool/Approval.test.mjs +1 -1
- package/dist/tool/HistoryCheck.d.mts +2 -2
- package/dist/tool/Tool.d.mts +2 -2
- package/dist/tool/Tool.mjs +27 -7
- package/dist/tool/Tool.mjs.map +1 -1
- package/dist/tool/Tool.test.mjs +127 -3
- package/dist/tool/Tool.test.mjs.map +1 -1
- package/dist/tool/ToolEvent.d.mts +1 -1
- package/dist/tool/ToolResult.d.mts +1 -1
- package/dist/tool/Toolkit.d.mts +1 -1
- package/dist/tool/Toolkit.mjs.map +1 -1
- package/dist/tool/Toolkit.test.mjs +46 -2
- package/dist/tool/Toolkit.test.mjs.map +1 -1
- package/dist/transcriber/Transcriber.mjs +3 -3
- package/dist/transcriber/Transcriber.mjs.map +1 -1
- package/dist/transcriber/Transcriber.test.mjs +1 -1
- package/dist/web-read/WebRead.mjs +1 -1
- package/dist/web-read/WebRead.mjs.map +1 -1
- package/dist/web-read/WebReadTool.d.mts +1 -1
- package/dist/web-search/WebSearch.mjs +1 -1
- package/dist/web-search/WebSearch.mjs.map +1 -1
- package/dist/web-search/WebSearchTool.d.mts +1 -1
- package/package.json +19 -3
- package/src/browser/Browser.ts +4 -4
- package/src/domain/Citation.ts +64 -0
- package/src/domain/Items.ts +32 -4
- package/src/domain/Research.ts +42 -0
- package/src/domain/Turn.ts +26 -0
- package/src/embedding-model/EmbeddingModel.ts +2 -2
- package/src/index.ts +4 -0
- package/src/job/Job.ts +125 -0
- package/src/language-model/LanguageModel.ts +2 -2
- package/src/music-generator/MusicGenerator.ts +4 -4
- package/src/observability/Metrics.test.ts +65 -0
- package/src/observability/Metrics.ts +53 -11
- package/src/research/DeepResearch.ts +137 -0
- package/src/retry/Retry.ts +44 -3
- package/src/sandbox/Sandbox.ts +18 -18
- package/src/speech-synthesizer/SpeechSynthesizer.ts +8 -8
- package/src/streaming/JSONL.test.ts +19 -0
- package/src/streaming/JSONL.ts +6 -38
- package/src/streaming/SSE.test.ts +86 -3
- package/src/streaming/SSE.ts +36 -80
- package/src/tool/Tool.test.ts +151 -1
- package/src/tool/Tool.ts +120 -22
- package/src/tool/Toolkit.test.ts +60 -0
- package/src/tool/Toolkit.ts +2 -2
- package/src/transcriber/Transcriber.ts +3 -3
- package/src/web-read/WebRead.ts +1 -1
- package/src/web-search/WebSearch.ts +1 -1
- package/dist/Items-BnIduEV2.d.mts.map +0 -1
- package/dist/Tool-2lC_XMth.d.mts.map +0 -1
- package/dist/Toolkit-Dr9l_hNy.d.mts.map +0 -1
- package/dist/dist-DWgRbDN3.mjs.map +0 -1
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { DateTime } from "effect";
|
|
2
|
+
|
|
3
|
+
//#region src/domain/Citation.d.ts
|
|
4
|
+
declare namespace Citation_d_exports {
|
|
5
|
+
export { CitationSpan, Citations, Source };
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* A document the model consulted. `url` and `title` are the only
|
|
9
|
+
* near-universal fields; the rest is best-effort. `raw` round-trips
|
|
10
|
+
* provider-opaque tokens (encrypted indices, chunk handles, document ids) so
|
|
11
|
+
* nothing is lost.
|
|
12
|
+
*/
|
|
13
|
+
type Source = {
|
|
14
|
+
readonly url: string;
|
|
15
|
+
readonly title?: string;
|
|
16
|
+
readonly snippet?: string;
|
|
17
|
+
readonly publishedDate?: DateTime.DateTime;
|
|
18
|
+
readonly sourceType?: "web" | "x" | "news" | "file" | "document" | (string & {});
|
|
19
|
+
readonly raw?: unknown;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Where in the answer a claim is grounded, and which sources ground it.
|
|
23
|
+
* `sourceRefs` indexes into the sibling {@link Citations.sources} array
|
|
24
|
+
* (many-to-one). The four kinds normalize how providers link answer text to
|
|
25
|
+
* sources: a character / byte offset range, an exact source quote, a
|
|
26
|
+
* positional `[n]` marker, or `none` for a bare source with no anchor.
|
|
27
|
+
*/
|
|
28
|
+
type CitationSpan = {
|
|
29
|
+
readonly kind: "char";
|
|
30
|
+
readonly start: number;
|
|
31
|
+
readonly end: number;
|
|
32
|
+
readonly unit: "char" | "byte";
|
|
33
|
+
readonly sourceRefs: ReadonlyArray<number>;
|
|
34
|
+
readonly confidence?: number;
|
|
35
|
+
} | {
|
|
36
|
+
readonly kind: "quote";
|
|
37
|
+
readonly text: string;
|
|
38
|
+
readonly sourceRefs: ReadonlyArray<number>;
|
|
39
|
+
} | {
|
|
40
|
+
readonly kind: "marker";
|
|
41
|
+
readonly ordinal: number;
|
|
42
|
+
readonly sourceRefs: ReadonlyArray<number>;
|
|
43
|
+
} | {
|
|
44
|
+
readonly kind: "none";
|
|
45
|
+
readonly sourceRefs: ReadonlyArray<number>;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* The grounding for a piece of generated text: the sources consulted, and the
|
|
49
|
+
* spans that reference them. This is the canonical, provider-agnostic form.
|
|
50
|
+
* The flat `Items.Annotation` array is its degenerate view (one `char` span
|
|
51
|
+
* with one inlined source), used where a wire-attached, per-`output_text`
|
|
52
|
+
* shape is enough.
|
|
53
|
+
*/
|
|
54
|
+
type Citations = {
|
|
55
|
+
readonly sources: ReadonlyArray<Source>;
|
|
56
|
+
readonly spans: ReadonlyArray<CitationSpan>;
|
|
57
|
+
};
|
|
58
|
+
//#endregion
|
|
59
|
+
export { CitationSpan, Citations, Source, Citation_d_exports as t };
|
|
60
|
+
//# sourceMappingURL=Citation.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Citation.d.mts","names":[],"sources":["../../src/domain/Citation.ts"],"mappings":";;;;;;;;;;;;KAYY,MAAA;EAAA,SACD,GAAA;EAAA,SACA,KAAA;EAAA,SACA,OAAA;EAAA,SACA,aAAA,GAAgB,QAAA,CAAS,QAAA;EAAA,SACzB,UAAA;EAAA,SACA,GAAA;AAAA;;;;;;;;KAcC,YAAA;EAAA,SAEG,IAAA;EAAA,SACA,KAAA;EAAA,SACA,GAAA;EAAA,SACA,IAAA;EAAA,SACA,UAAA,EAAY,aAAA;EAAA,SACZ,UAAA;AAAA;EAAA,SAEA,IAAA;EAAA,SAAwB,IAAA;EAAA,SAAuB,UAAA,EAAY,aAAA;AAAA;EAAA,SAE3D,IAAA;EAAA,SACA,OAAA;EAAA,SACA,UAAA,EAAY,aAAA;AAAA;EAAA,SAEZ,IAAA;EAAA,SAAuB,UAAA,EAAY,aAAA;AAAA;;;;;;;;KAatC,SAAA;EAAA,SACD,OAAA,EAAS,aAAA,CAAc,MAAA;EAAA,SACvB,KAAA,EAAO,aAAA,CAAc,YAAA;AAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Citation.mjs","names":[],"sources":["../../src/domain/Citation.ts"],"sourcesContent":["import type { DateTime } from \"effect\"\n\n// ---------------------------------------------------------------------------\n// Source\n// ---------------------------------------------------------------------------\n\n/**\n * A document the model consulted. `url` and `title` are the only\n * near-universal fields; the rest is best-effort. `raw` round-trips\n * provider-opaque tokens (encrypted indices, chunk handles, document ids) so\n * nothing is lost.\n */\nexport type Source = {\n readonly url: string\n readonly title?: string\n readonly snippet?: string\n readonly publishedDate?: DateTime.DateTime\n readonly sourceType?: \"web\" | \"x\" | \"news\" | \"file\" | \"document\" | (string & {})\n readonly raw?: unknown\n}\n\n// ---------------------------------------------------------------------------\n// Span\n// ---------------------------------------------------------------------------\n\n/**\n * Where in the answer a claim is grounded, and which sources ground it.\n * `sourceRefs` indexes into the sibling {@link Citations.sources} array\n * (many-to-one). The four kinds normalize how providers link answer text to\n * sources: a character / byte offset range, an exact source quote, a\n * positional `[n]` marker, or `none` for a bare source with no anchor.\n */\nexport type CitationSpan =\n | {\n readonly kind: \"char\"\n readonly start: number\n readonly end: number\n readonly unit: \"char\" | \"byte\"\n readonly sourceRefs: ReadonlyArray<number>\n readonly confidence?: number\n }\n | { readonly kind: \"quote\"; readonly text: string; readonly sourceRefs: ReadonlyArray<number> }\n | {\n readonly kind: \"marker\"\n readonly ordinal: number\n readonly sourceRefs: ReadonlyArray<number>\n }\n | { readonly kind: \"none\"; readonly sourceRefs: ReadonlyArray<number> }\n\n// ---------------------------------------------------------------------------\n// Citations\n// ---------------------------------------------------------------------------\n\n/**\n * The grounding for a piece of generated text: the sources consulted, and the\n * spans that reference them. This is the canonical, provider-agnostic form.\n * The flat `Items.Annotation` array is its degenerate view (one `char` span\n * with one inlined source), used where a wire-attached, per-`output_text`\n * shape is enough.\n */\nexport type Citations = {\n readonly sources: ReadonlyArray<Source>\n readonly spans: ReadonlyArray<CitationSpan>\n}\n"],"mappings":""}
|
package/dist/domain/Image.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as ImageUrlSource, c as imageBytes, d as isImageBytes, f as isImageUrl, i as ImageSource, l as imageUrl, n as ImageBytesSource, r as ImageMimeType, s as imageBase64, t as ImageBase64Source, u as isImageBase64 } from "../Image-
|
|
1
|
+
import { a as ImageUrlSource, c as imageBytes, d as isImageBytes, f as isImageUrl, i as ImageSource, l as imageUrl, n as ImageBytesSource, r as ImageMimeType, s as imageBase64, t as ImageBase64Source, u as isImageBase64 } from "../Image-C4vuBmu0.mjs";
|
|
2
2
|
export { ImageBase64Source, ImageBytesSource, ImageMimeType, ImageSource, ImageUrlSource, imageBase64, imageBytes, imageUrl, isImageBase64, isImageBytes, isImageUrl };
|
package/dist/domain/Items.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as isReasoning, C as isContainerFileCitation, D as isInputText, E as isInputImage, F as systemText, I as toolCallOutput, L as userText, M as isToolCall, N as isToolCallOutput, O as isMessage, P as isUrlCitation, S as assistantText, T as isFilePath, _ as StopReason, a as FilePath, b as UrlCitation, c as InputText, d as Message, f as OutputText, g as Role, h as Refusal, i as FileCitation, j as isRefusal, k as isOutputText, l as InputTokensDetails, m as Reasoning, n as ContainerFileCitation, o as HistoryItem, p as OutputTokensDetails, r as ContentBlock, s as InputImage, t as Annotation, v as ToolCall, w as isFileCitation, x as Usage, y as ToolCallOutput } from "../Items-
|
|
1
|
+
import { A as isReasoning, C as isContainerFileCitation, D as isInputText, E as isInputImage, F as systemText, I as toolCallOutput, L as userText, M as isToolCall, N as isToolCallOutput, O as isMessage, P as isUrlCitation, S as assistantText, T as isFilePath, _ as StopReason, a as FilePath, b as UrlCitation, c as InputText, d as Message, f as OutputText, g as Role, h as Refusal, i as FileCitation, j as isRefusal, k as isOutputText, l as InputTokensDetails, m as Reasoning, n as ContainerFileCitation, o as HistoryItem, p as OutputTokensDetails, r as ContentBlock, s as InputImage, t as Annotation, v as ToolCall, w as isFileCitation, x as Usage, y as ToolCallOutput } from "../Items-BKQgqJ8A.mjs";
|
|
2
2
|
export { Annotation, ContainerFileCitation, ContentBlock, FileCitation, FilePath, HistoryItem, InputImage, InputText, InputTokensDetails, Message, OutputText, OutputTokensDetails, Reasoning, Refusal, Role, StopReason, ToolCall, ToolCallOutput, UrlCitation, Usage, assistantText, isContainerFileCitation, isFileCitation, isFilePath, isInputImage, isInputText, isMessage, isOutputText, isReasoning, isRefusal, isToolCall, isToolCallOutput, isUrlCitation, systemText, toolCallOutput, userText };
|
package/dist/domain/Items.mjs
CHANGED
|
@@ -56,12 +56,22 @@ const InputImage = Schema.Struct({
|
|
|
56
56
|
type: Schema.Literal("input_image"),
|
|
57
57
|
source: ImageSource
|
|
58
58
|
});
|
|
59
|
+
/**
|
|
60
|
+
* A cited source. `url` + `title` are the only near-universal fields; the
|
|
61
|
+
* link from a source to the answer text varies by provider, so it is optional
|
|
62
|
+
* and expressed three ways: `start_index`/`end_index` (a character span into
|
|
63
|
+
* the answer), `cited_text` (an exact quote of the source, when no offsets are
|
|
64
|
+
* given), or `marker` (a positional `[n]` reference into an ordered list). A
|
|
65
|
+
* provider populates whichever it has; a bare source list sets none.
|
|
66
|
+
*/
|
|
59
67
|
const UrlCitation = Schema.Struct({
|
|
60
68
|
type: Schema.Literal("url_citation"),
|
|
61
69
|
url: Schema.String,
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
70
|
+
title: Schema.String,
|
|
71
|
+
start_index: Schema.optional(Schema.Number),
|
|
72
|
+
end_index: Schema.optional(Schema.Number),
|
|
73
|
+
cited_text: Schema.optional(Schema.String),
|
|
74
|
+
marker: Schema.optional(Schema.Number)
|
|
65
75
|
});
|
|
66
76
|
const FileCitation = Schema.Struct({
|
|
67
77
|
type: Schema.Literal("file_citation"),
|
|
@@ -163,7 +173,21 @@ const isMessage = Schema.is(Message);
|
|
|
163
173
|
const isToolCall = Schema.is(ToolCall);
|
|
164
174
|
const isToolCallOutput = Schema.is(ToolCallOutput);
|
|
165
175
|
const isReasoning = Schema.is(Reasoning);
|
|
166
|
-
|
|
176
|
+
/**
|
|
177
|
+
* Prompt-cache token breakdown. `cached_tokens` is cache reads;
|
|
178
|
+
* `cache_write_tokens` is tokens written to the cache this turn (billed at a
|
|
179
|
+
* premium). Field names mirror the OpenAI Responses usage shape.
|
|
180
|
+
*
|
|
181
|
+
* Whether these are a subset of `input_tokens` or a separate bucket is
|
|
182
|
+
* provider-specific: OpenAI counts cache reads inside `input_tokens`, while
|
|
183
|
+
* Anthropic reports `input_tokens` as post-breakpoint tokens only, with reads
|
|
184
|
+
* and writes as separate additive buckets. Read a provider's usage in its own
|
|
185
|
+
* terms; do not assume one relationship holds everywhere.
|
|
186
|
+
*/
|
|
187
|
+
const InputTokensDetails = Schema.Struct({
|
|
188
|
+
cached_tokens: Schema.optional(Schema.Number),
|
|
189
|
+
cache_write_tokens: Schema.optional(Schema.Number)
|
|
190
|
+
});
|
|
167
191
|
const OutputTokensDetails = Schema.Struct({ reasoning_tokens: Schema.optional(Schema.Number) });
|
|
168
192
|
const Usage = Schema.Struct({
|
|
169
193
|
input_tokens: Schema.optional(Schema.Number),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Items.mjs","names":[],"sources":["../../src/domain/Items.ts"],"sourcesContent":["import { Schema } from \"effect\"\nimport { ImageSource } from \"./Image.js\"\n\n// ---------------------------------------------------------------------------\n// Content blocks (inside Message.content)\n// ---------------------------------------------------------------------------\n\nexport const InputText = Schema.Struct({\n type: Schema.Literal(\"input_text\"),\n text: Schema.String,\n})\nexport type InputText = typeof InputText.Type\n\n/**\n * User-provided image content block. Pair with `InputText` inside a\n * `Message.content` array to ask \"what's in this image?\" style questions.\n *\n * `source` is the cross-modality `ImageSource` from `domain/Image.ts` -\n * url, base64, or raw bytes. Provider codecs encode bytes to whatever\n * wire format the provider wants.\n */\nexport const InputImage = Schema.Struct({\n type: Schema.Literal(\"input_image\"),\n source: ImageSource,\n})\nexport type InputImage = typeof InputImage.Type\n\n// ---------------------------------------------------------------------------\n// Annotations - source / citation pointers attached to `output_text` blocks.\n// Mirrors OpenAI Responses API; other providers can omit or map onto these\n// shapes.\n// ---------------------------------------------------------------------------\n\nexport const UrlCitation = Schema.Struct({\n type: Schema.Literal(\"url_citation\"),\n url: Schema.String,\n start_index: Schema.Number,\n end_index: Schema.Number,\n title: Schema.String,\n})\nexport type UrlCitation = typeof UrlCitation.Type\n\nexport const FileCitation = Schema.Struct({\n type: Schema.Literal(\"file_citation\"),\n file_id: Schema.String,\n index: Schema.Number,\n})\nexport type FileCitation = typeof FileCitation.Type\n\nexport const ContainerFileCitation = Schema.Struct({\n type: Schema.Literal(\"container_file_citation\"),\n container_id: Schema.String,\n file_id: Schema.String,\n start_index: Schema.Number,\n end_index: Schema.Number,\n})\nexport type ContainerFileCitation = typeof ContainerFileCitation.Type\n\nexport const FilePath = Schema.Struct({\n type: Schema.Literal(\"file_path\"),\n file_id: Schema.String,\n index: Schema.Number,\n})\nexport type FilePath = typeof FilePath.Type\n\nexport const Annotation = Schema.Union([UrlCitation, FileCitation, ContainerFileCitation, FilePath])\nexport type Annotation = typeof Annotation.Type\n\nexport const isUrlCitation = Schema.is(UrlCitation)\nexport const isFileCitation = Schema.is(FileCitation)\nexport const isContainerFileCitation = Schema.is(ContainerFileCitation)\nexport const isFilePath = Schema.is(FilePath)\n\nexport const OutputText = Schema.Struct({\n type: Schema.Literal(\"output_text\"),\n text: Schema.String,\n annotations: Schema.optional(Schema.Array(Annotation)),\n})\nexport type OutputText = typeof OutputText.Type\n\n/**\n * Model-emitted refusal. Distinct from `output_text`: the model declined\n * to answer rather than producing normal output. Pair with\n * `stop_reason: \"refusal\"` on the surrounding `Turn`. Streamed via the\n * `RefusalDelta` `TurnEvent`.\n */\nexport const Refusal = Schema.Struct({\n type: Schema.Literal(\"refusal\"),\n text: Schema.String,\n})\nexport type Refusal = typeof Refusal.Type\n\nexport const ContentBlock = Schema.Union([InputText, InputImage, OutputText, Refusal])\nexport type ContentBlock = typeof ContentBlock.Type\n\nexport const Role = Schema.Literals([\"user\", \"assistant\", \"system\"])\nexport type Role = typeof Role.Type\n\n// ---------------------------------------------------------------------------\n// Provider passthrough - every Item type carries this opaque slot.\n// The framework never reads or interprets it; provider modules decode\n// their own data via their own typed readers (see e.g.\n// the `@effect-uai/responses` package).\n// ---------------------------------------------------------------------------\n\nconst ProviderData = Schema.optional(Schema.Unknown)\n\n// ---------------------------------------------------------------------------\n// Items\n// ---------------------------------------------------------------------------\n\nexport const Message = Schema.Struct({\n type: Schema.Literal(\"message\"),\n role: Role,\n content: Schema.Array(ContentBlock),\n providerData: ProviderData,\n})\nexport type Message = typeof Message.Type\n\nexport const ToolCall = Schema.Struct({\n type: Schema.Literal(\"function_call\"),\n call_id: Schema.String,\n name: Schema.String,\n // JSON-encoded arguments string, mirroring OpenAI Responses API\n arguments: Schema.String,\n providerData: ProviderData,\n})\nexport type ToolCall = typeof ToolCall.Type\n\nexport const ToolCallOutput = Schema.Struct({\n type: Schema.Literal(\"function_call_output\"),\n call_id: Schema.String,\n output: Schema.String,\n providerData: ProviderData,\n})\nexport type ToolCallOutput = typeof ToolCallOutput.Type\n\n/**\n * Reasoning item - top-level, mirrors OpenAI Responses API. Common shape\n * across providers covers `summary` (human-readable text) and `signature`\n * (opaque round-trip blob - Anthropic's signed thinking, OpenAI's\n * encrypted_content, etc.). Provider-specific fields go in `providerData`.\n */\nexport const Reasoning = Schema.Struct({\n type: Schema.Literal(\"reasoning\"),\n id: Schema.optional(Schema.String),\n summary: Schema.optional(Schema.String),\n signature: Schema.optional(Schema.String),\n providerData: ProviderData,\n})\nexport type Reasoning = typeof Reasoning.Type\n\nexport const HistoryItem = Schema.Union([Message, ToolCall, ToolCallOutput, Reasoning])\nexport type HistoryItem = typeof HistoryItem.Type\n\n// ---------------------------------------------------------------------------\n// Type guards\n// ---------------------------------------------------------------------------\n\nexport const isInputText = Schema.is(InputText)\nexport const isInputImage = Schema.is(InputImage)\nexport const isOutputText = Schema.is(OutputText)\nexport const isRefusal = Schema.is(Refusal)\n\nexport const isMessage = Schema.is(Message)\nexport const isToolCall = Schema.is(ToolCall)\nexport const isToolCallOutput = Schema.is(ToolCallOutput)\nexport const isReasoning = Schema.is(Reasoning)\n\n// ---------------------------------------------------------------------------\n// Usage and stop reason\n// ---------------------------------------------------------------------------\n\nexport const InputTokensDetails = Schema.Struct({\n cached_tokens: Schema.optional(Schema.Number),\n})\nexport type InputTokensDetails = typeof InputTokensDetails.Type\n\nexport const OutputTokensDetails = Schema.Struct({\n reasoning_tokens: Schema.optional(Schema.Number),\n})\nexport type OutputTokensDetails = typeof OutputTokensDetails.Type\n\nexport const Usage = Schema.Struct({\n input_tokens: Schema.optional(Schema.Number),\n output_tokens: Schema.optional(Schema.Number),\n total_tokens: Schema.optional(Schema.Number),\n input_tokens_details: Schema.optional(InputTokensDetails),\n output_tokens_details: Schema.optional(OutputTokensDetails),\n})\nexport type Usage = typeof Usage.Type\n\nexport const StopReason = Schema.Literals([\n \"stop\",\n \"tool_calls\",\n \"max_tokens\",\n \"refusal\",\n /** Provider-side safety classifier flagged the output. */\n \"content_filter\",\n /** Server-enforced cap on tool calls per turn was hit. */\n \"max_tool_calls\",\n])\nexport type StopReason = typeof StopReason.Type\n\n// ---------------------------------------------------------------------------\n// Helper constructors\n// ---------------------------------------------------------------------------\n\nexport const userText = (text: string): Message => ({\n type: \"message\",\n role: \"user\",\n content: [{ type: \"input_text\", text }],\n})\n\nexport const systemText = (text: string): Message => ({\n type: \"message\",\n role: \"system\",\n content: [{ type: \"input_text\", text }],\n})\n\nexport const assistantText = (text: string): Message => ({\n type: \"message\",\n role: \"assistant\",\n content: [{ type: \"output_text\", text }],\n})\n\nexport const toolCallOutput = (call_id: string, output: string): ToolCallOutput => ({\n type: \"function_call_output\",\n call_id,\n output,\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Items.mjs","names":[],"sources":["../../src/domain/Items.ts"],"sourcesContent":["import { Schema } from \"effect\"\nimport { ImageSource } from \"./Image.js\"\n\n// ---------------------------------------------------------------------------\n// Content blocks (inside Message.content)\n// ---------------------------------------------------------------------------\n\nexport const InputText = Schema.Struct({\n type: Schema.Literal(\"input_text\"),\n text: Schema.String,\n})\nexport type InputText = typeof InputText.Type\n\n/**\n * User-provided image content block. Pair with `InputText` inside a\n * `Message.content` array to ask \"what's in this image?\" style questions.\n *\n * `source` is the cross-modality `ImageSource` from `domain/Image.ts` -\n * url, base64, or raw bytes. Provider codecs encode bytes to whatever\n * wire format the provider wants.\n */\nexport const InputImage = Schema.Struct({\n type: Schema.Literal(\"input_image\"),\n source: ImageSource,\n})\nexport type InputImage = typeof InputImage.Type\n\n// ---------------------------------------------------------------------------\n// Annotations - source / citation pointers attached to `output_text` blocks.\n// Provider-agnostic: each provider populates the fields it has (character\n// span, quote, or positional marker) and omits the rest.\n// ---------------------------------------------------------------------------\n\n/**\n * A cited source. `url` + `title` are the only near-universal fields; the\n * link from a source to the answer text varies by provider, so it is optional\n * and expressed three ways: `start_index`/`end_index` (a character span into\n * the answer), `cited_text` (an exact quote of the source, when no offsets are\n * given), or `marker` (a positional `[n]` reference into an ordered list). A\n * provider populates whichever it has; a bare source list sets none.\n */\nexport const UrlCitation = Schema.Struct({\n type: Schema.Literal(\"url_citation\"),\n url: Schema.String,\n title: Schema.String,\n start_index: Schema.optional(Schema.Number),\n end_index: Schema.optional(Schema.Number),\n cited_text: Schema.optional(Schema.String),\n marker: Schema.optional(Schema.Number),\n})\nexport type UrlCitation = typeof UrlCitation.Type\n\nexport const FileCitation = Schema.Struct({\n type: Schema.Literal(\"file_citation\"),\n file_id: Schema.String,\n index: Schema.Number,\n})\nexport type FileCitation = typeof FileCitation.Type\n\nexport const ContainerFileCitation = Schema.Struct({\n type: Schema.Literal(\"container_file_citation\"),\n container_id: Schema.String,\n file_id: Schema.String,\n start_index: Schema.Number,\n end_index: Schema.Number,\n})\nexport type ContainerFileCitation = typeof ContainerFileCitation.Type\n\nexport const FilePath = Schema.Struct({\n type: Schema.Literal(\"file_path\"),\n file_id: Schema.String,\n index: Schema.Number,\n})\nexport type FilePath = typeof FilePath.Type\n\nexport const Annotation = Schema.Union([UrlCitation, FileCitation, ContainerFileCitation, FilePath])\nexport type Annotation = typeof Annotation.Type\n\nexport const isUrlCitation = Schema.is(UrlCitation)\nexport const isFileCitation = Schema.is(FileCitation)\nexport const isContainerFileCitation = Schema.is(ContainerFileCitation)\nexport const isFilePath = Schema.is(FilePath)\n\nexport const OutputText = Schema.Struct({\n type: Schema.Literal(\"output_text\"),\n text: Schema.String,\n annotations: Schema.optional(Schema.Array(Annotation)),\n})\nexport type OutputText = typeof OutputText.Type\n\n/**\n * Model-emitted refusal. Distinct from `output_text`: the model declined\n * to answer rather than producing normal output. Pair with\n * `stop_reason: \"refusal\"` on the surrounding `Turn`. Streamed via the\n * `RefusalDelta` `TurnEvent`.\n */\nexport const Refusal = Schema.Struct({\n type: Schema.Literal(\"refusal\"),\n text: Schema.String,\n})\nexport type Refusal = typeof Refusal.Type\n\nexport const ContentBlock = Schema.Union([InputText, InputImage, OutputText, Refusal])\nexport type ContentBlock = typeof ContentBlock.Type\n\nexport const Role = Schema.Literals([\"user\", \"assistant\", \"system\"])\nexport type Role = typeof Role.Type\n\n// ---------------------------------------------------------------------------\n// Provider passthrough - every Item type carries this opaque slot.\n// The framework never reads or interprets it; provider modules decode\n// their own data via their own typed readers (see e.g.\n// the `@effect-uai/responses` package).\n//\n// The slot is shared, so a provider keys its data under its own name\n// (`{ responses: ... }`, `{ gemini: ... }`) and reads only that key. One item\n// can pass through several providers - falling back from one to another\n// leaves both keys on it - and a provider that finds no key of its own must\n// encode the item normally rather than assume the slot is its own.\n// ---------------------------------------------------------------------------\n\nconst ProviderData = Schema.optional(Schema.Unknown)\n\n// ---------------------------------------------------------------------------\n// Items\n// ---------------------------------------------------------------------------\n\nexport const Message = Schema.Struct({\n type: Schema.Literal(\"message\"),\n role: Role,\n content: Schema.Array(ContentBlock),\n providerData: ProviderData,\n})\nexport type Message = typeof Message.Type\n\nexport const ToolCall = Schema.Struct({\n type: Schema.Literal(\"function_call\"),\n call_id: Schema.String,\n name: Schema.String,\n // JSON-encoded arguments string, mirroring OpenAI Responses API\n arguments: Schema.String,\n providerData: ProviderData,\n})\nexport type ToolCall = typeof ToolCall.Type\n\nexport const ToolCallOutput = Schema.Struct({\n type: Schema.Literal(\"function_call_output\"),\n call_id: Schema.String,\n output: Schema.String,\n providerData: ProviderData,\n})\nexport type ToolCallOutput = typeof ToolCallOutput.Type\n\n/**\n * Reasoning item - top-level, mirrors OpenAI Responses API. Common shape\n * across providers covers `summary` (human-readable text) and `signature`\n * (opaque round-trip blob - Anthropic's signed thinking, OpenAI's\n * encrypted_content, etc.). Provider-specific fields go in `providerData`.\n */\nexport const Reasoning = Schema.Struct({\n type: Schema.Literal(\"reasoning\"),\n id: Schema.optional(Schema.String),\n summary: Schema.optional(Schema.String),\n signature: Schema.optional(Schema.String),\n providerData: ProviderData,\n})\nexport type Reasoning = typeof Reasoning.Type\n\nexport const HistoryItem = Schema.Union([Message, ToolCall, ToolCallOutput, Reasoning])\nexport type HistoryItem = typeof HistoryItem.Type\n\n// ---------------------------------------------------------------------------\n// Type guards\n// ---------------------------------------------------------------------------\n\nexport const isInputText = Schema.is(InputText)\nexport const isInputImage = Schema.is(InputImage)\nexport const isOutputText = Schema.is(OutputText)\nexport const isRefusal = Schema.is(Refusal)\n\nexport const isMessage = Schema.is(Message)\nexport const isToolCall = Schema.is(ToolCall)\nexport const isToolCallOutput = Schema.is(ToolCallOutput)\nexport const isReasoning = Schema.is(Reasoning)\n\n// ---------------------------------------------------------------------------\n// Usage and stop reason\n// ---------------------------------------------------------------------------\n\n/**\n * Prompt-cache token breakdown. `cached_tokens` is cache reads;\n * `cache_write_tokens` is tokens written to the cache this turn (billed at a\n * premium). Field names mirror the OpenAI Responses usage shape.\n *\n * Whether these are a subset of `input_tokens` or a separate bucket is\n * provider-specific: OpenAI counts cache reads inside `input_tokens`, while\n * Anthropic reports `input_tokens` as post-breakpoint tokens only, with reads\n * and writes as separate additive buckets. Read a provider's usage in its own\n * terms; do not assume one relationship holds everywhere.\n */\nexport const InputTokensDetails = Schema.Struct({\n cached_tokens: Schema.optional(Schema.Number),\n cache_write_tokens: Schema.optional(Schema.Number),\n})\nexport type InputTokensDetails = typeof InputTokensDetails.Type\n\nexport const OutputTokensDetails = Schema.Struct({\n reasoning_tokens: Schema.optional(Schema.Number),\n})\nexport type OutputTokensDetails = typeof OutputTokensDetails.Type\n\nexport const Usage = Schema.Struct({\n input_tokens: Schema.optional(Schema.Number),\n output_tokens: Schema.optional(Schema.Number),\n total_tokens: Schema.optional(Schema.Number),\n input_tokens_details: Schema.optional(InputTokensDetails),\n output_tokens_details: Schema.optional(OutputTokensDetails),\n})\nexport type Usage = typeof Usage.Type\n\nexport const StopReason = Schema.Literals([\n \"stop\",\n \"tool_calls\",\n \"max_tokens\",\n \"refusal\",\n /** Provider-side safety classifier flagged the output. */\n \"content_filter\",\n /** Server-enforced cap on tool calls per turn was hit. */\n \"max_tool_calls\",\n])\nexport type StopReason = typeof StopReason.Type\n\n// ---------------------------------------------------------------------------\n// Helper constructors\n// ---------------------------------------------------------------------------\n\nexport const userText = (text: string): Message => ({\n type: \"message\",\n role: \"user\",\n content: [{ type: \"input_text\", text }],\n})\n\nexport const systemText = (text: string): Message => ({\n type: \"message\",\n role: \"system\",\n content: [{ type: \"input_text\", text }],\n})\n\nexport const assistantText = (text: string): Message => ({\n type: \"message\",\n role: \"assistant\",\n content: [{ type: \"output_text\", text }],\n})\n\nexport const toolCallOutput = (call_id: string, output: string): ToolCallOutput => ({\n type: \"function_call_output\",\n call_id,\n output,\n})\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,MAAa,YAAY,OAAO,OAAO;CACrC,MAAM,OAAO,QAAQ,aAAa;CAClC,MAAM,OAAO;CACd,CAAC;;;;;;;;;AAWF,MAAa,aAAa,OAAO,OAAO;CACtC,MAAM,OAAO,QAAQ,cAAc;CACnC,QAAQ;CACT,CAAC;;;;;;;;;AAiBF,MAAa,cAAc,OAAO,OAAO;CACvC,MAAM,OAAO,QAAQ,eAAe;CACpC,KAAK,OAAO;CACZ,OAAO,OAAO;CACd,aAAa,OAAO,SAAS,OAAO,OAAO;CAC3C,WAAW,OAAO,SAAS,OAAO,OAAO;CACzC,YAAY,OAAO,SAAS,OAAO,OAAO;CAC1C,QAAQ,OAAO,SAAS,OAAO,OAAO;CACvC,CAAC;AAGF,MAAa,eAAe,OAAO,OAAO;CACxC,MAAM,OAAO,QAAQ,gBAAgB;CACrC,SAAS,OAAO;CAChB,OAAO,OAAO;CACf,CAAC;AAGF,MAAa,wBAAwB,OAAO,OAAO;CACjD,MAAM,OAAO,QAAQ,0BAA0B;CAC/C,cAAc,OAAO;CACrB,SAAS,OAAO;CAChB,aAAa,OAAO;CACpB,WAAW,OAAO;CACnB,CAAC;AAGF,MAAa,WAAW,OAAO,OAAO;CACpC,MAAM,OAAO,QAAQ,YAAY;CACjC,SAAS,OAAO;CAChB,OAAO,OAAO;CACf,CAAC;AAGF,MAAa,aAAa,OAAO,MAAM;CAAC;CAAa;CAAc;CAAuB;CAAS,CAAC;AAGpG,MAAa,gBAAgB,OAAO,GAAG,YAAY;AACnD,MAAa,iBAAiB,OAAO,GAAG,aAAa;AACrD,MAAa,0BAA0B,OAAO,GAAG,sBAAsB;AACvE,MAAa,aAAa,OAAO,GAAG,SAAS;AAE7C,MAAa,aAAa,OAAO,OAAO;CACtC,MAAM,OAAO,QAAQ,cAAc;CACnC,MAAM,OAAO;CACb,aAAa,OAAO,SAAS,OAAO,MAAM,WAAW,CAAC;CACvD,CAAC;;;;;;;AASF,MAAa,UAAU,OAAO,OAAO;CACnC,MAAM,OAAO,QAAQ,UAAU;CAC/B,MAAM,OAAO;CACd,CAAC;AAGF,MAAa,eAAe,OAAO,MAAM;CAAC;CAAW;CAAY;CAAY;CAAQ,CAAC;AAGtF,MAAa,OAAO,OAAO,SAAS;CAAC;CAAQ;CAAa;CAAS,CAAC;AAgBpE,MAAM,eAAe,OAAO,SAAS,OAAO,QAAQ;AAMpD,MAAa,UAAU,OAAO,OAAO;CACnC,MAAM,OAAO,QAAQ,UAAU;CAC/B,MAAM;CACN,SAAS,OAAO,MAAM,aAAa;CACnC,cAAc;CACf,CAAC;AAGF,MAAa,WAAW,OAAO,OAAO;CACpC,MAAM,OAAO,QAAQ,gBAAgB;CACrC,SAAS,OAAO;CAChB,MAAM,OAAO;CAEb,WAAW,OAAO;CAClB,cAAc;CACf,CAAC;AAGF,MAAa,iBAAiB,OAAO,OAAO;CAC1C,MAAM,OAAO,QAAQ,uBAAuB;CAC5C,SAAS,OAAO;CAChB,QAAQ,OAAO;CACf,cAAc;CACf,CAAC;;;;;;;AASF,MAAa,YAAY,OAAO,OAAO;CACrC,MAAM,OAAO,QAAQ,YAAY;CACjC,IAAI,OAAO,SAAS,OAAO,OAAO;CAClC,SAAS,OAAO,SAAS,OAAO,OAAO;CACvC,WAAW,OAAO,SAAS,OAAO,OAAO;CACzC,cAAc;CACf,CAAC;AAGF,MAAa,cAAc,OAAO,MAAM;CAAC;CAAS;CAAU;CAAgB;CAAU,CAAC;AAOvF,MAAa,cAAc,OAAO,GAAG,UAAU;AAC/C,MAAa,eAAe,OAAO,GAAG,WAAW;AACjD,MAAa,eAAe,OAAO,GAAG,WAAW;AACjD,MAAa,YAAY,OAAO,GAAG,QAAQ;AAE3C,MAAa,YAAY,OAAO,GAAG,QAAQ;AAC3C,MAAa,aAAa,OAAO,GAAG,SAAS;AAC7C,MAAa,mBAAmB,OAAO,GAAG,eAAe;AACzD,MAAa,cAAc,OAAO,GAAG,UAAU;;;;;;;;;;;;AAiB/C,MAAa,qBAAqB,OAAO,OAAO;CAC9C,eAAe,OAAO,SAAS,OAAO,OAAO;CAC7C,oBAAoB,OAAO,SAAS,OAAO,OAAO;CACnD,CAAC;AAGF,MAAa,sBAAsB,OAAO,OAAO,EAC/C,kBAAkB,OAAO,SAAS,OAAO,OAAO,EACjD,CAAC;AAGF,MAAa,QAAQ,OAAO,OAAO;CACjC,cAAc,OAAO,SAAS,OAAO,OAAO;CAC5C,eAAe,OAAO,SAAS,OAAO,OAAO;CAC7C,cAAc,OAAO,SAAS,OAAO,OAAO;CAC5C,sBAAsB,OAAO,SAAS,mBAAmB;CACzD,uBAAuB,OAAO,SAAS,oBAAoB;CAC5D,CAAC;AAGF,MAAa,aAAa,OAAO,SAAS;CACxC;CACA;CACA;CACA;CAEA;CAEA;CACD,CAAC;AAOF,MAAa,YAAY,UAA2B;CAClD,MAAM;CACN,MAAM;CACN,SAAS,CAAC;EAAE,MAAM;EAAc;EAAM,CAAC;CACxC;AAED,MAAa,cAAc,UAA2B;CACpD,MAAM;CACN,MAAM;CACN,SAAS,CAAC;EAAE,MAAM;EAAc;EAAM,CAAC;CACxC;AAED,MAAa,iBAAiB,UAA2B;CACvD,MAAM;CACN,MAAM;CACN,SAAS,CAAC;EAAE,MAAM;EAAe;EAAM,CAAC;CACzC;AAED,MAAa,kBAAkB,SAAiB,YAAoC;CAClF,MAAM;CACN;CACA;CACD"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { o as HistoryItem } from "../Items-BKQgqJ8A.mjs";
|
|
2
|
+
import { JobRef, JobState } from "../job/Job.mjs";
|
|
3
|
+
import { Turn } from "./Turn.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/domain/Research.d.ts
|
|
6
|
+
declare namespace Research_d_exports {
|
|
7
|
+
export { ResearchJobRef, ResearchRequest, ResearchState };
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Cross-provider deep-research request: a question in, a cited report out.
|
|
11
|
+
* Deliberately minimal, only the input every provider shares. Depth, search
|
|
12
|
+
* caps, and structured-output knobs vary too much to unify, so they live on
|
|
13
|
+
* each provider's typed request, which extends this and narrows `model`.
|
|
14
|
+
*
|
|
15
|
+
* `history` reuses the `LanguageModel` input primitive: the common case is a
|
|
16
|
+
* single user message with the question. There is no history threading. A
|
|
17
|
+
* research call is one background job, not a conversation, but the input
|
|
18
|
+
* encoding is shared.
|
|
19
|
+
*/
|
|
20
|
+
type ResearchRequest = {
|
|
21
|
+
readonly history: ReadonlyArray<HistoryItem>; /** Model / agent id. Provider default if omitted; each provider narrows. */
|
|
22
|
+
readonly model?: string;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* A completed research result is a `Turn`: one assistant message with the
|
|
26
|
+
* report text and its citations on `OutputText.annotations`, plus usage.
|
|
27
|
+
* Project it with `Turn.assistantText` / `Turn.citations` /
|
|
28
|
+
* `Turn.decodeStructured`. There is no bespoke report type; the streaming
|
|
29
|
+
* terminal (`TurnComplete.turn`) and the collected result are the same shape.
|
|
30
|
+
*/
|
|
31
|
+
/** Provider-tagged handle to a running research job, branded to `Turn`. */
|
|
32
|
+
type ResearchJobRef = JobRef<Turn>;
|
|
33
|
+
/** Current state of a research job. See {@link Job.JobState}. */
|
|
34
|
+
type ResearchState = JobState<Turn>;
|
|
35
|
+
//#endregion
|
|
36
|
+
export { ResearchJobRef, ResearchRequest, ResearchState, Research_d_exports as t };
|
|
37
|
+
//# sourceMappingURL=Research.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Research.d.mts","names":[],"sources":["../../src/domain/Research.ts"],"mappings":";;;;;;;;;;;;;;;;AAmBA;;;KAAY,eAAA;EAAA,SACD,OAAA,EAAS,aAAA,CAAc,WAAA,GAAd;EAAA,SAET,KAAA;AAAA;;;;AAgBX;;;;;KAAY,cAAA,GAAiB,MAAA,CAAW,IAAA;;KAG5B,aAAA,GAAgB,QAAA,CAAa,IAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Research.mjs","names":[],"sources":["../../src/domain/Research.ts"],"sourcesContent":["import type * as Job from \"../job/Job.js\"\nimport type * as Items from \"./Items.js\"\nimport type { Turn } from \"./Turn.js\"\n\n// ---------------------------------------------------------------------------\n// Request\n// ---------------------------------------------------------------------------\n\n/**\n * Cross-provider deep-research request: a question in, a cited report out.\n * Deliberately minimal, only the input every provider shares. Depth, search\n * caps, and structured-output knobs vary too much to unify, so they live on\n * each provider's typed request, which extends this and narrows `model`.\n *\n * `history` reuses the `LanguageModel` input primitive: the common case is a\n * single user message with the question. There is no history threading. A\n * research call is one background job, not a conversation, but the input\n * encoding is shared.\n */\nexport type ResearchRequest = {\n readonly history: ReadonlyArray<Items.HistoryItem>\n /** Model / agent id. Provider default if omitted; each provider narrows. */\n readonly model?: string\n}\n\n// ---------------------------------------------------------------------------\n// Result + job handle\n// ---------------------------------------------------------------------------\n\n/**\n * A completed research result is a `Turn`: one assistant message with the\n * report text and its citations on `OutputText.annotations`, plus usage.\n * Project it with `Turn.assistantText` / `Turn.citations` /\n * `Turn.decodeStructured`. There is no bespoke report type; the streaming\n * terminal (`TurnComplete.turn`) and the collected result are the same shape.\n */\n\n/** Provider-tagged handle to a running research job, branded to `Turn`. */\nexport type ResearchJobRef = Job.JobRef<Turn>\n\n/** Current state of a research job. See {@link Job.JobState}. */\nexport type ResearchState = Job.JobState<Turn>\n"],"mappings":""}
|
package/dist/domain/Turn.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as ImageSource } from "../Image-
|
|
2
|
-
import { d as Message, m as Reasoning, o as HistoryItem, v as ToolCall, x as Usage, y as ToolCallOutput } from "../Items-
|
|
1
|
+
import { i as ImageSource } from "../Image-C4vuBmu0.mjs";
|
|
2
|
+
import { d as Message, m as Reasoning, o as HistoryItem, t as Annotation, v as ToolCall, x as Usage, y as ToolCallOutput } from "../Items-BKQgqJ8A.mjs";
|
|
3
3
|
import { i as StructuredFormat, n as JsonParseError, r as StructuredDecodeError } from "../StructuredFormat-DHaUJBdd.mjs";
|
|
4
4
|
import { Data, Effect, Schema, Stream } from "effect";
|
|
5
5
|
import * as _$effect_Cause0 from "effect/Cause";
|
|
@@ -8,7 +8,7 @@ import * as _$effect_Unify0 from "effect/Unify";
|
|
|
8
8
|
|
|
9
9
|
//#region src/domain/Turn.d.ts
|
|
10
10
|
declare namespace Turn_d_exports {
|
|
11
|
-
export { InteractionEvent, RefusalRejected, Turn, TurnEvent, appendToHistory, assistantMessages, assistantText, assistantTexts, decodeStructured, getToolCalls, isTurnComplete, reasonings, textDeltas };
|
|
11
|
+
export { InteractionEvent, RefusalRejected, Turn, TurnEvent, appendToHistory, assistantMessages, assistantText, assistantTexts, citations, decodeStructured, getToolCalls, isTurnComplete, reasonings, textDeltas };
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
14
|
* The result of a single LLM generation. A turn produces zero or more items
|
|
@@ -31,9 +31,11 @@ declare const Turn: Schema.Struct<{
|
|
|
31
31
|
readonly annotations: Schema.optional<Schema.$Array<Schema.Union<readonly [Schema.Struct<{
|
|
32
32
|
readonly type: Schema.Literal<"url_citation">;
|
|
33
33
|
readonly url: Schema.String;
|
|
34
|
-
readonly start_index: Schema.Number;
|
|
35
|
-
readonly end_index: Schema.Number;
|
|
36
34
|
readonly title: Schema.String;
|
|
35
|
+
readonly start_index: Schema.optional<Schema.Number>;
|
|
36
|
+
readonly end_index: Schema.optional<Schema.Number>;
|
|
37
|
+
readonly cited_text: Schema.optional<Schema.String>;
|
|
38
|
+
readonly marker: Schema.optional<Schema.Number>;
|
|
37
39
|
}>, Schema.Struct<{
|
|
38
40
|
readonly type: Schema.Literal<"file_citation">;
|
|
39
41
|
readonly file_id: Schema.String;
|
|
@@ -78,6 +80,7 @@ declare const Turn: Schema.Struct<{
|
|
|
78
80
|
readonly total_tokens: Schema.optional<Schema.Number>;
|
|
79
81
|
readonly input_tokens_details: Schema.optional<Schema.Struct<{
|
|
80
82
|
readonly cached_tokens: Schema.optional<Schema.Number>;
|
|
83
|
+
readonly cache_write_tokens: Schema.optional<Schema.Number>;
|
|
81
84
|
}>>;
|
|
82
85
|
readonly output_tokens_details: Schema.optional<Schema.Struct<{
|
|
83
86
|
readonly reasoning_tokens: Schema.optional<Schema.Number>;
|
|
@@ -104,6 +107,14 @@ type Turn = typeof Turn.Type;
|
|
|
104
107
|
* `UsageUpdate`: mid-stream cumulative usage. Anthropic emits this on
|
|
105
108
|
* `message_start` and `message_delta`; other providers may only deliver
|
|
106
109
|
* usage via `TurnComplete.turn.usage`.
|
|
110
|
+
*
|
|
111
|
+
* `WebSearchCall`: lifecycle of a provider-executed web search within the
|
|
112
|
+
* turn. Fires only when the turn grounds against search; absent otherwise.
|
|
113
|
+
*
|
|
114
|
+
* `CitationAdded`: a citation attached to the answer, emitted incrementally
|
|
115
|
+
* where the provider streams citations. Providers that bundle citations emit
|
|
116
|
+
* none of these; their citations still arrive on `TurnComplete.turn`
|
|
117
|
+
* (`OutputText.annotations`). Either way the final set is on the assembled turn.
|
|
107
118
|
*/
|
|
108
119
|
type TurnEvent = Data.TaggedEnum<{
|
|
109
120
|
TextDelta: {
|
|
@@ -127,6 +138,14 @@ type TurnEvent = Data.TaggedEnum<{
|
|
|
127
138
|
UsageUpdate: {
|
|
128
139
|
readonly usage: Usage;
|
|
129
140
|
};
|
|
141
|
+
WebSearchCall: {
|
|
142
|
+
readonly status: "started" | "searching" | "completed";
|
|
143
|
+
readonly query?: string;
|
|
144
|
+
readonly action?: "search" | "open_page" | "find_in_page";
|
|
145
|
+
};
|
|
146
|
+
CitationAdded: {
|
|
147
|
+
readonly annotation: Annotation;
|
|
148
|
+
};
|
|
130
149
|
TurnComplete: {
|
|
131
150
|
readonly turn: Turn;
|
|
132
151
|
};
|
|
@@ -159,11 +178,21 @@ declare const TurnEvent: {
|
|
|
159
178
|
readonly _tag: "UsageUpdate";
|
|
160
179
|
readonly usage: Usage;
|
|
161
180
|
}, "_tag">;
|
|
181
|
+
readonly WebSearchCall: Data.TaggedEnum.ConstructorFrom<{
|
|
182
|
+
readonly _tag: "WebSearchCall";
|
|
183
|
+
readonly status: "started" | "searching" | "completed";
|
|
184
|
+
readonly query?: string;
|
|
185
|
+
readonly action?: "search" | "open_page" | "find_in_page";
|
|
186
|
+
}, "_tag">;
|
|
187
|
+
readonly CitationAdded: Data.TaggedEnum.ConstructorFrom<{
|
|
188
|
+
readonly _tag: "CitationAdded";
|
|
189
|
+
readonly annotation: Annotation;
|
|
190
|
+
}, "_tag">;
|
|
162
191
|
readonly TurnComplete: Data.TaggedEnum.ConstructorFrom<{
|
|
163
192
|
readonly _tag: "TurnComplete";
|
|
164
193
|
readonly turn: Turn;
|
|
165
194
|
}, "_tag">;
|
|
166
|
-
readonly $is: <Tag extends "TextDelta" | "ReasoningDelta" | "RefusalDelta" | "ToolCallStart" | "ToolCallArgsDelta" | "UsageUpdate" | "TurnComplete">(tag: Tag) => (u: unknown) => u is Extract<{
|
|
195
|
+
readonly $is: <Tag extends "TextDelta" | "ReasoningDelta" | "RefusalDelta" | "ToolCallStart" | "ToolCallArgsDelta" | "UsageUpdate" | "WebSearchCall" | "CitationAdded" | "TurnComplete">(tag: Tag) => (u: unknown) => u is Extract<{
|
|
167
196
|
readonly _tag: "TextDelta";
|
|
168
197
|
readonly text: string;
|
|
169
198
|
}, {
|
|
@@ -196,6 +225,18 @@ declare const TurnEvent: {
|
|
|
196
225
|
readonly usage: Usage;
|
|
197
226
|
}, {
|
|
198
227
|
readonly _tag: Tag;
|
|
228
|
+
}> | Extract<{
|
|
229
|
+
readonly _tag: "WebSearchCall";
|
|
230
|
+
readonly status: "started" | "searching" | "completed";
|
|
231
|
+
readonly query?: string;
|
|
232
|
+
readonly action?: "search" | "open_page" | "find_in_page";
|
|
233
|
+
}, {
|
|
234
|
+
readonly _tag: Tag;
|
|
235
|
+
}> | Extract<{
|
|
236
|
+
readonly _tag: "CitationAdded";
|
|
237
|
+
readonly annotation: Annotation;
|
|
238
|
+
}, {
|
|
239
|
+
readonly _tag: Tag;
|
|
199
240
|
}> | Extract<{
|
|
200
241
|
readonly _tag: "TurnComplete";
|
|
201
242
|
readonly turn: Turn;
|
|
@@ -231,6 +272,16 @@ declare const TurnEvent: {
|
|
|
231
272
|
readonly _tag: "UsageUpdate";
|
|
232
273
|
readonly usage: Usage;
|
|
233
274
|
}) => any;
|
|
275
|
+
readonly WebSearchCall: (args: {
|
|
276
|
+
readonly _tag: "WebSearchCall";
|
|
277
|
+
readonly status: "started" | "searching" | "completed";
|
|
278
|
+
readonly query?: string;
|
|
279
|
+
readonly action?: "search" | "open_page" | "find_in_page";
|
|
280
|
+
}) => any;
|
|
281
|
+
readonly CitationAdded: (args: {
|
|
282
|
+
readonly _tag: "CitationAdded";
|
|
283
|
+
readonly annotation: Annotation;
|
|
284
|
+
}) => any;
|
|
234
285
|
readonly TurnComplete: (args: {
|
|
235
286
|
readonly _tag: "TurnComplete";
|
|
236
287
|
readonly turn: Turn;
|
|
@@ -256,10 +307,18 @@ declare const TurnEvent: {
|
|
|
256
307
|
} | {
|
|
257
308
|
readonly _tag: "UsageUpdate";
|
|
258
309
|
readonly usage: Usage;
|
|
310
|
+
} | {
|
|
311
|
+
readonly _tag: "WebSearchCall";
|
|
312
|
+
readonly status: "started" | "searching" | "completed";
|
|
313
|
+
readonly query?: string;
|
|
314
|
+
readonly action?: "search" | "open_page" | "find_in_page";
|
|
315
|
+
} | {
|
|
316
|
+
readonly _tag: "CitationAdded";
|
|
317
|
+
readonly annotation: Annotation;
|
|
259
318
|
} | {
|
|
260
319
|
readonly _tag: "TurnComplete";
|
|
261
320
|
readonly turn: Turn;
|
|
262
|
-
}) => _$effect_Unify0.Unify<ReturnType<Cases["TextDelta" | "ReasoningDelta" | "RefusalDelta" | "ToolCallStart" | "ToolCallArgsDelta" | "UsageUpdate" | "TurnComplete"]>>;
|
|
321
|
+
}) => _$effect_Unify0.Unify<ReturnType<Cases["TextDelta" | "ReasoningDelta" | "RefusalDelta" | "ToolCallStart" | "ToolCallArgsDelta" | "UsageUpdate" | "WebSearchCall" | "CitationAdded" | "TurnComplete"]>>;
|
|
263
322
|
<Cases extends {
|
|
264
323
|
readonly TextDelta: (args: {
|
|
265
324
|
readonly _tag: "TextDelta";
|
|
@@ -288,6 +347,16 @@ declare const TurnEvent: {
|
|
|
288
347
|
readonly _tag: "UsageUpdate";
|
|
289
348
|
readonly usage: Usage;
|
|
290
349
|
}) => any;
|
|
350
|
+
readonly WebSearchCall: (args: {
|
|
351
|
+
readonly _tag: "WebSearchCall";
|
|
352
|
+
readonly status: "started" | "searching" | "completed";
|
|
353
|
+
readonly query?: string;
|
|
354
|
+
readonly action?: "search" | "open_page" | "find_in_page";
|
|
355
|
+
}) => any;
|
|
356
|
+
readonly CitationAdded: (args: {
|
|
357
|
+
readonly _tag: "CitationAdded";
|
|
358
|
+
readonly annotation: Annotation;
|
|
359
|
+
}) => any;
|
|
291
360
|
readonly TurnComplete: (args: {
|
|
292
361
|
readonly _tag: "TurnComplete";
|
|
293
362
|
readonly turn: Turn;
|
|
@@ -313,10 +382,18 @@ declare const TurnEvent: {
|
|
|
313
382
|
} | {
|
|
314
383
|
readonly _tag: "UsageUpdate";
|
|
315
384
|
readonly usage: Usage;
|
|
385
|
+
} | {
|
|
386
|
+
readonly _tag: "WebSearchCall";
|
|
387
|
+
readonly status: "started" | "searching" | "completed";
|
|
388
|
+
readonly query?: string;
|
|
389
|
+
readonly action?: "search" | "open_page" | "find_in_page";
|
|
390
|
+
} | {
|
|
391
|
+
readonly _tag: "CitationAdded";
|
|
392
|
+
readonly annotation: Annotation;
|
|
316
393
|
} | {
|
|
317
394
|
readonly _tag: "TurnComplete";
|
|
318
395
|
readonly turn: Turn;
|
|
319
|
-
}, cases: Cases): _$effect_Unify0.Unify<ReturnType<Cases["TextDelta" | "ReasoningDelta" | "RefusalDelta" | "ToolCallStart" | "ToolCallArgsDelta" | "UsageUpdate" | "TurnComplete"]>>;
|
|
396
|
+
}, cases: Cases): _$effect_Unify0.Unify<ReturnType<Cases["TextDelta" | "ReasoningDelta" | "RefusalDelta" | "ToolCallStart" | "ToolCallArgsDelta" | "UsageUpdate" | "WebSearchCall" | "CitationAdded" | "TurnComplete"]>>;
|
|
320
397
|
};
|
|
321
398
|
};
|
|
322
399
|
/**
|
|
@@ -347,6 +424,12 @@ declare const assistantTexts: (turn: Turn) => ReadonlyArray<string>;
|
|
|
347
424
|
* that want one concatenated string.
|
|
348
425
|
*/
|
|
349
426
|
declare const assistantText: (turn: Turn) => string;
|
|
427
|
+
/**
|
|
428
|
+
* Every citation annotation attached to the turn's assistant `output_text`
|
|
429
|
+
* blocks, in order. The flat view of a grounded turn's sources, whether the
|
|
430
|
+
* turn came from a normal generation with native search or a deep-research job.
|
|
431
|
+
*/
|
|
432
|
+
declare const citations: (turn: Turn) => ReadonlyArray<Annotation>;
|
|
350
433
|
/**
|
|
351
434
|
* Append a completed turn and optional follow-up items to a state record's
|
|
352
435
|
* history. Recipes use this at the point where structured tool results are
|
|
@@ -384,5 +467,5 @@ declare class RefusalRejected extends RefusalRejected_base<{
|
|
|
384
467
|
*/
|
|
385
468
|
declare const decodeStructured: <A>(turn: Turn, format: StructuredFormat<A>) => Effect.Effect<A, RefusalRejected | JsonParseError | StructuredDecodeError>;
|
|
386
469
|
//#endregion
|
|
387
|
-
export { InteractionEvent, RefusalRejected, Turn, TurnEvent, appendToHistory, assistantMessages, assistantText, assistantTexts, decodeStructured, getToolCalls, isTurnComplete, reasonings, Turn_d_exports as t, textDeltas };
|
|
470
|
+
export { InteractionEvent, RefusalRejected, Turn, TurnEvent, appendToHistory, assistantMessages, assistantText, assistantTexts, citations, decodeStructured, getToolCalls, isTurnComplete, reasonings, Turn_d_exports as t, textDeltas };
|
|
388
471
|
//# sourceMappingURL=Turn.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Turn.d.mts","names":[],"sources":["../../src/domain/Turn.ts"],"mappings":";;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"Turn.d.mts","names":[],"sources":["../../src/domain/Turn.ts"],"mappings":"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"}
|
package/dist/domain/Turn.mjs
CHANGED
|
@@ -11,6 +11,7 @@ var Turn_exports = /* @__PURE__ */ __exportAll({
|
|
|
11
11
|
assistantMessages: () => assistantMessages,
|
|
12
12
|
assistantText: () => assistantText,
|
|
13
13
|
assistantTexts: () => assistantTexts,
|
|
14
|
+
citations: () => citations,
|
|
14
15
|
decodeStructured: () => decodeStructured,
|
|
15
16
|
getToolCalls: () => getToolCalls,
|
|
16
17
|
isTurnComplete: () => isTurnComplete,
|
|
@@ -47,6 +48,12 @@ const assistantTexts = (turn) => assistantMessages(turn).flatMap((m) => m.conten
|
|
|
47
48
|
*/
|
|
48
49
|
const assistantText = (turn) => assistantTexts(turn).join("");
|
|
49
50
|
/**
|
|
51
|
+
* Every citation annotation attached to the turn's assistant `output_text`
|
|
52
|
+
* blocks, in order. The flat view of a grounded turn's sources, whether the
|
|
53
|
+
* turn came from a normal generation with native search or a deep-research job.
|
|
54
|
+
*/
|
|
55
|
+
const citations = (turn) => assistantMessages(turn).flatMap((m) => m.content).filter(isOutputText).flatMap((b) => b.annotations ?? []);
|
|
56
|
+
/**
|
|
50
57
|
* Append a completed turn and optional follow-up items to a state record's
|
|
51
58
|
* history. Recipes use this at the point where structured tool results are
|
|
52
59
|
* converted to model-facing `ToolCallOutput`s.
|
|
@@ -99,6 +106,6 @@ const lastAssistantContent = (turn) => {
|
|
|
99
106
|
*/
|
|
100
107
|
const decodeStructured = (turn, format) => pipe(lastAssistantContent(turn), ({ text, refused }) => refused ? Effect.fail(new RefusalRejected({ turn })) : parseJson(format)(text));
|
|
101
108
|
//#endregion
|
|
102
|
-
export { RefusalRejected, Turn, TurnEvent, appendToHistory, assistantMessages, assistantText, assistantTexts, decodeStructured, getToolCalls, isTurnComplete, reasonings, Turn_exports as t, textDeltas };
|
|
109
|
+
export { RefusalRejected, Turn, TurnEvent, appendToHistory, assistantMessages, assistantText, assistantTexts, citations, decodeStructured, getToolCalls, isTurnComplete, reasonings, Turn_exports as t, textDeltas };
|
|
103
110
|
|
|
104
111
|
//# sourceMappingURL=Turn.mjs.map
|
package/dist/domain/Turn.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Turn.mjs","names":["StructuredFormat.parseJson"],"sources":["../../src/domain/Turn.ts"],"sourcesContent":["import { Data, Effect, Result, Schema, Stream, pipe } from \"effect\"\nimport * as StructuredFormat from \"../structured-format/StructuredFormat.js\"\nimport {\n HistoryItem,\n Message,\n Reasoning,\n StopReason,\n ToolCall,\n ToolCallOutput,\n Usage,\n isOutputText,\n isReasoning,\n isRefusal,\n isToolCall,\n} from \"./Items.js\"\n\n/**\n * The result of a single LLM generation. A turn produces zero or more items\n * (typically one assistant message and zero or more function_call items)\n * and reports usage + a stop reason.\n */\nexport const Turn = Schema.Struct({\n items: Schema.Array(HistoryItem),\n usage: Usage,\n stop_reason: StopReason,\n})\nexport type Turn = typeof Turn.Type\n\n/**\n * Canonical events emitted while a single turn is being generated. Most\n * variants are streaming deltas (text, reasoning, tool-call args); the\n * terminal `TurnComplete` carries the assembled `Turn`. Lifecycle members\n * aren't deltas, hence the union name.\n *\n * `ReasoningDelta.kind`: `trace` is the model's raw chain-of-thought;\n * `summary` is a model-written summary intended for display. OpenAI\n * Responses emits both; Anthropic and Gemini only emit `trace`.\n *\n * `RefusalDelta`: the model declined to answer. OpenAI Responses emits\n * this as its own event; Anthropic surfaces refusals via `stop_reason`\n * and Gemini collapses them into `finishReason: SAFETY` — both go\n * without a `RefusalDelta`.\n *\n * `UsageUpdate`: mid-stream cumulative usage. Anthropic emits this on\n * `message_start` and `message_delta`; other providers may only deliver\n * usage via `TurnComplete.turn.usage`.\n */\nexport type TurnEvent = Data.TaggedEnum<{\n TextDelta: { readonly text: string }\n ReasoningDelta: { readonly text: string; readonly kind: \"trace\" | \"summary\" }\n RefusalDelta: { readonly text: string }\n ToolCallStart: { readonly call_id: string; readonly name: string }\n ToolCallArgsDelta: { readonly call_id: string; readonly delta: string }\n UsageUpdate: { readonly usage: Usage }\n TurnComplete: { readonly turn: Turn }\n}>\n\nexport const TurnEvent = Data.taggedEnum<TurnEvent>()\n\n/**\n * What flows out of an agent loop body to its consumer per turn: every\n * `TurnEvent` the provider emits (including the terminal `TurnComplete`\n * carrying the assembled `Turn`), plus the output of any tool the loop ran.\n * Both variants carry a `_tag` discriminator.\n */\nexport type InteractionEvent = TurnEvent | ToolCallOutput\n\nexport const isTurnComplete = TurnEvent.$is(\"TurnComplete\")\n\nexport const getToolCalls = (turn: Turn): ReadonlyArray<ToolCall> => turn.items.filter(isToolCall)\n\nexport const reasonings = (turn: Turn): ReadonlyArray<Reasoning> => turn.items.filter(isReasoning)\n\nexport const assistantMessages = (turn: Turn): ReadonlyArray<Message> =>\n turn.items.filter((i): i is Message => i.type === \"message\" && i.role === \"assistant\")\n\n/**\n * Every `output_text` payload across every assistant message in the turn,\n * preserving order. Refusals and other content blocks are dropped — use\n * `assistantMessages` if you need to inspect them. The primitive for\n * \"give me the assistant's text\"; callers decide how to combine\n * (typically `.join(\"\")` for prose or `.join(\" \")` for log strings).\n */\nexport const assistantTexts = (turn: Turn): ReadonlyArray<string> =>\n assistantMessages(turn)\n .flatMap((m) => m.content)\n .filter(isOutputText)\n .map((b) => b.text)\n\n/**\n * Sugar over `assistantTexts(turn).join(\"\")` — the common case for\n * summarizers, classifiers, judge calls, and structured-output backstops\n * that want one concatenated string.\n */\nexport const assistantText = (turn: Turn): string => assistantTexts(turn).join(\"\")\n\n/**\n * Append a completed turn and optional follow-up items to a state record's\n * history. Recipes use this at the point where structured tool results are\n * converted to model-facing `ToolCallOutput`s.\n */\nexport const appendToHistory = <S extends { readonly history: ReadonlyArray<HistoryItem> }>(\n state: S,\n turn: Turn,\n items: ReadonlyArray<HistoryItem> = [],\n): S => ({\n ...state,\n history: [...state.history, ...turn.items, ...items],\n})\n\n// ---------------------------------------------------------------------------\n// Stream operators\n// ---------------------------------------------------------------------------\n\n/**\n * Project a `TurnEvent` stream onto its `TextDelta` payloads. Other\n * variants are dropped. Composes with `Lines.lines` +\n * `decodeJsonLines` for prompted-JSONL streaming.\n */\nexport const textDeltas = <E, R>(\n self: Stream.Stream<TurnEvent, E, R>,\n): Stream.Stream<string, E, R> =>\n self.pipe(\n Stream.filterMap((ev) => (ev._tag === \"TextDelta\" ? Result.succeed(ev.text) : Result.failVoid)),\n )\n\n// ---------------------------------------------------------------------------\n// Structured-output integration\n// ---------------------------------------------------------------------------\n\n/**\n * The assistant message on the just-completed turn was a refusal block,\n * not an `output_text` payload. Returned by `decodeStructured` to short-circuit\n * decoding before `JSON.parse` / schema validation runs.\n */\nexport class RefusalRejected extends Data.TaggedError(\"RefusalRejected\")<{\n readonly turn: Turn\n}> {}\n\nconst lastAssistantContent = (turn: Turn): { readonly text: string; readonly refused: boolean } => {\n const assistants = assistantMessages(turn)\n const last = assistants[assistants.length - 1]\n if (last === undefined) return { text: \"\", refused: false }\n if (last.content.some(isRefusal)) return { text: \"\", refused: true }\n const text = last.content\n .filter(isOutputText)\n .map((b) => b.text)\n .join(\"\")\n return { text, refused: false }\n}\n\n/**\n * Validate a completed `Turn` against a `StructuredFormat`. Concatenates\n * `output_text` blocks on the last assistant message, then runs\n * `JSON.parse` + the format's schema validation.\n *\n * Three failure modes:\n * - `RefusalRejected` — the assistant emitted a refusal block.\n * - `JsonParseError` — the assembled text wasn't valid JSON.\n * - `StructuredDecodeError` — the JSON didn't match the schema.\n */\nexport const decodeStructured = <A>(\n turn: Turn,\n format: StructuredFormat.StructuredFormat<A>,\n): Effect.Effect<\n A,\n RefusalRejected | StructuredFormat.JsonParseError | StructuredFormat.StructuredDecodeError\n> =>\n pipe(lastAssistantContent(turn), ({ text, refused }) =>\n refused ? Effect.fail(new RefusalRejected({ turn })) : StructuredFormat.parseJson(format)(text),\n )\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Turn.mjs","names":["StructuredFormat.parseJson"],"sources":["../../src/domain/Turn.ts"],"sourcesContent":["import { Data, Effect, Result, Schema, Stream, pipe } from \"effect\"\nimport * as StructuredFormat from \"../structured-format/StructuredFormat.js\"\nimport {\n type Annotation,\n HistoryItem,\n Message,\n Reasoning,\n StopReason,\n ToolCall,\n ToolCallOutput,\n Usage,\n isOutputText,\n isReasoning,\n isRefusal,\n isToolCall,\n} from \"./Items.js\"\n\n/**\n * The result of a single LLM generation. A turn produces zero or more items\n * (typically one assistant message and zero or more function_call items)\n * and reports usage + a stop reason.\n */\nexport const Turn = Schema.Struct({\n items: Schema.Array(HistoryItem),\n usage: Usage,\n stop_reason: StopReason,\n})\nexport type Turn = typeof Turn.Type\n\n/**\n * Canonical events emitted while a single turn is being generated. Most\n * variants are streaming deltas (text, reasoning, tool-call args); the\n * terminal `TurnComplete` carries the assembled `Turn`. Lifecycle members\n * aren't deltas, hence the union name.\n *\n * `ReasoningDelta.kind`: `trace` is the model's raw chain-of-thought;\n * `summary` is a model-written summary intended for display. OpenAI\n * Responses emits both; Anthropic and Gemini only emit `trace`.\n *\n * `RefusalDelta`: the model declined to answer. OpenAI Responses emits\n * this as its own event; Anthropic surfaces refusals via `stop_reason`\n * and Gemini collapses them into `finishReason: SAFETY` — both go\n * without a `RefusalDelta`.\n *\n * `UsageUpdate`: mid-stream cumulative usage. Anthropic emits this on\n * `message_start` and `message_delta`; other providers may only deliver\n * usage via `TurnComplete.turn.usage`.\n *\n * `WebSearchCall`: lifecycle of a provider-executed web search within the\n * turn. Fires only when the turn grounds against search; absent otherwise.\n *\n * `CitationAdded`: a citation attached to the answer, emitted incrementally\n * where the provider streams citations. Providers that bundle citations emit\n * none of these; their citations still arrive on `TurnComplete.turn`\n * (`OutputText.annotations`). Either way the final set is on the assembled turn.\n */\nexport type TurnEvent = Data.TaggedEnum<{\n TextDelta: { readonly text: string }\n ReasoningDelta: { readonly text: string; readonly kind: \"trace\" | \"summary\" }\n RefusalDelta: { readonly text: string }\n ToolCallStart: { readonly call_id: string; readonly name: string }\n ToolCallArgsDelta: { readonly call_id: string; readonly delta: string }\n UsageUpdate: { readonly usage: Usage }\n WebSearchCall: {\n readonly status: \"started\" | \"searching\" | \"completed\"\n readonly query?: string\n readonly action?: \"search\" | \"open_page\" | \"find_in_page\"\n }\n CitationAdded: { readonly annotation: Annotation }\n TurnComplete: { readonly turn: Turn }\n}>\n\nexport const TurnEvent = Data.taggedEnum<TurnEvent>()\n\n/**\n * What flows out of an agent loop body to its consumer per turn: every\n * `TurnEvent` the provider emits (including the terminal `TurnComplete`\n * carrying the assembled `Turn`), plus the output of any tool the loop ran.\n * Both variants carry a `_tag` discriminator.\n */\nexport type InteractionEvent = TurnEvent | ToolCallOutput\n\nexport const isTurnComplete = TurnEvent.$is(\"TurnComplete\")\n\nexport const getToolCalls = (turn: Turn): ReadonlyArray<ToolCall> => turn.items.filter(isToolCall)\n\nexport const reasonings = (turn: Turn): ReadonlyArray<Reasoning> => turn.items.filter(isReasoning)\n\nexport const assistantMessages = (turn: Turn): ReadonlyArray<Message> =>\n turn.items.filter((i): i is Message => i.type === \"message\" && i.role === \"assistant\")\n\n/**\n * Every `output_text` payload across every assistant message in the turn,\n * preserving order. Refusals and other content blocks are dropped — use\n * `assistantMessages` if you need to inspect them. The primitive for\n * \"give me the assistant's text\"; callers decide how to combine\n * (typically `.join(\"\")` for prose or `.join(\" \")` for log strings).\n */\nexport const assistantTexts = (turn: Turn): ReadonlyArray<string> =>\n assistantMessages(turn)\n .flatMap((m) => m.content)\n .filter(isOutputText)\n .map((b) => b.text)\n\n/**\n * Sugar over `assistantTexts(turn).join(\"\")` — the common case for\n * summarizers, classifiers, judge calls, and structured-output backstops\n * that want one concatenated string.\n */\nexport const assistantText = (turn: Turn): string => assistantTexts(turn).join(\"\")\n\n/**\n * Every citation annotation attached to the turn's assistant `output_text`\n * blocks, in order. The flat view of a grounded turn's sources, whether the\n * turn came from a normal generation with native search or a deep-research job.\n */\nexport const citations = (turn: Turn): ReadonlyArray<Annotation> =>\n assistantMessages(turn)\n .flatMap((m) => m.content)\n .filter(isOutputText)\n .flatMap((b) => b.annotations ?? [])\n\n/**\n * Append a completed turn and optional follow-up items to a state record's\n * history. Recipes use this at the point where structured tool results are\n * converted to model-facing `ToolCallOutput`s.\n */\nexport const appendToHistory = <S extends { readonly history: ReadonlyArray<HistoryItem> }>(\n state: S,\n turn: Turn,\n items: ReadonlyArray<HistoryItem> = [],\n): S => ({\n ...state,\n history: [...state.history, ...turn.items, ...items],\n})\n\n// ---------------------------------------------------------------------------\n// Stream operators\n// ---------------------------------------------------------------------------\n\n/**\n * Project a `TurnEvent` stream onto its `TextDelta` payloads. Other\n * variants are dropped. Composes with `Lines.lines` +\n * `decodeJsonLines` for prompted-JSONL streaming.\n */\nexport const textDeltas = <E, R>(\n self: Stream.Stream<TurnEvent, E, R>,\n): Stream.Stream<string, E, R> =>\n self.pipe(\n Stream.filterMap((ev) => (ev._tag === \"TextDelta\" ? Result.succeed(ev.text) : Result.failVoid)),\n )\n\n// ---------------------------------------------------------------------------\n// Structured-output integration\n// ---------------------------------------------------------------------------\n\n/**\n * The assistant message on the just-completed turn was a refusal block,\n * not an `output_text` payload. Returned by `decodeStructured` to short-circuit\n * decoding before `JSON.parse` / schema validation runs.\n */\nexport class RefusalRejected extends Data.TaggedError(\"RefusalRejected\")<{\n readonly turn: Turn\n}> {}\n\nconst lastAssistantContent = (turn: Turn): { readonly text: string; readonly refused: boolean } => {\n const assistants = assistantMessages(turn)\n const last = assistants[assistants.length - 1]\n if (last === undefined) return { text: \"\", refused: false }\n if (last.content.some(isRefusal)) return { text: \"\", refused: true }\n const text = last.content\n .filter(isOutputText)\n .map((b) => b.text)\n .join(\"\")\n return { text, refused: false }\n}\n\n/**\n * Validate a completed `Turn` against a `StructuredFormat`. Concatenates\n * `output_text` blocks on the last assistant message, then runs\n * `JSON.parse` + the format's schema validation.\n *\n * Three failure modes:\n * - `RefusalRejected` — the assistant emitted a refusal block.\n * - `JsonParseError` — the assembled text wasn't valid JSON.\n * - `StructuredDecodeError` — the JSON didn't match the schema.\n */\nexport const decodeStructured = <A>(\n turn: Turn,\n format: StructuredFormat.StructuredFormat<A>,\n): Effect.Effect<\n A,\n RefusalRejected | StructuredFormat.JsonParseError | StructuredFormat.StructuredDecodeError\n> =>\n pipe(lastAssistantContent(turn), ({ text, refused }) =>\n refused ? Effect.fail(new RefusalRejected({ turn })) : StructuredFormat.parseJson(format)(text),\n )\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,MAAa,OAAO,OAAO,OAAO;CAChC,OAAO,OAAO,MAAM,YAAY;CAChC,OAAO;CACP,aAAa;CACd,CAAC;AA8CF,MAAa,YAAY,KAAK,YAAuB;AAUrD,MAAa,iBAAiB,UAAU,IAAI,eAAe;AAE3D,MAAa,gBAAgB,SAAwC,KAAK,MAAM,OAAO,WAAW;AAElG,MAAa,cAAc,SAAyC,KAAK,MAAM,OAAO,YAAY;AAElG,MAAa,qBAAqB,SAChC,KAAK,MAAM,QAAQ,MAAoB,EAAE,SAAS,aAAa,EAAE,SAAS,YAAY;;;;;;;;AASxF,MAAa,kBAAkB,SAC7B,kBAAkB,KAAK,CACpB,SAAS,MAAM,EAAE,QAAQ,CACzB,OAAO,aAAa,CACpB,KAAK,MAAM,EAAE,KAAK;;;;;;AAOvB,MAAa,iBAAiB,SAAuB,eAAe,KAAK,CAAC,KAAK,GAAG;;;;;;AAOlF,MAAa,aAAa,SACxB,kBAAkB,KAAK,CACpB,SAAS,MAAM,EAAE,QAAQ,CACzB,OAAO,aAAa,CACpB,SAAS,MAAM,EAAE,eAAe,EAAE,CAAC;;;;;;AAOxC,MAAa,mBACX,OACA,MACA,QAAoC,EAAE,MAC/B;CACP,GAAG;CACH,SAAS;EAAC,GAAG,MAAM;EAAS,GAAG,KAAK;EAAO,GAAG;EAAM;CACrD;;;;;;AAWD,MAAa,cACX,SAEA,KAAK,KACH,OAAO,WAAW,OAAQ,GAAG,SAAS,cAAc,OAAO,QAAQ,GAAG,KAAK,GAAG,OAAO,SAAU,CAChG;;;;;;AAWH,IAAa,kBAAb,cAAqC,KAAK,YAAY,kBAAkB,CAErE;AAEH,MAAM,wBAAwB,SAAqE;CACjG,MAAM,aAAa,kBAAkB,KAAK;CAC1C,MAAM,OAAO,WAAW,WAAW,SAAS;AAC5C,KAAI,SAAS,KAAA,EAAW,QAAO;EAAE,MAAM;EAAI,SAAS;EAAO;AAC3D,KAAI,KAAK,QAAQ,KAAK,UAAU,CAAE,QAAO;EAAE,MAAM;EAAI,SAAS;EAAM;AAKpE,QAAO;EAAE,MAJI,KAAK,QACf,OAAO,aAAa,CACpB,KAAK,MAAM,EAAE,KAAK,CAClB,KAAK,GACK;EAAE,SAAS;EAAO;;;;;;;;;;;;AAajC,MAAa,oBACX,MACA,WAKA,KAAK,qBAAqB,KAAK,GAAG,EAAE,MAAM,cACxC,UAAU,OAAO,KAAK,IAAI,gBAAgB,EAAE,MAAM,CAAC,CAAC,GAAGA,UAA2B,OAAO,CAAC,KAAK,CAChG"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { assistantText, systemText, userText } from "./Items.mjs";
|
|
2
2
|
import { assistantText as assistantText$1, assistantTexts } from "./Turn.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { c as it, n as globalExpect, o as describe } from "../dist-CcRV3-A5.mjs";
|
|
4
4
|
//#region src/domain/Turn.test.ts
|
|
5
5
|
const turnOf = (items) => ({
|
|
6
6
|
items,
|
|
@@ -10,9 +10,9 @@ var EmbeddingModel_exports = /* @__PURE__ */ __exportAll({
|
|
|
10
10
|
});
|
|
11
11
|
var EmbeddingModel = class extends Context.Service()("@betalyra/effect-uai/EmbeddingModel") {};
|
|
12
12
|
/** Embed a single input. */
|
|
13
|
-
const embed = (request) => Effect.flatMap(EmbeddingModel
|
|
13
|
+
const embed = (request) => Effect.flatMap(EmbeddingModel, (m) => m.embed(request));
|
|
14
14
|
/** Embed a batch in one provider call. Same `task` for every input. */
|
|
15
|
-
const embedMany = (request) => Effect.flatMap(EmbeddingModel
|
|
15
|
+
const embedMany = (request) => Effect.flatMap(EmbeddingModel, (m) => m.embedMany(request));
|
|
16
16
|
/**
|
|
17
17
|
* Guard a requested `encoding` against a provider's supported set. Returns
|
|
18
18
|
* `void` when the encoding is unset or supported, and fails
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmbeddingModel.mjs","names":["AiError.Unsupported"],"sources":["../../src/embedding-model/EmbeddingModel.ts"],"sourcesContent":["import { Context, Effect } from \"effect\"\nimport * as AiError from \"../domain/AiError.js\"\nimport type { EmbeddingFor, EmbedInput, ResponseEncoding, Usage } from \"./Embedding.js\"\n\n/**\n * Output representation requested from the provider. Cross-provider dense\n * quantization only, the same vector at different storage cost:\n * - `float32`: universal default.\n * - `int8`: ~4x smaller, minimal recall loss on most benchmarks. Supported\n * by Cohere, Voyage, Jina (binary only), Mixedbread.\n * - `binary`: ~32x smaller, meaningful recall loss but pairs well with a\n * float32 reranker pass over a small candidate set.\n *\n * Non-dense representations (`sparse`, `multivector`) are a different vector\n * *structure*, not a storage option, and are produced by Jina only. They\n * live on `JinaEncoding`, not here (the same widening pattern `task` uses).\n * The response `Embedding` union still carries all arms, see\n * {@link ResponseEncoding}.\n *\n * Each provider's typed request narrows this to its supported set. On the\n * generic `EmbeddingModel` path, a provider that emits float32 only (OpenAI,\n * Gemini) rejects a non-float32 encoding with `AiError.Unsupported`\n * (bucket 1) via {@link assertEncoding}, rather than silently returning a\n * mislabeled float32 vector.\n */\nexport type EmbedEncoding = \"float32\" | \"int8\" | \"binary\"\n\n/**\n * Cross-provider single-embed request. Mirrors the shape of\n * `LanguageModel.CommonRequest`: cross-cutting fields here, vendor\n * specifics in the provider's typed request.\n *\n * Provider-specific extensions (Cohere widened `task` enum, Jina LoRA\n * tasks, Mixedbread free-form `prompt`, etc.) live in that provider's own\n * request interface, which extends this and narrows `model` / widens\n * `task`.\n */\nexport type CommonEmbedRequest = {\n readonly input: EmbedInput\n /**\n * Model identifier. Each provider narrows this to its typed literal\n * union, so code that yields a typed provider tag gets autocompletion.\n */\n readonly model: string\n /**\n * Retrieval-task hint. Applies to the input. OpenAI ignores this;\n * Mixedbread doesn't have it; Cohere v3+ requires it on the wire (typed\n * as required in `CohereEmbedRequest`). Provider-specific task enums\n * (classification, clustering, code retrieval, …) live on the\n * provider's own request type.\n */\n readonly task?: \"query\" | \"document\"\n /**\n * Matryoshka truncation. Default: provider's native dimension.\n * Discrete-value providers (Cohere, Vertex `multimodalembedding@001`)\n * narrow this to a literal union in their typed request.\n */\n readonly dimensions?: number\n /**\n * Output representation - see {@link EmbedEncoding}. Dense float32 is the\n * default; provider layers reject unsupported values up front with\n * `InvalidRequest`.\n */\n readonly encoding?: EmbedEncoding\n}\n\n/**\n * Cross-provider batch-embed request. One `task` for the whole batch -\n * mixed-task batches aren't a real provider feature (rerankers exist for\n * that).\n */\nexport type CommonEmbedManyRequest = Omit<CommonEmbedRequest, \"input\"> & {\n readonly inputs: ReadonlyArray<EmbedInput>\n}\n\n/**\n * Single-embed response. The `embedding` type is determined by the\n * request's `encoding` field via `EmbeddingFor<E>` — callers that don't\n * specify an encoding get a `Float32Embedding` directly with no runtime\n * narrowing. Defaults to `undefined` for back-compat with consumers that\n * use the bare `EmbedResponse` name.\n */\nexport type EmbedResponse<E extends ResponseEncoding | undefined = undefined> = {\n readonly embedding: EmbeddingFor<E>\n readonly usage: Usage\n}\n\n/** Batch-embed response. Same encoding rule as {@link EmbedResponse}. */\nexport type EmbedManyResponse<E extends ResponseEncoding | undefined = undefined> = {\n readonly embeddings: ReadonlyArray<EmbeddingFor<E>>\n readonly usage: Usage\n}\n\nexport type EmbeddingModelService = {\n readonly embed: <E extends EmbedEncoding | undefined = undefined>(\n request: Omit<CommonEmbedRequest, \"encoding\"> & { readonly encoding?: E },\n ) => Effect.Effect<EmbedResponse<E>, AiError.AiError>\n readonly embedMany: <E extends EmbedEncoding | undefined = undefined>(\n request: Omit<CommonEmbedManyRequest, \"encoding\"> & { readonly encoding?: E },\n ) => Effect.Effect<EmbedManyResponse<E>, AiError.AiError>\n}\n\nexport class EmbeddingModel extends Context.Service<EmbeddingModel, EmbeddingModelService>()(\n \"@betalyra/effect-uai/EmbeddingModel\",\n) {}\n\n/** Embed a single input. */\nexport const embed = <E extends EmbedEncoding | undefined = undefined>(\n request: Omit<CommonEmbedRequest, \"encoding\"> & { readonly encoding?: E },\n): Effect.Effect<EmbedResponse<E>, AiError.AiError, EmbeddingModel> =>\n Effect.flatMap(EmbeddingModel
|
|
1
|
+
{"version":3,"file":"EmbeddingModel.mjs","names":["AiError.Unsupported"],"sources":["../../src/embedding-model/EmbeddingModel.ts"],"sourcesContent":["import { Context, Effect } from \"effect\"\nimport * as AiError from \"../domain/AiError.js\"\nimport type { EmbeddingFor, EmbedInput, ResponseEncoding, Usage } from \"./Embedding.js\"\n\n/**\n * Output representation requested from the provider. Cross-provider dense\n * quantization only, the same vector at different storage cost:\n * - `float32`: universal default.\n * - `int8`: ~4x smaller, minimal recall loss on most benchmarks. Supported\n * by Cohere, Voyage, Jina (binary only), Mixedbread.\n * - `binary`: ~32x smaller, meaningful recall loss but pairs well with a\n * float32 reranker pass over a small candidate set.\n *\n * Non-dense representations (`sparse`, `multivector`) are a different vector\n * *structure*, not a storage option, and are produced by Jina only. They\n * live on `JinaEncoding`, not here (the same widening pattern `task` uses).\n * The response `Embedding` union still carries all arms, see\n * {@link ResponseEncoding}.\n *\n * Each provider's typed request narrows this to its supported set. On the\n * generic `EmbeddingModel` path, a provider that emits float32 only (OpenAI,\n * Gemini) rejects a non-float32 encoding with `AiError.Unsupported`\n * (bucket 1) via {@link assertEncoding}, rather than silently returning a\n * mislabeled float32 vector.\n */\nexport type EmbedEncoding = \"float32\" | \"int8\" | \"binary\"\n\n/**\n * Cross-provider single-embed request. Mirrors the shape of\n * `LanguageModel.CommonRequest`: cross-cutting fields here, vendor\n * specifics in the provider's typed request.\n *\n * Provider-specific extensions (Cohere widened `task` enum, Jina LoRA\n * tasks, Mixedbread free-form `prompt`, etc.) live in that provider's own\n * request interface, which extends this and narrows `model` / widens\n * `task`.\n */\nexport type CommonEmbedRequest = {\n readonly input: EmbedInput\n /**\n * Model identifier. Each provider narrows this to its typed literal\n * union, so code that yields a typed provider tag gets autocompletion.\n */\n readonly model: string\n /**\n * Retrieval-task hint. Applies to the input. OpenAI ignores this;\n * Mixedbread doesn't have it; Cohere v3+ requires it on the wire (typed\n * as required in `CohereEmbedRequest`). Provider-specific task enums\n * (classification, clustering, code retrieval, …) live on the\n * provider's own request type.\n */\n readonly task?: \"query\" | \"document\"\n /**\n * Matryoshka truncation. Default: provider's native dimension.\n * Discrete-value providers (Cohere, Vertex `multimodalembedding@001`)\n * narrow this to a literal union in their typed request.\n */\n readonly dimensions?: number\n /**\n * Output representation - see {@link EmbedEncoding}. Dense float32 is the\n * default; provider layers reject unsupported values up front with\n * `InvalidRequest`.\n */\n readonly encoding?: EmbedEncoding\n}\n\n/**\n * Cross-provider batch-embed request. One `task` for the whole batch -\n * mixed-task batches aren't a real provider feature (rerankers exist for\n * that).\n */\nexport type CommonEmbedManyRequest = Omit<CommonEmbedRequest, \"input\"> & {\n readonly inputs: ReadonlyArray<EmbedInput>\n}\n\n/**\n * Single-embed response. The `embedding` type is determined by the\n * request's `encoding` field via `EmbeddingFor<E>` — callers that don't\n * specify an encoding get a `Float32Embedding` directly with no runtime\n * narrowing. Defaults to `undefined` for back-compat with consumers that\n * use the bare `EmbedResponse` name.\n */\nexport type EmbedResponse<E extends ResponseEncoding | undefined = undefined> = {\n readonly embedding: EmbeddingFor<E>\n readonly usage: Usage\n}\n\n/** Batch-embed response. Same encoding rule as {@link EmbedResponse}. */\nexport type EmbedManyResponse<E extends ResponseEncoding | undefined = undefined> = {\n readonly embeddings: ReadonlyArray<EmbeddingFor<E>>\n readonly usage: Usage\n}\n\nexport type EmbeddingModelService = {\n readonly embed: <E extends EmbedEncoding | undefined = undefined>(\n request: Omit<CommonEmbedRequest, \"encoding\"> & { readonly encoding?: E },\n ) => Effect.Effect<EmbedResponse<E>, AiError.AiError>\n readonly embedMany: <E extends EmbedEncoding | undefined = undefined>(\n request: Omit<CommonEmbedManyRequest, \"encoding\"> & { readonly encoding?: E },\n ) => Effect.Effect<EmbedManyResponse<E>, AiError.AiError>\n}\n\nexport class EmbeddingModel extends Context.Service<EmbeddingModel, EmbeddingModelService>()(\n \"@betalyra/effect-uai/EmbeddingModel\",\n) {}\n\n/** Embed a single input. */\nexport const embed = <E extends EmbedEncoding | undefined = undefined>(\n request: Omit<CommonEmbedRequest, \"encoding\"> & { readonly encoding?: E },\n): Effect.Effect<EmbedResponse<E>, AiError.AiError, EmbeddingModel> =>\n Effect.flatMap(EmbeddingModel, (m) => m.embed(request))\n\n/** Embed a batch in one provider call. Same `task` for every input. */\nexport const embedMany = <E extends EmbedEncoding | undefined = undefined>(\n request: Omit<CommonEmbedManyRequest, \"encoding\"> & { readonly encoding?: E },\n): Effect.Effect<EmbedManyResponse<E>, AiError.AiError, EmbeddingModel> =>\n Effect.flatMap(EmbeddingModel, (m) => m.embedMany(request))\n\n/**\n * Guard a requested `encoding` against a provider's supported set. Returns\n * `void` when the encoding is unset or supported, and fails\n * `AiError.Unsupported` (bucket 1) otherwise.\n *\n * Used by the generic-tag registration of providers that emit a strict\n * subset of `EmbedEncoding`: OpenAI / Gemini pass `[\"float32\"]`, Jina passes\n * `[\"float32\", \"binary\"]`. Without this guard, a non-supported encoding on\n * the generic path silently returns a float32 vector mislabeled as the\n * requested type (the `as`-cast lie), which breaks downstream storage and\n * vector math.\n */\nexport const assertEncoding = (\n encoding: EmbedEncoding | undefined,\n supported: ReadonlyArray<EmbedEncoding>,\n provider: string,\n): Effect.Effect<void, AiError.AiError> =>\n encoding === undefined || supported.includes(encoding)\n ? Effect.void\n : Effect.fail(\n new AiError.Unsupported({\n provider,\n capability: \"encoding\",\n reason: `${provider} emits ${supported.join(\" / \")} only; encoding=\"${encoding}\" is unavailable.`,\n }),\n )\n"],"mappings":";;;;;;;;;;AAsGA,IAAa,iBAAb,cAAoC,QAAQ,SAAgD,CAC1F,sCACD,CAAC;;AAGF,MAAa,SACX,YAEA,OAAO,QAAQ,iBAAiB,MAAM,EAAE,MAAM,QAAQ,CAAC;;AAGzD,MAAa,aACX,YAEA,OAAO,QAAQ,iBAAiB,MAAM,EAAE,UAAU,QAAQ,CAAC;;;;;;;;;;;;;AAc7D,MAAa,kBACX,UACA,WACA,aAEA,aAAa,KAAA,KAAa,UAAU,SAAS,SAAS,GAClD,OAAO,OACP,OAAO,KACL,IAAIA,YAAoB;CACtB;CACA,YAAY;CACZ,QAAQ,GAAG,SAAS,SAAS,UAAU,KAAK,MAAM,CAAC,mBAAmB,SAAS;CAChF,CAAC,CACH"}
|