@effect-uai/core 0.13.0 → 0.14.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/{Audio-60lKKHxS.d.mts → Audio-_nGR4V0X.d.mts} +2 -2
- package/dist/{Audio-60lKKHxS.d.mts.map → Audio-_nGR4V0X.d.mts.map} +1 -1
- package/dist/Image-Cv6iBLTy.d.mts +99 -0
- package/dist/Image-Cv6iBLTy.d.mts.map +1 -0
- package/dist/{Items-SfUabNuB.d.mts → Items-C7MyrYPX.d.mts} +35 -4
- package/dist/Items-C7MyrYPX.d.mts.map +1 -0
- package/dist/Media-BbX7BAaO.d.mts +60 -0
- package/dist/Media-BbX7BAaO.d.mts.map +1 -0
- package/dist/{Tool-DE-rnvkw.d.mts → Tool-BF78QWtn.d.mts} +2 -2
- package/dist/{Tool-DE-rnvkw.d.mts.map → Tool-BF78QWtn.d.mts.map} +1 -1
- package/dist/{ToolEvent-D99MGQYH.d.mts → ToolEvent-Di4a723B.d.mts} +2 -2
- package/dist/{ToolEvent-D99MGQYH.d.mts.map → ToolEvent-Di4a723B.d.mts.map} +1 -1
- package/dist/{ToolResult-Cj8ChodL.d.mts → ToolResult-BsYQRjmW.d.mts} +2 -2
- package/dist/{ToolResult-Cj8ChodL.d.mts.map → ToolResult-BsYQRjmW.d.mts.map} +1 -1
- package/dist/{Toolkit-BEZrNPTI.d.mts → Toolkit-DAjJ9Tvl.d.mts} +5 -5
- package/dist/{Toolkit-BEZrNPTI.d.mts.map → Toolkit-DAjJ9Tvl.d.mts.map} +1 -1
- package/dist/browser/BrowserTool.d.mts +1 -1
- package/dist/capabilities/Capabilities.d.mts +26 -2
- package/dist/capabilities/Capabilities.d.mts.map +1 -1
- package/dist/capabilities/Capabilities.mjs +32 -1
- package/dist/capabilities/Capabilities.mjs.map +1 -1
- package/dist/domain/Audio.d.mts +1 -1
- package/dist/domain/Image.d.mts +3 -2
- package/dist/domain/Image.mjs +29 -3
- package/dist/domain/Image.mjs.map +1 -1
- package/dist/domain/Items.d.mts +2 -2
- package/dist/domain/Items.mjs +19 -1
- package/dist/domain/Items.mjs.map +1 -1
- package/dist/domain/Media.d.mts +2 -2
- package/dist/domain/Media.mjs +51 -2
- package/dist/domain/Media.mjs.map +1 -1
- package/dist/domain/Music.d.mts +3 -8
- package/dist/domain/Music.d.mts.map +1 -1
- package/dist/domain/Music.mjs.map +1 -1
- package/dist/domain/Research.d.mts +1 -1
- package/dist/domain/Turn.d.mts +73 -9
- package/dist/domain/Turn.d.mts.map +1 -1
- package/dist/domain/Turn.mjs +38 -2
- package/dist/domain/Turn.mjs.map +1 -1
- package/dist/embedding-model/Embedding.d.mts +1 -1
- package/dist/image-generator/ImageGenerator.d.mts +188 -0
- package/dist/image-generator/ImageGenerator.d.mts.map +1 -0
- package/dist/image-generator/ImageGenerator.mjs +50 -0
- package/dist/image-generator/ImageGenerator.mjs.map +1 -0
- package/dist/index.d.mts +11 -9
- package/dist/index.mjs +4 -2
- package/dist/language-model/LanguageModel.d.mts +2 -2
- package/dist/music-generator/MusicGenerator.d.mts +3 -2
- package/dist/music-generator/MusicGenerator.d.mts.map +1 -1
- package/dist/observability/Metrics.d.mts +1 -1
- package/dist/speech-synthesizer/SpeechSynthesizer.d.mts +1 -1
- package/dist/streaming/Multipart.d.mts +21 -0
- package/dist/streaming/Multipart.d.mts.map +1 -0
- package/dist/streaming/Multipart.mjs +26 -0
- package/dist/streaming/Multipart.mjs.map +1 -0
- package/dist/testing/MockMusicGenerator.d.mts +1 -1
- package/dist/testing/MockProvider.d.mts +1 -1
- package/dist/testing/MockSpeechSynthesizer.d.mts +1 -1
- package/dist/tool/Approval.d.mts +3 -3
- package/dist/tool/HistoryCheck.d.mts +2 -2
- package/dist/tool/Tool.d.mts +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/transcriber/Transcriber.d.mts +1 -1
- package/dist/web-read/WebReadTool.d.mts +1 -1
- package/dist/web-search/WebSearchTool.d.mts +1 -1
- package/package.json +9 -1
- package/src/capabilities/Capabilities.ts +38 -0
- package/src/domain/Image.ts +68 -2
- package/src/domain/Items.ts +18 -1
- package/src/domain/Media.ts +66 -0
- package/src/domain/Music.ts +4 -3
- package/src/domain/Turn.ts +56 -0
- package/src/image-generator/ImageGenerator.ts +165 -0
- package/src/index.ts +2 -0
- package/src/streaming/Multipart.ts +29 -0
- package/dist/Image-BK8-4H6s.d.mts +0 -59
- package/dist/Image-BK8-4H6s.d.mts.map +0 -1
- package/dist/Items-SfUabNuB.d.mts.map +0 -1
- package/dist/Media-DwgpifPD.d.mts +0 -57
- package/dist/Media-DwgpifPD.d.mts.map +0 -1
package/dist/domain/Items.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as
|
|
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 };
|
|
1
|
+
import { A as isOutputImage, C as assistantText, D as isInputImage, E as isFilePath, F as isToolCallOutput, I as isUrlCitation, L as systemText, M as isReasoning, N as isRefusal, O as isInputText, P as isToolCall, R as toolCallOutput, S as Usage, T as isFileCitation, _ as Role, a as FilePath, b as ToolCallOutput, c as InputText, d as Message, f as OutputImage, g as Refusal, h as Reasoning, i as FileCitation, j as isOutputText, k as isMessage, l as InputTokensDetails, m as OutputTokensDetails, n as ContainerFileCitation, o as HistoryItem, p as OutputText, r as ContentBlock, s as InputImage, t as Annotation, v as StopReason, w as isContainerFileCitation, x as UrlCitation, y as ToolCall, z as userText } from "../Items-C7MyrYPX.mjs";
|
|
2
|
+
export { Annotation, ContainerFileCitation, ContentBlock, FileCitation, FilePath, HistoryItem, InputImage, InputText, InputTokensDetails, Message, OutputImage, OutputText, OutputTokensDetails, Reasoning, Refusal, Role, StopReason, ToolCall, ToolCallOutput, UrlCitation, Usage, assistantText, isContainerFileCitation, isFileCitation, isFilePath, isInputImage, isInputText, isMessage, isOutputImage, isOutputText, isReasoning, isRefusal, isToolCall, isToolCallOutput, isUrlCitation, systemText, toolCallOutput, userText };
|
package/dist/domain/Items.mjs
CHANGED
|
@@ -13,6 +13,7 @@ var Items_exports = /* @__PURE__ */ __exportAll({
|
|
|
13
13
|
InputText: () => InputText,
|
|
14
14
|
InputTokensDetails: () => InputTokensDetails,
|
|
15
15
|
Message: () => Message,
|
|
16
|
+
OutputImage: () => OutputImage,
|
|
16
17
|
OutputText: () => OutputText,
|
|
17
18
|
OutputTokensDetails: () => OutputTokensDetails,
|
|
18
19
|
Reasoning: () => Reasoning,
|
|
@@ -30,6 +31,7 @@ var Items_exports = /* @__PURE__ */ __exportAll({
|
|
|
30
31
|
isInputImage: () => isInputImage,
|
|
31
32
|
isInputText: () => isInputText,
|
|
32
33
|
isMessage: () => isMessage,
|
|
34
|
+
isOutputImage: () => isOutputImage,
|
|
33
35
|
isOutputText: () => isOutputText,
|
|
34
36
|
isReasoning: () => isReasoning,
|
|
35
37
|
isRefusal: () => isRefusal,
|
|
@@ -106,6 +108,20 @@ const OutputText = Schema.Struct({
|
|
|
106
108
|
annotations: Schema.optional(Schema.Array(Annotation))
|
|
107
109
|
});
|
|
108
110
|
/**
|
|
111
|
+
* Model-emitted image. The counterpart to {@link InputImage}: same
|
|
112
|
+
* `ImageSource`, so an image the model drew goes straight back into the
|
|
113
|
+
* next turn with no conversion.
|
|
114
|
+
*
|
|
115
|
+
* How the pixels were produced is not modelled here. A provider may draw
|
|
116
|
+
* them itself, as an image part of the turn, or reach a hosted tool that
|
|
117
|
+
* draws them; either way the fact is the same, and enabling it is
|
|
118
|
+
* provider-specific.
|
|
119
|
+
*/
|
|
120
|
+
const OutputImage = Schema.Struct({
|
|
121
|
+
type: Schema.Literal("output_image"),
|
|
122
|
+
source: ImageSource
|
|
123
|
+
});
|
|
124
|
+
/**
|
|
109
125
|
* Model-emitted refusal. Distinct from `output_text`: the model declined
|
|
110
126
|
* to answer rather than producing normal output. Pair with
|
|
111
127
|
* `stop_reason: "refusal"` on the surrounding `Turn`. Streamed via the
|
|
@@ -119,6 +135,7 @@ const ContentBlock = Schema.Union([
|
|
|
119
135
|
InputText,
|
|
120
136
|
InputImage,
|
|
121
137
|
OutputText,
|
|
138
|
+
OutputImage,
|
|
122
139
|
Refusal
|
|
123
140
|
]);
|
|
124
141
|
const Role = Schema.Literals([
|
|
@@ -168,6 +185,7 @@ const HistoryItem = Schema.Union([
|
|
|
168
185
|
const isInputText = Schema.is(InputText);
|
|
169
186
|
const isInputImage = Schema.is(InputImage);
|
|
170
187
|
const isOutputText = Schema.is(OutputText);
|
|
188
|
+
const isOutputImage = Schema.is(OutputImage);
|
|
171
189
|
const isRefusal = Schema.is(Refusal);
|
|
172
190
|
const isMessage = Schema.is(Message);
|
|
173
191
|
const isToolCall = Schema.is(ToolCall);
|
|
@@ -234,6 +252,6 @@ const toolCallOutput = (call_id, output) => ({
|
|
|
234
252
|
output
|
|
235
253
|
});
|
|
236
254
|
//#endregion
|
|
237
|
-
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, Items_exports as t, toolCallOutput, userText };
|
|
255
|
+
export { Annotation, ContainerFileCitation, ContentBlock, FileCitation, FilePath, HistoryItem, InputImage, InputText, InputTokensDetails, Message, OutputImage, OutputText, OutputTokensDetails, Reasoning, Refusal, Role, StopReason, ToolCall, ToolCallOutput, UrlCitation, Usage, assistantText, isContainerFileCitation, isFileCitation, isFilePath, isInputImage, isInputText, isMessage, isOutputImage, isOutputText, isReasoning, isRefusal, isToolCall, isToolCallOutput, isUrlCitation, systemText, Items_exports as t, toolCallOutput, userText };
|
|
238
256
|
|
|
239
257
|
//# sourceMappingURL=Items.mjs.map
|
|
@@ -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// 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":"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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 image. The counterpart to {@link InputImage}: same\n * `ImageSource`, so an image the model drew goes straight back into the\n * next turn with no conversion.\n *\n * How the pixels were produced is not modelled here. A provider may draw\n * them itself, as an image part of the turn, or reach a hosted tool that\n * draws them; either way the fact is the same, and enabling it is\n * provider-specific.\n */\nexport const OutputImage = Schema.Struct({\n type: Schema.Literal(\"output_image\"),\n source: ImageSource,\n})\nexport type OutputImage = typeof OutputImage.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, OutputImage, 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 isOutputImage = Schema.is(OutputImage)\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":"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"}
|
package/dist/domain/Media.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { c as isMediaUrl, i as
|
|
2
|
-
export { MediaBase64, MediaBytes, MediaSource, MediaUrl, isMediaBase64, isMediaBytes, isMediaUrl };
|
|
1
|
+
import { a as MediaSource, c as Watermark, d as isMediaUrl, f as parseAspectRatio, i as MediaBytes, l as isMediaBase64, n as Dimensions, o as MediaUrl, p as round16, r as MediaBase64, t as AspectRatio, u as isMediaBytes } from "../Media-BbX7BAaO.mjs";
|
|
2
|
+
export { AspectRatio, Dimensions, MediaBase64, MediaBytes, MediaSource, MediaUrl, Watermark, isMediaBase64, isMediaBytes, isMediaUrl, parseAspectRatio, round16 };
|
package/dist/domain/Media.mjs
CHANGED
|
@@ -1,14 +1,63 @@
|
|
|
1
1
|
import { n as __exportAll } from "../rolldown-runtime-EAsCxrDo.mjs";
|
|
2
|
+
import { Result } from "effect";
|
|
2
3
|
//#region src/domain/Media.ts
|
|
4
|
+
/**
|
|
5
|
+
* Cross-modality media reference shape.
|
|
6
|
+
*
|
|
7
|
+
* Every "media at rest" reference - image, audio, video, document - is one
|
|
8
|
+
* of three variants:
|
|
9
|
+
*
|
|
10
|
+
* - `url` : a remote address (HTTP, GCS, etc.). The model fetches it.
|
|
11
|
+
* `mimeType` is optional - servers usually set Content-Type.
|
|
12
|
+
* Some providers (Gemini `fileData`) want it explicit.
|
|
13
|
+
*
|
|
14
|
+
* - `base64` : an inline base64-encoded payload. Always carries a
|
|
15
|
+
* `mimeType` so the consumer knows how to decode.
|
|
16
|
+
*
|
|
17
|
+
* - `bytes` : raw `Uint8Array`. Provider layers normalize to base64 or
|
|
18
|
+
* multipart upload at the wire boundary - users don't need
|
|
19
|
+
* to encode themselves.
|
|
20
|
+
*
|
|
21
|
+
* Per-modality files (`Image.ts`, future `Audio.ts` / `Video.ts` /
|
|
22
|
+
* `Document.ts`) instantiate this shape with their typed MIME union to
|
|
23
|
+
* get autocomplete on common formats while keeping the structural type
|
|
24
|
+
* uniform across modalities.
|
|
25
|
+
*
|
|
26
|
+
* Streaming media (live mic feed, streaming TTS playback) is *not*
|
|
27
|
+
* modeled here. Streams carry effect parameters (`Stream<A, E, R>`) and
|
|
28
|
+
* lifecycle (Scope, cancellation) that don't apply to media at rest. The
|
|
29
|
+
* complementary type lives alongside this one as `*Stream` in each
|
|
30
|
+
* per-modality file when those modalities land.
|
|
31
|
+
*
|
|
32
|
+
* Provider-uploaded asset references (OpenAI Files `file_id`, Gemini
|
|
33
|
+
* Files API URIs, Anthropic file IDs) are also out of scope here -
|
|
34
|
+
* they're a separate union (`FileRef`) added when needed.
|
|
35
|
+
*/
|
|
3
36
|
var Media_exports = /* @__PURE__ */ __exportAll({
|
|
4
37
|
isMediaBase64: () => isMediaBase64,
|
|
5
38
|
isMediaBytes: () => isMediaBytes,
|
|
6
|
-
isMediaUrl: () => isMediaUrl
|
|
39
|
+
isMediaUrl: () => isMediaUrl,
|
|
40
|
+
parseAspectRatio: () => parseAspectRatio,
|
|
41
|
+
round16: () => round16
|
|
7
42
|
});
|
|
43
|
+
const positive = (n) => n !== void 0 && Number.isFinite(n) && n > 0;
|
|
44
|
+
/**
|
|
45
|
+
* Read `"W:H"` as a pair. Fails when the ratio is not arithmetic, which
|
|
46
|
+
* the `(string & {})` tail on {@link AspectRatio} lets through: a caller
|
|
47
|
+
* asking for `"cinematic"` gets a message rather than NaN pixels. The
|
|
48
|
+
* failure is a plain string so this file stays free of provider
|
|
49
|
+
* vocabulary; each adapter wraps it in its own error.
|
|
50
|
+
*/
|
|
51
|
+
const parseAspectRatio = (ratio) => {
|
|
52
|
+
const [w, h, ...rest] = ratio.split(":").map(Number);
|
|
53
|
+
return positive(w) && positive(h) && rest.length === 0 ? Result.succeed([w, h]) : Result.fail(`aspectRatio "${ratio}" must read "W:H" with positive numbers.`);
|
|
54
|
+
};
|
|
55
|
+
/** Several image endpoints require both edges to be multiples of 16. */
|
|
56
|
+
const round16 = (n) => Math.max(16, Math.round(n / 16) * 16);
|
|
8
57
|
const isMediaUrl = (s) => s._tag === "url";
|
|
9
58
|
const isMediaBase64 = (s) => s._tag === "base64";
|
|
10
59
|
const isMediaBytes = (s) => s._tag === "bytes";
|
|
11
60
|
//#endregion
|
|
12
|
-
export { isMediaBase64, isMediaBytes, isMediaUrl, Media_exports as t };
|
|
61
|
+
export { isMediaBase64, isMediaBytes, isMediaUrl, parseAspectRatio, round16, Media_exports as t };
|
|
13
62
|
|
|
14
63
|
//# sourceMappingURL=Media.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Media.mjs","names":[],"sources":["../../src/domain/Media.ts"],"sourcesContent":["/**\n * Cross-modality media reference shape.\n *\n * Every \"media at rest\" reference - image, audio, video, document - is one\n * of three variants:\n *\n * - `url` : a remote address (HTTP, GCS, etc.). The model fetches it.\n * `mimeType` is optional - servers usually set Content-Type.\n * Some providers (Gemini `fileData`) want it explicit.\n *\n * - `base64` : an inline base64-encoded payload. Always carries a\n * `mimeType` so the consumer knows how to decode.\n *\n * - `bytes` : raw `Uint8Array`. Provider layers normalize to base64 or\n * multipart upload at the wire boundary - users don't need\n * to encode themselves.\n *\n * Per-modality files (`Image.ts`, future `Audio.ts` / `Video.ts` /\n * `Document.ts`) instantiate this shape with their typed MIME union to\n * get autocomplete on common formats while keeping the structural type\n * uniform across modalities.\n *\n * Streaming media (live mic feed, streaming TTS playback) is *not*\n * modeled here. Streams carry effect parameters (`Stream<A, E, R>`) and\n * lifecycle (Scope, cancellation) that don't apply to media at rest. The\n * complementary type lives alongside this one as `*Stream` in each\n * per-modality file when those modalities land.\n *\n * Provider-uploaded asset references (OpenAI Files `file_id`, Gemini\n * Files API URIs, Anthropic file IDs) are also out of scope here -\n * they're a separate union (`FileRef`) added when needed.\n */\n\nexport type MediaUrl<M extends string = string> = {\n readonly _tag: \"url\"\n readonly url: string\n readonly mimeType?: M\n}\n\nexport type MediaBase64<M extends string = string> = {\n readonly _tag: \"base64\"\n readonly base64: string\n readonly mimeType: M\n}\n\nexport type MediaBytes<M extends string = string> = {\n readonly _tag: \"bytes\"\n readonly bytes: Uint8Array\n readonly mimeType: M\n}\n\nexport type MediaSource<M extends string = string> = MediaUrl<M> | MediaBase64<M> | MediaBytes<M>\n\nexport const isMediaUrl = <M extends string>(s: MediaSource<M>): s is MediaUrl<M> =>\n s._tag === \"url\"\n\nexport const isMediaBase64 = <M extends string>(s: MediaSource<M>): s is MediaBase64<M> =>\n s._tag === \"base64\"\n\nexport const isMediaBytes = <M extends string>(s: MediaSource<M>): s is MediaBytes<M> =>\n s._tag === \"bytes\"\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Media.mjs","names":[],"sources":["../../src/domain/Media.ts"],"sourcesContent":["/**\n * Cross-modality media reference shape.\n *\n * Every \"media at rest\" reference - image, audio, video, document - is one\n * of three variants:\n *\n * - `url` : a remote address (HTTP, GCS, etc.). The model fetches it.\n * `mimeType` is optional - servers usually set Content-Type.\n * Some providers (Gemini `fileData`) want it explicit.\n *\n * - `base64` : an inline base64-encoded payload. Always carries a\n * `mimeType` so the consumer knows how to decode.\n *\n * - `bytes` : raw `Uint8Array`. Provider layers normalize to base64 or\n * multipart upload at the wire boundary - users don't need\n * to encode themselves.\n *\n * Per-modality files (`Image.ts`, future `Audio.ts` / `Video.ts` /\n * `Document.ts`) instantiate this shape with their typed MIME union to\n * get autocomplete on common formats while keeping the structural type\n * uniform across modalities.\n *\n * Streaming media (live mic feed, streaming TTS playback) is *not*\n * modeled here. Streams carry effect parameters (`Stream<A, E, R>`) and\n * lifecycle (Scope, cancellation) that don't apply to media at rest. The\n * complementary type lives alongside this one as `*Stream` in each\n * per-modality file when those modalities land.\n *\n * Provider-uploaded asset references (OpenAI Files `file_id`, Gemini\n * Files API URIs, Anthropic file IDs) are also out of scope here -\n * they're a separate union (`FileRef`) added when needed.\n */\n\nimport { Result } from \"effect\"\n\n/**\n * Watermark kind a provider embedded in generated media. Shared across\n * modalities (audio, image). No provider exposes metadata beyond the\n * kind, so a bare literal union is enough.\n */\nexport type Watermark = \"synthid\" | \"c2pa\" | (string & {})\n\n/**\n * Requested shape of generated visual media, width to height. Shared by\n * image and video generation: the listed ratios are the ones providers\n * accept as literals, and the `(string & {})` tail keeps a\n * newly-supported ratio working without an SDK update. Which ratios a\n * given model accepts is not checked here; the provider rejects what it\n * cannot render and the adapter translates that error.\n *\n * Resolution is NOT shared: image models tier by short edge\n * (`ImageResolution`), video models by scan height. Each modality types\n * its own.\n */\nexport type AspectRatio =\n | \"1:1\"\n | \"2:3\"\n | \"3:2\"\n | \"3:4\"\n | \"4:3\"\n | \"4:5\"\n | \"5:4\"\n | \"9:16\"\n | \"16:9\"\n | \"21:9\"\n | \"1:4\"\n | \"4:1\"\n | \"1:8\"\n | \"8:1\"\n | (string & {})\n\n/** Exact pixels, for adapters whose wire takes dimensions rather than a ratio. */\nexport type Dimensions = {\n readonly width: number\n readonly height: number\n}\n\nconst positive = (n: number | undefined): n is number =>\n n !== undefined && Number.isFinite(n) && n > 0\n\n/**\n * Read `\"W:H\"` as a pair. Fails when the ratio is not arithmetic, which\n * the `(string & {})` tail on {@link AspectRatio} lets through: a caller\n * asking for `\"cinematic\"` gets a message rather than NaN pixels. The\n * failure is a plain string so this file stays free of provider\n * vocabulary; each adapter wraps it in its own error.\n */\nexport const parseAspectRatio = (\n ratio: AspectRatio,\n): Result.Result<readonly [number, number], string> => {\n const [w, h, ...rest] = ratio.split(\":\").map(Number)\n return positive(w) && positive(h) && rest.length === 0\n ? Result.succeed([w, h] as const)\n : Result.fail(`aspectRatio \"${ratio}\" must read \"W:H\" with positive numbers.`)\n}\n\n/** Several image endpoints require both edges to be multiples of 16. */\nexport const round16 = (n: number): number => Math.max(16, Math.round(n / 16) * 16)\n\nexport type MediaUrl<M extends string = string> = {\n readonly _tag: \"url\"\n readonly url: string\n readonly mimeType?: M\n}\n\nexport type MediaBase64<M extends string = string> = {\n readonly _tag: \"base64\"\n readonly base64: string\n readonly mimeType: M\n}\n\nexport type MediaBytes<M extends string = string> = {\n readonly _tag: \"bytes\"\n readonly bytes: Uint8Array\n readonly mimeType: M\n}\n\nexport type MediaSource<M extends string = string> = MediaUrl<M> | MediaBase64<M> | MediaBytes<M>\n\nexport const isMediaUrl = <M extends string>(s: MediaSource<M>): s is MediaUrl<M> =>\n s._tag === \"url\"\n\nexport const isMediaBase64 = <M extends string>(s: MediaSource<M>): s is MediaBase64<M> =>\n s._tag === \"base64\"\n\nexport const isMediaBytes = <M extends string>(s: MediaSource<M>): s is MediaBytes<M> =>\n s._tag === \"bytes\"\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6EA,MAAM,YAAY,MAChB,MAAM,KAAA,KAAa,OAAO,SAAS,CAAC,KAAK,IAAI;;;;;;;;AAS/C,MAAa,oBACX,UACqD;CACrD,MAAM,CAAC,GAAG,GAAG,GAAG,QAAQ,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,MAAM;CACnD,OAAO,SAAS,CAAC,KAAK,SAAS,CAAC,KAAK,KAAK,WAAW,IACjD,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAU,IAC9B,OAAO,KAAK,gBAAgB,MAAM,yCAAyC;AACjF;;AAGA,MAAa,WAAW,MAAsB,KAAK,IAAI,IAAI,KAAK,MAAM,IAAI,EAAE,IAAI,EAAE;AAsBlF,MAAa,cAAgC,MAC3C,EAAE,SAAS;AAEb,MAAa,iBAAmC,MAC9C,EAAE,SAAS;AAEb,MAAa,gBAAkC,MAC7C,EAAE,SAAS"}
|
package/dist/domain/Music.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { c as Watermark } from "../Media-BbX7BAaO.mjs";
|
|
2
|
+
import { n as AudioChunk, r as AudioFormat, t as AudioBlob } from "../Audio-_nGR4V0X.mjs";
|
|
2
3
|
import { Duration } from "effect";
|
|
3
4
|
declare namespace Music_d_exports {
|
|
4
5
|
export { CommonGenerateMusicRequest, CommonStreamGenerateMusicRequest, GenerateResult, MusicResult, MusicSection, MusicSessionControl, MusicSessionInput, MusicStreamEvent, Watermark, WeightedPrompt, audioEvent, controlInput, filteredPromptEvent, isAudioEvent, isControlInput, isFilteredPromptEvent, isPromptsInput, isWarningEvent, promptsInput, singleVariant, warningEvent };
|
|
@@ -86,12 +87,6 @@ type MusicSessionInput = {
|
|
|
86
87
|
};
|
|
87
88
|
declare const promptsInput: (prompts: ReadonlyArray<WeightedPrompt>) => MusicSessionInput;
|
|
88
89
|
declare const controlInput: (action: MusicSessionControl) => MusicSessionInput;
|
|
89
|
-
/**
|
|
90
|
-
* Watermark kind on the response. SynthID is mandatory on Lyria; C2PA
|
|
91
|
-
* is opt-in on ElevenLabs. No provider exposes additional metadata
|
|
92
|
-
* about the watermark itself, so a bare literal-union is enough.
|
|
93
|
-
*/
|
|
94
|
-
type Watermark = "synthid" | "c2pa" | (string & {});
|
|
95
90
|
/**
|
|
96
91
|
* Labelled section with absolute timing. Populated when the provider
|
|
97
92
|
* returns structured section metadata (Lyria text part, ElevenLabs
|
|
@@ -178,5 +173,5 @@ declare const isFilteredPromptEvent: (e: MusicStreamEvent) => e is MusicStreamEv
|
|
|
178
173
|
*/
|
|
179
174
|
declare const singleVariant: (result: MusicResult) => GenerateResult;
|
|
180
175
|
//#endregion
|
|
181
|
-
export { CommonGenerateMusicRequest, CommonStreamGenerateMusicRequest, GenerateResult, MusicResult, MusicSection, MusicSessionControl, MusicSessionInput, MusicStreamEvent, Watermark, WeightedPrompt, audioEvent, controlInput, filteredPromptEvent, isAudioEvent, isControlInput, isFilteredPromptEvent, isPromptsInput, isWarningEvent, promptsInput, singleVariant, Music_d_exports as t, warningEvent };
|
|
176
|
+
export { CommonGenerateMusicRequest, CommonStreamGenerateMusicRequest, GenerateResult, MusicResult, MusicSection, MusicSessionControl, MusicSessionInput, MusicStreamEvent, type Watermark, WeightedPrompt, audioEvent, controlInput, filteredPromptEvent, isAudioEvent, isControlInput, isFilteredPromptEvent, isPromptsInput, isWarningEvent, promptsInput, singleVariant, Music_d_exports as t, warningEvent };
|
|
182
177
|
//# sourceMappingURL=Music.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Music.d.mts","names":[],"sources":["../../src/domain/Music.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Music.d.mts","names":[],"sources":["../../src/domain/Music.ts"],"mappings":";;;;;;;;;;;;KAUY;WACD;;WAEA;;;;;;;;;;;;;KAcC;;WAED;;WAEA;;;;;;;;;WASA;;WAEA,WAAW,SAAS;;;;;;;WAOpB;;WAEA,eAAe;;;;;;KAOd,mCAAmC;;;;;;;;KASnC;;;;;;;;;;;;;;KAeA;WACG;WAA0B,SAAS,cAAc;;WACjD;WAA0B,QAAQ;;cAEpC,eAAY,SAAa,cAAc,oBAAkB;cAKzD,eAAY,QAAY,wBAAsB;;;;;;KAiB/C;WACD;WACA;WACA;;;;;;;KAQC;WACD,OAAO;;;;;;WAMP;;WAEA;;WAEA;;WAEA,WAAW,cAAc;;WAEzB,YAAY;;;;;;;;KASX;WACD,SAAS;WACT,UAAU,cAAc;;;;;;;;KASvB;WACG;WAAwB,OAAO;;WAC/B;WAA0B;;WAC1B;WAAiC;WAAyB;;cAE5D,iBAAc,GACtB,sBACF,KAAK;EAAsB;;cACjB,iBAAc,GACtB,sBACF,KAAK;EAAsB;;cAEjB,aAAU,OAAW,eAAa;cAClC,eAAY,oBAAsB;cAIlC,sBAAmB,gBAAkB,mBAAmB;cAMxD,eAAY,GAAO,qBAAmB,KAAK;EAAqB;;cAEhE,iBAAc,GAAO,qBAAmB,KAAK;EAAqB;;cAElE,wBAAqB,GAC7B,qBACF,KAAK;EAAqB;;;;;;;;;cAShB,gBAAa,QAAY,gBAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Music.mjs","names":[],"sources":["../../src/domain/Music.ts"],"sourcesContent":["import type { Duration } from \"effect\"\nimport type { AudioBlob, AudioChunk, AudioFormat } from \"./Audio.js\"\n\n/**\n * Prompt fragment with a relative weight. Native to Lyria RealTime\n * (`{ text, weight }` pairs blended in the model) and Riffusion compose.\n * Single-prompt providers (the majority) treat a 1-element array with\n * `weight: 1` as a plain prompt.\n */\nexport type WeightedPrompt = {\n readonly text: string\n /** Default `1.0`. Range typically `[0, 1]`; provider-dependent. */\n readonly weight?: number\n}\n\n/**\n * Cross-provider music-generation request. Trimmed to fields the\n * majority of music providers honor structurally; provider-specific\n * extras (Lyria `bpm` / `scale`, ElevenLabs `compositionPlan` /\n * `signWithC2pa`, Suno `style` / `personaId`, MiniMax `lyricsOptimizer`,\n * `instrumental` on providers that ship a wire toggle) live on each\n * provider's typed request which extends this and narrows `model`.\n *\n * Music providers are one-shot text-to-audio, not conversational. No\n * `messages[]` shape applies.\n */\nexport type CommonGenerateMusicRequest = {\n /** Model identifier. Each provider narrows. */\n readonly model: string\n /** Single prompt string. Weighted blends are provider-typed extras. */\n readonly prompt: string\n /**\n * Lyrics text, optionally with section tags like `[Verse]` /\n * `[Chorus]` / `[Bridge]` / `[Outro]`. Routed to a structured wire\n * field on providers that have one (ElevenLabs `lines`, MiniMax\n * `lyrics`, Mureka `lyrics`, Suno custom-mode `prompt`); embedded in\n * the prompt with a warning on providers without one (Lyria 3,\n * Riffusion).\n */\n readonly lyrics?: string\n /** Target duration. Provider may treat as a hint or hard limit. */\n readonly duration?: Duration.Duration\n /**\n * Reproducibility seed. Tuning hint (bucket 3): honored where the\n * provider takes one (Lyria 2 Vertex, Lyria RealTime, ElevenLabs\n * with `compositionPlan`, Stable Audio, MusicGen); silently ignored\n * elsewhere.\n */\n readonly seed?: number\n /** Preferred output format. Provider may override. */\n readonly outputFormat?: AudioFormat\n}\n\n/**\n * Streamed-output request. Same shape as the sync request: the\n * streaming variant only differs in how the response is delivered.\n */\nexport type CommonStreamGenerateMusicRequest = CommonGenerateMusicRequest\n\n/**\n * Playback-control vocabulary that converges across interactive-media\n * protocols (Web Audio, MIDI sequencer control, music SDK surfaces).\n * Provider-specific control actions (Lyria's `reset_context` and any\n * future provider's extras) live on the provider-typed session-input\n * union.\n */\nexport type MusicSessionControl = \"play\" | \"pause\" | \"stop\" | \"reset\"\n\n/**\n * Bidirectional-session input on the cross-provider surface. Two\n * load-bearing actions every interactive music session needs:\n *\n * - `prompts` — steer the active generation with a (single or\n * weighted) prompt blend.\n * - `control` — play / pause / stop / reset.\n *\n * Provider-typed services extend this union with their own `config`\n * variant for model-specific knobs (Lyria RealTime exposes density /\n * brightness / mute-stems / BPM / scale / etc. via its own\n * `LyriaRealtimeSessionInput`).\n */\nexport type MusicSessionInput =\n | { readonly _tag: \"prompts\"; readonly prompts: ReadonlyArray<WeightedPrompt> }\n | { readonly _tag: \"control\"; readonly action: MusicSessionControl }\n\nexport const promptsInput = (prompts: ReadonlyArray<WeightedPrompt>): MusicSessionInput => ({\n _tag: \"prompts\",\n prompts,\n})\n\nexport const controlInput = (action: MusicSessionControl): MusicSessionInput => ({\n _tag: \"control\",\n action,\n})\n\n/**\n * Watermark kind on the response. SynthID is mandatory on Lyria; C2PA\n * is opt-in on ElevenLabs.
|
|
1
|
+
{"version":3,"file":"Music.mjs","names":[],"sources":["../../src/domain/Music.ts"],"sourcesContent":["import type { Duration } from \"effect\"\nimport type { AudioBlob, AudioChunk, AudioFormat } from \"./Audio.js\"\nimport type { Watermark } from \"./Media.js\"\n\n/**\n * Prompt fragment with a relative weight. Native to Lyria RealTime\n * (`{ text, weight }` pairs blended in the model) and Riffusion compose.\n * Single-prompt providers (the majority) treat a 1-element array with\n * `weight: 1` as a plain prompt.\n */\nexport type WeightedPrompt = {\n readonly text: string\n /** Default `1.0`. Range typically `[0, 1]`; provider-dependent. */\n readonly weight?: number\n}\n\n/**\n * Cross-provider music-generation request. Trimmed to fields the\n * majority of music providers honor structurally; provider-specific\n * extras (Lyria `bpm` / `scale`, ElevenLabs `compositionPlan` /\n * `signWithC2pa`, Suno `style` / `personaId`, MiniMax `lyricsOptimizer`,\n * `instrumental` on providers that ship a wire toggle) live on each\n * provider's typed request which extends this and narrows `model`.\n *\n * Music providers are one-shot text-to-audio, not conversational. No\n * `messages[]` shape applies.\n */\nexport type CommonGenerateMusicRequest = {\n /** Model identifier. Each provider narrows. */\n readonly model: string\n /** Single prompt string. Weighted blends are provider-typed extras. */\n readonly prompt: string\n /**\n * Lyrics text, optionally with section tags like `[Verse]` /\n * `[Chorus]` / `[Bridge]` / `[Outro]`. Routed to a structured wire\n * field on providers that have one (ElevenLabs `lines`, MiniMax\n * `lyrics`, Mureka `lyrics`, Suno custom-mode `prompt`); embedded in\n * the prompt with a warning on providers without one (Lyria 3,\n * Riffusion).\n */\n readonly lyrics?: string\n /** Target duration. Provider may treat as a hint or hard limit. */\n readonly duration?: Duration.Duration\n /**\n * Reproducibility seed. Tuning hint (bucket 3): honored where the\n * provider takes one (Lyria 2 Vertex, Lyria RealTime, ElevenLabs\n * with `compositionPlan`, Stable Audio, MusicGen); silently ignored\n * elsewhere.\n */\n readonly seed?: number\n /** Preferred output format. Provider may override. */\n readonly outputFormat?: AudioFormat\n}\n\n/**\n * Streamed-output request. Same shape as the sync request: the\n * streaming variant only differs in how the response is delivered.\n */\nexport type CommonStreamGenerateMusicRequest = CommonGenerateMusicRequest\n\n/**\n * Playback-control vocabulary that converges across interactive-media\n * protocols (Web Audio, MIDI sequencer control, music SDK surfaces).\n * Provider-specific control actions (Lyria's `reset_context` and any\n * future provider's extras) live on the provider-typed session-input\n * union.\n */\nexport type MusicSessionControl = \"play\" | \"pause\" | \"stop\" | \"reset\"\n\n/**\n * Bidirectional-session input on the cross-provider surface. Two\n * load-bearing actions every interactive music session needs:\n *\n * - `prompts` — steer the active generation with a (single or\n * weighted) prompt blend.\n * - `control` — play / pause / stop / reset.\n *\n * Provider-typed services extend this union with their own `config`\n * variant for model-specific knobs (Lyria RealTime exposes density /\n * brightness / mute-stems / BPM / scale / etc. via its own\n * `LyriaRealtimeSessionInput`).\n */\nexport type MusicSessionInput =\n | { readonly _tag: \"prompts\"; readonly prompts: ReadonlyArray<WeightedPrompt> }\n | { readonly _tag: \"control\"; readonly action: MusicSessionControl }\n\nexport const promptsInput = (prompts: ReadonlyArray<WeightedPrompt>): MusicSessionInput => ({\n _tag: \"prompts\",\n prompts,\n})\n\nexport const controlInput = (action: MusicSessionControl): MusicSessionInput => ({\n _tag: \"control\",\n action,\n})\n\n/**\n * Watermark kind on the response. SynthID is mandatory on Lyria; C2PA\n * is opt-in on ElevenLabs. Lives in `Media.ts` since image providers\n * report the same kinds; re-exported here unchanged.\n */\nexport type { Watermark } from \"./Media.js\"\n\n/**\n * Labelled section with absolute timing. Populated when the provider\n * returns structured section metadata (Lyria text part, ElevenLabs\n * `/v1/music/detailed` with `with_timestamps`).\n */\nexport type MusicSection = {\n readonly label: string\n readonly startSeconds: number\n readonly endSeconds: number\n}\n\n/**\n * Single generated track. Composes `AudioBlob` rather than extending\n * it — `result.audio` is the raw blob, `result.songId` / `lyrics` /\n * `sections` / `watermark` are provider-side metadata when returned.\n */\nexport type MusicResult = {\n readonly audio: AudioBlob\n /**\n * Provider identifier, useful when routing through multiple\n * providers in a single pipeline (`\"lyria\"`, `\"elevenlabs-music\"`,\n * etc.).\n */\n readonly provider?: string\n /** Provider-side ID for back-reference (re-download, extension, stems). */\n readonly songId?: string\n /** Generated or transcribed lyrics when the provider returned them. */\n readonly lyrics?: string\n /** Structured section markers when the provider returned them. */\n readonly sections?: ReadonlyArray<MusicSection>\n /** Watermark presence indicator when the provider applied one. */\n readonly watermark?: Watermark\n}\n\n/**\n * Result of a `generate` call. Suno and Mureka always return 2 tracks\n * per request; every other provider returns 1. `primary` is the\n * caller-friendly convenience; `variants` carries every track the\n * provider produced (length ≥ 1; `primary === variants[0]`).\n */\nexport type GenerateResult = {\n readonly primary: MusicResult\n readonly variants: ReadonlyArray<MusicResult>\n}\n\n/**\n * In-band event on the bidirectional `streamGenerationFrom` output\n * stream. Audio chunks flow as `audio`; server-side warnings\n * (`warning`) and prompt-filter rejections (`filteredPrompt`) flow\n * alongside rather than going to a side-channel log.\n */\nexport type MusicStreamEvent =\n | { readonly _tag: \"audio\"; readonly chunk: AudioChunk }\n | { readonly _tag: \"warning\"; readonly message: string }\n | { readonly _tag: \"filteredPrompt\"; readonly prompt: string; readonly reason: string }\n\nexport const isPromptsInput = (\n i: MusicSessionInput,\n): i is MusicSessionInput & { _tag: \"prompts\" } => i._tag === \"prompts\"\nexport const isControlInput = (\n i: MusicSessionInput,\n): i is MusicSessionInput & { _tag: \"control\" } => i._tag === \"control\"\n\nexport const audioEvent = (chunk: AudioChunk): MusicStreamEvent => ({ _tag: \"audio\", chunk })\nexport const warningEvent = (message: string): MusicStreamEvent => ({\n _tag: \"warning\",\n message,\n})\nexport const filteredPromptEvent = (prompt: string, reason: string): MusicStreamEvent => ({\n _tag: \"filteredPrompt\",\n prompt,\n reason,\n})\n\nexport const isAudioEvent = (e: MusicStreamEvent): e is MusicStreamEvent & { _tag: \"audio\" } =>\n e._tag === \"audio\"\nexport const isWarningEvent = (e: MusicStreamEvent): e is MusicStreamEvent & { _tag: \"warning\" } =>\n e._tag === \"warning\"\nexport const isFilteredPromptEvent = (\n e: MusicStreamEvent,\n): e is MusicStreamEvent & { _tag: \"filteredPrompt\" } => e._tag === \"filteredPrompt\"\n\n/**\n * Build a single-variant `GenerateResult` from a `MusicResult`.\n * Convenience for providers that always return exactly one track\n * (Lyria, ElevenLabs, MiniMax, Stable Audio, MusicGen, Riffusion,\n * Tencent). Providers that return multiple tracks (Suno, Mureka)\n * construct the `GenerateResult` directly.\n */\nexport const singleVariant = (result: MusicResult): GenerateResult => ({\n primary: result,\n variants: [result],\n})\n"],"mappings":";;;;;;;;;;;;;;;AAsFA,MAAa,gBAAgB,aAA+D;CAC1F,MAAM;CACN;AACF;AAEA,MAAa,gBAAgB,YAAoD;CAC/E,MAAM;CACN;AACF;AAiEA,MAAa,kBACX,MACiD,EAAE,SAAS;AAC9D,MAAa,kBACX,MACiD,EAAE,SAAS;AAE9D,MAAa,cAAc,WAAyC;CAAE,MAAM;CAAS;AAAM;AAC3F,MAAa,gBAAgB,aAAuC;CAClE,MAAM;CACN;AACF;AACA,MAAa,uBAAuB,QAAgB,YAAsC;CACxF,MAAM;CACN;CACA;AACF;AAEA,MAAa,gBAAgB,MAC3B,EAAE,SAAS;AACb,MAAa,kBAAkB,MAC7B,EAAE,SAAS;AACb,MAAa,yBACX,MACuD,EAAE,SAAS;;;;;;;;AASpE,MAAa,iBAAiB,YAAyC;CACrE,SAAS;CACT,UAAU,CAAC,MAAM;AACnB"}
|
package/dist/domain/Turn.d.mts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { o as ImageSource } from "../Image-Cv6iBLTy.mjs";
|
|
2
|
+
import { S as Usage, b as ToolCallOutput, d as Message, h as Reasoning, o as HistoryItem, t as Annotation, y as ToolCall } from "../Items-C7MyrYPX.mjs";
|
|
3
3
|
import { i as StructuredFormat, n as JsonParseError, r as StructuredDecodeError } from "../StructuredFormat-BlZhyOsi.mjs";
|
|
4
4
|
import { Data, Effect, Schema, Stream } from "effect";
|
|
5
5
|
declare namespace Turn_d_exports {
|
|
6
|
-
export { InteractionEvent, RefusalRejected, Turn, TurnEvent, appendToHistory, assistantMessages, assistantText, assistantTexts, citations, decodeStructured, getToolCalls, isTurnComplete, reasonings, textDeltas };
|
|
6
|
+
export { InteractionEvent, RefusalRejected, Turn, TurnEvent, appendToHistory, assistantImages, assistantMessages, assistantText, assistantTexts, citations, decodeStructured, getToolCalls, imagesAsInput, isTurnComplete, reasonings, textDeltas };
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
9
|
* The result of a single LLM generation. A turn produces zero or more items
|
|
@@ -46,6 +46,9 @@ declare const Turn: Schema.Struct<{
|
|
|
46
46
|
readonly file_id: Schema.String;
|
|
47
47
|
readonly index: Schema.Number;
|
|
48
48
|
}>]>>>;
|
|
49
|
+
}>, Schema.Struct<{
|
|
50
|
+
readonly type: Schema.Literal<"output_image">;
|
|
51
|
+
readonly source: Schema.Schema<ImageSource>;
|
|
49
52
|
}>, Schema.Struct<{
|
|
50
53
|
readonly type: Schema.Literal<"refusal">;
|
|
51
54
|
readonly text: Schema.String;
|
|
@@ -106,6 +109,12 @@ type Turn = typeof Turn.Type;
|
|
|
106
109
|
* `WebSearchCall`: lifecycle of a provider-executed web search within the
|
|
107
110
|
* turn. Fires only when the turn grounds against search; absent otherwise.
|
|
108
111
|
*
|
|
112
|
+
* `ImageOutput`: an image the model produced, whether it drew it as part
|
|
113
|
+
* of its turn or reached a hosted tool for it. `partialIndex` marks a
|
|
114
|
+
* preview frame from providers that stream them; the finished image
|
|
115
|
+
* arrives without one and is also on `TurnComplete.turn` as an
|
|
116
|
+
* `OutputImage` block.
|
|
117
|
+
*
|
|
109
118
|
* `CitationAdded`: a citation attached to the answer, emitted incrementally
|
|
110
119
|
* where the provider streams citations. Providers that bundle citations emit
|
|
111
120
|
* none of these; their citations still arrive on `TurnComplete.turn`
|
|
@@ -138,6 +147,11 @@ type TurnEvent = Data.TaggedEnum<{
|
|
|
138
147
|
readonly query?: string;
|
|
139
148
|
readonly action?: "search" | "open_page" | "find_in_page";
|
|
140
149
|
};
|
|
150
|
+
ImageOutput: {
|
|
151
|
+
readonly image: ImageSource;
|
|
152
|
+
/** Set only on a preview frame, counting from 0. Absent means finished. */
|
|
153
|
+
readonly partialIndex?: number;
|
|
154
|
+
};
|
|
141
155
|
CitationAdded: {
|
|
142
156
|
readonly annotation: Annotation;
|
|
143
157
|
};
|
|
@@ -146,11 +160,17 @@ type TurnEvent = Data.TaggedEnum<{
|
|
|
146
160
|
};
|
|
147
161
|
}>;
|
|
148
162
|
declare const TurnEvent: {
|
|
149
|
-
readonly $is: <Tag extends "CitationAdded" | "ReasoningDelta" | "RefusalDelta" | "TextDelta" | "ToolCallArgsDelta" | "ToolCallStart" | "TurnComplete" | "UsageUpdate" | "WebSearchCall">(tag: Tag) => (u: unknown) => u is Extract<{
|
|
163
|
+
readonly $is: <Tag extends "CitationAdded" | "ImageOutput" | "ReasoningDelta" | "RefusalDelta" | "TextDelta" | "ToolCallArgsDelta" | "ToolCallStart" | "TurnComplete" | "UsageUpdate" | "WebSearchCall">(tag: Tag) => (u: unknown) => u is Extract<{
|
|
150
164
|
readonly _tag: "CitationAdded";
|
|
151
165
|
readonly annotation: Annotation;
|
|
152
166
|
}, {
|
|
153
167
|
readonly _tag: Tag;
|
|
168
|
+
}> | Extract<{
|
|
169
|
+
readonly _tag: "ImageOutput";
|
|
170
|
+
readonly image: ImageSource;
|
|
171
|
+
readonly partialIndex?: number;
|
|
172
|
+
}, {
|
|
173
|
+
readonly _tag: Tag;
|
|
154
174
|
}> | Extract<{
|
|
155
175
|
readonly _tag: "ReasoningDelta";
|
|
156
176
|
readonly text: string;
|
|
@@ -198,9 +218,13 @@ declare const TurnEvent: {
|
|
|
198
218
|
readonly _tag: Tag;
|
|
199
219
|
}>;
|
|
200
220
|
readonly $match: {
|
|
201
|
-
<Cases extends { readonly [Tag in "CitationAdded" | "ReasoningDelta" | "RefusalDelta" | "TextDelta" | "ToolCallArgsDelta" | "ToolCallStart" | "TurnComplete" | "UsageUpdate" | "WebSearchCall"]: (args: Extract<{
|
|
221
|
+
<Cases extends { readonly [Tag in "CitationAdded" | "ImageOutput" | "ReasoningDelta" | "RefusalDelta" | "TextDelta" | "ToolCallArgsDelta" | "ToolCallStart" | "TurnComplete" | "UsageUpdate" | "WebSearchCall"]: (args: Extract<{
|
|
202
222
|
readonly _tag: "CitationAdded";
|
|
203
223
|
readonly annotation: Annotation;
|
|
224
|
+
} | {
|
|
225
|
+
readonly _tag: "ImageOutput";
|
|
226
|
+
readonly image: ImageSource;
|
|
227
|
+
readonly partialIndex?: number;
|
|
204
228
|
} | {
|
|
205
229
|
readonly _tag: "ReasoningDelta";
|
|
206
230
|
readonly text: string;
|
|
@@ -235,6 +259,10 @@ declare const TurnEvent: {
|
|
|
235
259
|
}>) => any; }>(cases: Cases): (value: {
|
|
236
260
|
readonly _tag: "CitationAdded";
|
|
237
261
|
readonly annotation: Annotation;
|
|
262
|
+
} | {
|
|
263
|
+
readonly _tag: "ImageOutput";
|
|
264
|
+
readonly image: ImageSource;
|
|
265
|
+
readonly partialIndex?: number;
|
|
238
266
|
} | {
|
|
239
267
|
readonly _tag: "ReasoningDelta";
|
|
240
268
|
readonly text: string;
|
|
@@ -264,10 +292,14 @@ declare const TurnEvent: {
|
|
|
264
292
|
readonly status: "started" | "searching" | "completed";
|
|
265
293
|
readonly query?: string;
|
|
266
294
|
readonly action?: "search" | "open_page" | "find_in_page";
|
|
267
|
-
}) => import("effect/Unify").Unify<ReturnType<Cases["CitationAdded" | "ReasoningDelta" | "RefusalDelta" | "TextDelta" | "ToolCallArgsDelta" | "ToolCallStart" | "TurnComplete" | "UsageUpdate" | "WebSearchCall"]>>;
|
|
268
|
-
<Cases extends { readonly [Tag in "CitationAdded" | "ReasoningDelta" | "RefusalDelta" | "TextDelta" | "ToolCallArgsDelta" | "ToolCallStart" | "TurnComplete" | "UsageUpdate" | "WebSearchCall"]: (args: Extract<{
|
|
295
|
+
}) => import("effect/Unify").Unify<ReturnType<Cases["CitationAdded" | "ImageOutput" | "ReasoningDelta" | "RefusalDelta" | "TextDelta" | "ToolCallArgsDelta" | "ToolCallStart" | "TurnComplete" | "UsageUpdate" | "WebSearchCall"]>>;
|
|
296
|
+
<Cases extends { readonly [Tag in "CitationAdded" | "ImageOutput" | "ReasoningDelta" | "RefusalDelta" | "TextDelta" | "ToolCallArgsDelta" | "ToolCallStart" | "TurnComplete" | "UsageUpdate" | "WebSearchCall"]: (args: Extract<{
|
|
269
297
|
readonly _tag: "CitationAdded";
|
|
270
298
|
readonly annotation: Annotation;
|
|
299
|
+
} | {
|
|
300
|
+
readonly _tag: "ImageOutput";
|
|
301
|
+
readonly image: ImageSource;
|
|
302
|
+
readonly partialIndex?: number;
|
|
271
303
|
} | {
|
|
272
304
|
readonly _tag: "ReasoningDelta";
|
|
273
305
|
readonly text: string;
|
|
@@ -302,6 +334,10 @@ declare const TurnEvent: {
|
|
|
302
334
|
}>) => any; }>(value: {
|
|
303
335
|
readonly _tag: "CitationAdded";
|
|
304
336
|
readonly annotation: Annotation;
|
|
337
|
+
} | {
|
|
338
|
+
readonly _tag: "ImageOutput";
|
|
339
|
+
readonly image: ImageSource;
|
|
340
|
+
readonly partialIndex?: number;
|
|
305
341
|
} | {
|
|
306
342
|
readonly _tag: "ReasoningDelta";
|
|
307
343
|
readonly text: string;
|
|
@@ -331,12 +367,17 @@ declare const TurnEvent: {
|
|
|
331
367
|
readonly status: "started" | "searching" | "completed";
|
|
332
368
|
readonly query?: string;
|
|
333
369
|
readonly action?: "search" | "open_page" | "find_in_page";
|
|
334
|
-
}, cases: Cases): import("effect/Unify").Unify<ReturnType<Cases["CitationAdded" | "ReasoningDelta" | "RefusalDelta" | "TextDelta" | "ToolCallArgsDelta" | "ToolCallStart" | "TurnComplete" | "UsageUpdate" | "WebSearchCall"]>>;
|
|
370
|
+
}, cases: Cases): import("effect/Unify").Unify<ReturnType<Cases["CitationAdded" | "ImageOutput" | "ReasoningDelta" | "RefusalDelta" | "TextDelta" | "ToolCallArgsDelta" | "ToolCallStart" | "TurnComplete" | "UsageUpdate" | "WebSearchCall"]>>;
|
|
335
371
|
};
|
|
336
372
|
readonly CitationAdded: Data.TaggedEnum.ConstructorFrom<{
|
|
337
373
|
readonly _tag: "CitationAdded";
|
|
338
374
|
readonly annotation: Annotation;
|
|
339
375
|
}, "_tag">;
|
|
376
|
+
readonly ImageOutput: Data.TaggedEnum.ConstructorFrom<{
|
|
377
|
+
readonly _tag: "ImageOutput";
|
|
378
|
+
readonly image: ImageSource;
|
|
379
|
+
readonly partialIndex?: number;
|
|
380
|
+
}, "_tag">;
|
|
340
381
|
readonly ReasoningDelta: Data.TaggedEnum.ConstructorFrom<{
|
|
341
382
|
readonly _tag: "ReasoningDelta";
|
|
342
383
|
readonly text: string;
|
|
@@ -403,6 +444,29 @@ declare const assistantTexts: (turn: Turn) => ReadonlyArray<string>;
|
|
|
403
444
|
* that want one concatenated string.
|
|
404
445
|
*/
|
|
405
446
|
declare const assistantText: (turn: Turn) => string;
|
|
447
|
+
/**
|
|
448
|
+
* Every image the model produced this turn, in order. The counterpart to
|
|
449
|
+
* {@link assistantTexts}: each is an `ImageSource`, so it can be written
|
|
450
|
+
* to disk or passed straight back as an `input_image` on the next turn.
|
|
451
|
+
*/
|
|
452
|
+
declare const assistantImages: (turn: Turn) => ReadonlyArray<ImageSource>;
|
|
453
|
+
/**
|
|
454
|
+
* Rewrite assistant `output_image` blocks into a user message carrying
|
|
455
|
+
* the same pictures as `input_image`, so another provider can look at
|
|
456
|
+
* what this one drew.
|
|
457
|
+
*
|
|
458
|
+
* Only Gemini's wire has an assistant-role image part; every other
|
|
459
|
+
* adapter omits an `output_image` on replay and says so. Moving it to a
|
|
460
|
+
* user message is the conversion that makes it portable, and it is
|
|
461
|
+
* yours to make rather than the adapter's: "the assistant drew this" and
|
|
462
|
+
* "here is an image, look at it" are different claims, and silently
|
|
463
|
+
* swapping one for the other behind your back would be the wrong kind of
|
|
464
|
+
* helpful.
|
|
465
|
+
*
|
|
466
|
+
* Items with no images pass through untouched, and the new user message
|
|
467
|
+
* follows the assistant message it came from.
|
|
468
|
+
*/
|
|
469
|
+
declare const imagesAsInput: (history: ReadonlyArray<HistoryItem>) => ReadonlyArray<HistoryItem>;
|
|
406
470
|
/**
|
|
407
471
|
* Every citation annotation attached to the turn's assistant `output_text`
|
|
408
472
|
* blocks, in order. The flat view of a grounded turn's sources, whether the
|
|
@@ -446,5 +510,5 @@ declare class RefusalRejected extends RefusalRejected_base<{
|
|
|
446
510
|
*/
|
|
447
511
|
declare const decodeStructured: <A>(turn: Turn, format: StructuredFormat<A>) => Effect.Effect<A, RefusalRejected | JsonParseError | StructuredDecodeError>;
|
|
448
512
|
//#endregion
|
|
449
|
-
export { InteractionEvent, RefusalRejected, Turn, TurnEvent, appendToHistory, assistantMessages, assistantText, assistantTexts, citations, decodeStructured, getToolCalls, isTurnComplete, reasonings, Turn_d_exports as t, textDeltas };
|
|
513
|
+
export { InteractionEvent, RefusalRejected, Turn, TurnEvent, appendToHistory, assistantImages, assistantMessages, assistantText, assistantTexts, citations, decodeStructured, getToolCalls, imagesAsInput, isTurnComplete, reasonings, Turn_d_exports as t, textDeltas };
|
|
450
514
|
//# 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":";;;;;;;;;;;;cAwBa,MAAI,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAKL,cAAc,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAmCnB,YAAY,KAAK;EAC3B;aAAsB;;EACtB;aAA2B;aAAuB;;EAClD;aAAyB;;EACzB;aAA0B;aAA0B;;EACpD;aAA8B;aAA0B;;EACxD;aAAwB,OAAO;;EAC/B;aACW;aACA;aACA;;EAEX;aACW,OAAO;;aAEP;;EAEX;aAA0B,YAAY;;EACtC;aAAyB,MAAM;;;cAGpB;;;aAJ2B,YAAA;;;;;aAJpB,OAAA;aAEQ;;;;;aAbO;aAAuB;;;;;aACzB;;;;;aAFH;;;;;aAIW;aAAwB;;;;;aAD5B;aAAuB;;;;;aAc3B,MAAA;;;;;aAZA,OAAA;;;;;aAEZ;aACA;aACC;;;;;;;eAOkB,YAAA;;;eAJpB,OAAA;eAEQ;;;eAbO;eAAuB;;;eACzB;;;eAFH;;;eAIW;eAAwB;;;eAD5B;eAAuB;;;eAc3B,MAAA;;;eAZA,OAAA;;;eAEZ;eACA;eACC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAOkB,YAAA;;;eAJpB,OAAA;eAEQ;;;eAbO;eAAuB;;;eACzB;;;eAFH;;;eAIW;eAAwB;;;eAD5B;eAAuB;;;eAc3B,MAAA;;;eAZA,OAAA;;;eAEZ;eACA;eACC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAOkB,YAAA;;;;aAJpB,OAAA;aAEQ;;;;aAbO;aAAuB;;;;aACzB;;;;aAFH;;;;aAIW;aAAwB;;;;aAD5B;aAAuB;;;;aAc3B,MAAA;;;;aAZA,OAAA;;;;aAEZ;aACA;aACC;;;;;;;;;KAmBV,mBAAmB,YAAY;cAE9B,iBAAc,eAAA;;WAbM,MAAA;;cAepB,eAAY,MAAU,SAAO,cAAc;cAE3C,aAAU,MAAU,SAAO,cAAc;cAEzC,oBAAiB,MAAU,SAAO,cAAc;;;;;;;;cAUhD,iBAAc,MAAU,SAAO;;;;;;cAW/B,gBAAa,MAAU;;;;;;cAOvB,kBAAe,MAAU,SAAO,cAAc;;;;;;;;;;;;;;;;;cAsB9C,gBAAa,SAAa,cAAc,iBAAe,cAAc;;;;;;cAqBrE,YAAS,MAAU,SAAO,cAAc;;;;;;cAWxC,kBAAmB;WAAqB,SAAS,cAAc;GAAc,OACjF,GAAC,MACF,MAAI,QACH,cAAc,iBACpB;;;;;;cAcU,aAAc,GAAG,GAAC,MACvB,OAAO,OAAO,WAAW,GAAG,OACjC,OAAO,eAAe,GAAG;;;;;;;;;cAcf,wBAAwB;WAC1B,MAAM;;;;;;;;;;;;cAyBJ,mBAAoB,GAAC,MAC1B,MAAI,QACF,iBAAkC,OACzC,OAAO,OACR,GACA,kBAAkB,iBAAkC"}
|
package/dist/domain/Turn.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as __exportAll } from "../rolldown-runtime-EAsCxrDo.mjs";
|
|
2
|
-
import { HistoryItem, StopReason, Usage, isOutputText, isReasoning, isRefusal, isToolCall } from "./Items.mjs";
|
|
2
|
+
import { HistoryItem, StopReason, Usage, isOutputImage, isOutputText, isReasoning, isRefusal, isToolCall } from "./Items.mjs";
|
|
3
3
|
import { parseJson } from "../structured-format/StructuredFormat.mjs";
|
|
4
4
|
import { Data, Effect, Result, Schema, Stream, pipe } from "effect";
|
|
5
5
|
//#region src/domain/Turn.ts
|
|
@@ -8,12 +8,14 @@ var Turn_exports = /* @__PURE__ */ __exportAll({
|
|
|
8
8
|
Turn: () => Turn,
|
|
9
9
|
TurnEvent: () => TurnEvent,
|
|
10
10
|
appendToHistory: () => appendToHistory,
|
|
11
|
+
assistantImages: () => assistantImages,
|
|
11
12
|
assistantMessages: () => assistantMessages,
|
|
12
13
|
assistantText: () => assistantText,
|
|
13
14
|
assistantTexts: () => assistantTexts,
|
|
14
15
|
citations: () => citations,
|
|
15
16
|
decodeStructured: () => decodeStructured,
|
|
16
17
|
getToolCalls: () => getToolCalls,
|
|
18
|
+
imagesAsInput: () => imagesAsInput,
|
|
17
19
|
isTurnComplete: () => isTurnComplete,
|
|
18
20
|
reasonings: () => reasonings,
|
|
19
21
|
textDeltas: () => textDeltas
|
|
@@ -48,6 +50,40 @@ const assistantTexts = (turn) => assistantMessages(turn).flatMap((m) => m.conten
|
|
|
48
50
|
*/
|
|
49
51
|
const assistantText = (turn) => assistantTexts(turn).join("");
|
|
50
52
|
/**
|
|
53
|
+
* Every image the model produced this turn, in order. The counterpart to
|
|
54
|
+
* {@link assistantTexts}: each is an `ImageSource`, so it can be written
|
|
55
|
+
* to disk or passed straight back as an `input_image` on the next turn.
|
|
56
|
+
*/
|
|
57
|
+
const assistantImages = (turn) => assistantMessages(turn).flatMap((m) => m.content).filter(isOutputImage).map((b) => b.source);
|
|
58
|
+
/**
|
|
59
|
+
* Rewrite assistant `output_image` blocks into a user message carrying
|
|
60
|
+
* the same pictures as `input_image`, so another provider can look at
|
|
61
|
+
* what this one drew.
|
|
62
|
+
*
|
|
63
|
+
* Only Gemini's wire has an assistant-role image part; every other
|
|
64
|
+
* adapter omits an `output_image` on replay and says so. Moving it to a
|
|
65
|
+
* user message is the conversion that makes it portable, and it is
|
|
66
|
+
* yours to make rather than the adapter's: "the assistant drew this" and
|
|
67
|
+
* "here is an image, look at it" are different claims, and silently
|
|
68
|
+
* swapping one for the other behind your back would be the wrong kind of
|
|
69
|
+
* helpful.
|
|
70
|
+
*
|
|
71
|
+
* Items with no images pass through untouched, and the new user message
|
|
72
|
+
* follows the assistant message it came from.
|
|
73
|
+
*/
|
|
74
|
+
const imagesAsInput = (history) => history.flatMap((item) => {
|
|
75
|
+
if (item.type !== "message" || item.role !== "assistant") return [item];
|
|
76
|
+
const images = item.content.filter(isOutputImage);
|
|
77
|
+
return images.length === 0 ? [item] : [item, {
|
|
78
|
+
type: "message",
|
|
79
|
+
role: "user",
|
|
80
|
+
content: images.map((b) => ({
|
|
81
|
+
type: "input_image",
|
|
82
|
+
source: b.source
|
|
83
|
+
}))
|
|
84
|
+
}];
|
|
85
|
+
});
|
|
86
|
+
/**
|
|
51
87
|
* Every citation annotation attached to the turn's assistant `output_text`
|
|
52
88
|
* blocks, in order. The flat view of a grounded turn's sources, whether the
|
|
53
89
|
* turn came from a normal generation with native search or a deep-research job.
|
|
@@ -106,6 +142,6 @@ const lastAssistantContent = (turn) => {
|
|
|
106
142
|
*/
|
|
107
143
|
const decodeStructured = (turn, format) => pipe(lastAssistantContent(turn), ({ text, refused }) => refused ? Effect.fail(new RefusalRejected({ turn })) : parseJson(format)(text));
|
|
108
144
|
//#endregion
|
|
109
|
-
export { RefusalRejected, Turn, TurnEvent, appendToHistory, assistantMessages, assistantText, assistantTexts, citations, decodeStructured, getToolCalls, isTurnComplete, reasonings, Turn_exports as t, textDeltas };
|
|
145
|
+
export { RefusalRejected, Turn, TurnEvent, appendToHistory, assistantImages, assistantMessages, assistantText, assistantTexts, citations, decodeStructured, getToolCalls, imagesAsInput, isTurnComplete, reasonings, Turn_exports as t, textDeltas };
|
|
110
146
|
|
|
111
147
|
//# sourceMappingURL=Turn.mjs.map
|