@effect-uai/core 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{AiError-CqmYjXyx.d.mts → AiError-csR8Bhxx.d.mts} +26 -4
- package/dist/{AiError-CqmYjXyx.d.mts.map → AiError-csR8Bhxx.d.mts.map} +1 -1
- package/dist/Audio-BfCTGnH3.d.mts +61 -0
- package/dist/Audio-BfCTGnH3.d.mts.map +1 -0
- package/dist/Image-DxyXqzAM.d.mts +61 -0
- package/dist/Image-DxyXqzAM.d.mts.map +1 -0
- package/dist/{Items-D1C2686t.d.mts → Items-Hg5AsYxl.d.mts} +132 -80
- package/dist/Items-Hg5AsYxl.d.mts.map +1 -0
- package/dist/Media-D_CpcM1Z.d.mts +57 -0
- package/dist/Media-D_CpcM1Z.d.mts.map +1 -0
- package/dist/{StructuredFormat-B5ueioNr.d.mts → StructuredFormat-Cl41C56K.d.mts} +5 -5
- package/dist/StructuredFormat-Cl41C56K.d.mts.map +1 -0
- package/dist/{Tool-5wxOCuOh.d.mts → Tool-B8B5qVEy.d.mts} +13 -13
- package/dist/Tool-B8B5qVEy.d.mts.map +1 -0
- package/dist/{Turn-Bi83du4I.d.mts → Turn-7geUcKsf.d.mts} +5 -11
- package/dist/Turn-7geUcKsf.d.mts.map +1 -0
- package/dist/{chunk-CfYAbeIz.mjs → chunk-uyGKjUfl.mjs} +2 -1
- package/dist/dist-DV5ISja1.mjs +13782 -0
- package/dist/dist-DV5ISja1.mjs.map +1 -0
- package/dist/domain/AiError.d.mts +2 -2
- package/dist/domain/AiError.mjs +19 -3
- package/dist/domain/AiError.mjs.map +1 -1
- package/dist/domain/Audio.d.mts +2 -0
- package/dist/domain/Audio.mjs +14 -0
- package/dist/domain/Audio.mjs.map +1 -0
- package/dist/domain/Image.d.mts +2 -0
- package/dist/domain/Image.mjs +58 -0
- package/dist/domain/Image.mjs.map +1 -0
- package/dist/domain/Items.d.mts +2 -2
- package/dist/domain/Items.mjs +19 -42
- package/dist/domain/Items.mjs.map +1 -1
- package/dist/domain/Media.d.mts +2 -0
- package/dist/domain/Media.mjs +14 -0
- package/dist/domain/Media.mjs.map +1 -0
- package/dist/domain/Music.d.mts +116 -0
- package/dist/domain/Music.d.mts.map +1 -0
- package/dist/domain/Music.mjs +29 -0
- package/dist/domain/Music.mjs.map +1 -0
- package/dist/domain/Transcript.d.mts +95 -0
- package/dist/domain/Transcript.d.mts.map +1 -0
- package/dist/domain/Transcript.mjs +22 -0
- package/dist/domain/Transcript.mjs.map +1 -0
- package/dist/domain/Turn.d.mts +1 -1
- package/dist/domain/Turn.mjs +1 -1
- package/dist/embedding-model/Embedding.d.mts +107 -0
- package/dist/embedding-model/Embedding.d.mts.map +1 -0
- package/dist/embedding-model/Embedding.mjs +18 -0
- package/dist/embedding-model/Embedding.mjs.map +1 -0
- package/dist/embedding-model/EmbeddingModel.d.mts +97 -0
- package/dist/embedding-model/EmbeddingModel.d.mts.map +1 -0
- package/dist/embedding-model/EmbeddingModel.mjs +17 -0
- package/dist/embedding-model/EmbeddingModel.mjs.map +1 -0
- package/dist/index.d.mts +21 -7
- package/dist/index.mjs +16 -2
- package/dist/language-model/LanguageModel.d.mts +12 -20
- package/dist/language-model/LanguageModel.d.mts.map +1 -1
- package/dist/language-model/LanguageModel.mjs +3 -20
- package/dist/language-model/LanguageModel.mjs.map +1 -1
- package/dist/loop/Loop.d.mts +31 -7
- package/dist/loop/Loop.d.mts.map +1 -1
- package/dist/loop/Loop.mjs +39 -6
- package/dist/loop/Loop.mjs.map +1 -1
- package/dist/loop/Loop.test.d.mts +1 -0
- package/dist/loop/Loop.test.mjs +411 -0
- package/dist/loop/Loop.test.mjs.map +1 -0
- package/dist/magic-string.es-BgIV5Mu3.mjs +1013 -0
- package/dist/magic-string.es-BgIV5Mu3.mjs.map +1 -0
- package/dist/math/Vector.d.mts +47 -0
- package/dist/math/Vector.d.mts.map +1 -0
- package/dist/math/Vector.mjs +117 -0
- package/dist/math/Vector.mjs.map +1 -0
- package/dist/music-generator/MusicGenerator.d.mts +77 -0
- package/dist/music-generator/MusicGenerator.d.mts.map +1 -0
- package/dist/music-generator/MusicGenerator.mjs +51 -0
- package/dist/music-generator/MusicGenerator.mjs.map +1 -0
- package/dist/music-generator/MusicGenerator.test.d.mts +1 -0
- package/dist/music-generator/MusicGenerator.test.mjs +154 -0
- package/dist/music-generator/MusicGenerator.test.mjs.map +1 -0
- package/dist/observability/Metrics.d.mts +2 -2
- package/dist/observability/Metrics.d.mts.map +1 -1
- package/dist/observability/Metrics.mjs +1 -1
- package/dist/observability/Metrics.mjs.map +1 -1
- package/dist/speech-synthesizer/SpeechSynthesizer.d.mts +96 -0
- package/dist/speech-synthesizer/SpeechSynthesizer.d.mts.map +1 -0
- package/dist/speech-synthesizer/SpeechSynthesizer.mjs +48 -0
- package/dist/speech-synthesizer/SpeechSynthesizer.mjs.map +1 -0
- package/dist/speech-synthesizer/SpeechSynthesizer.test.d.mts +1 -0
- package/dist/speech-synthesizer/SpeechSynthesizer.test.mjs +112 -0
- package/dist/speech-synthesizer/SpeechSynthesizer.test.mjs.map +1 -0
- package/dist/streaming/JSONL.d.mts +10 -3
- package/dist/streaming/JSONL.d.mts.map +1 -1
- package/dist/streaming/JSONL.mjs +13 -2
- package/dist/streaming/JSONL.mjs.map +1 -1
- package/dist/streaming/JSONL.test.d.mts +1 -0
- package/dist/streaming/JSONL.test.mjs +70 -0
- package/dist/streaming/JSONL.test.mjs.map +1 -0
- package/dist/streaming/Lines.mjs +1 -1
- package/dist/streaming/SSE.d.mts +2 -2
- package/dist/streaming/SSE.d.mts.map +1 -1
- package/dist/streaming/SSE.mjs +1 -1
- package/dist/streaming/SSE.mjs.map +1 -1
- package/dist/streaming/SSE.test.d.mts +1 -0
- package/dist/streaming/SSE.test.mjs +72 -0
- package/dist/streaming/SSE.test.mjs.map +1 -0
- package/dist/structured-format/StructuredFormat.d.mts +1 -1
- package/dist/structured-format/StructuredFormat.mjs +1 -1
- package/dist/structured-format/StructuredFormat.mjs.map +1 -1
- package/dist/testing/MockMusicGenerator.d.mts +39 -0
- package/dist/testing/MockMusicGenerator.d.mts.map +1 -0
- package/dist/testing/MockMusicGenerator.mjs +96 -0
- package/dist/testing/MockMusicGenerator.mjs.map +1 -0
- package/dist/testing/MockProvider.d.mts +6 -6
- package/dist/testing/MockProvider.d.mts.map +1 -1
- package/dist/testing/MockProvider.mjs.map +1 -1
- package/dist/testing/MockSpeechSynthesizer.d.mts +37 -0
- package/dist/testing/MockSpeechSynthesizer.d.mts.map +1 -0
- package/dist/testing/MockSpeechSynthesizer.mjs +95 -0
- package/dist/testing/MockSpeechSynthesizer.mjs.map +1 -0
- package/dist/testing/MockTranscriber.d.mts +37 -0
- package/dist/testing/MockTranscriber.d.mts.map +1 -0
- package/dist/testing/MockTranscriber.mjs +77 -0
- package/dist/testing/MockTranscriber.mjs.map +1 -0
- package/dist/tool/HistoryCheck.d.mts +6 -3
- package/dist/tool/HistoryCheck.d.mts.map +1 -1
- package/dist/tool/HistoryCheck.mjs +7 -1
- package/dist/tool/HistoryCheck.mjs.map +1 -1
- package/dist/tool/Outcome.d.mts +138 -2
- package/dist/tool/Outcome.d.mts.map +1 -0
- package/dist/tool/Outcome.mjs +32 -10
- package/dist/tool/Outcome.mjs.map +1 -1
- package/dist/tool/Resolvers.d.mts +11 -8
- package/dist/tool/Resolvers.d.mts.map +1 -1
- package/dist/tool/Resolvers.mjs +10 -1
- package/dist/tool/Resolvers.mjs.map +1 -1
- package/dist/tool/Resolvers.test.d.mts +1 -0
- package/dist/tool/Resolvers.test.mjs +317 -0
- package/dist/tool/Resolvers.test.mjs.map +1 -0
- package/dist/tool/Tool.d.mts +1 -1
- package/dist/tool/Tool.mjs +1 -1
- package/dist/tool/Tool.mjs.map +1 -1
- package/dist/tool/ToolEvent.d.mts +151 -2
- package/dist/tool/ToolEvent.d.mts.map +1 -0
- package/dist/tool/ToolEvent.mjs +30 -4
- package/dist/tool/ToolEvent.mjs.map +1 -1
- package/dist/tool/Toolkit.d.mts +19 -10
- package/dist/tool/Toolkit.d.mts.map +1 -1
- package/dist/tool/Toolkit.mjs +5 -5
- package/dist/tool/Toolkit.mjs.map +1 -1
- package/dist/tool/Toolkit.test.d.mts +1 -0
- package/dist/tool/Toolkit.test.mjs +113 -0
- package/dist/tool/Toolkit.test.mjs.map +1 -0
- package/dist/transcriber/Transcriber.d.mts +101 -0
- package/dist/transcriber/Transcriber.d.mts.map +1 -0
- package/dist/transcriber/Transcriber.mjs +49 -0
- package/dist/transcriber/Transcriber.mjs.map +1 -0
- package/dist/transcriber/Transcriber.test.d.mts +1 -0
- package/dist/transcriber/Transcriber.test.mjs +130 -0
- package/dist/transcriber/Transcriber.test.mjs.map +1 -0
- package/package.json +65 -13
- package/src/domain/AiError.ts +21 -0
- package/src/domain/Audio.ts +88 -0
- package/src/domain/Image.ts +75 -0
- package/src/domain/Items.ts +18 -47
- package/src/domain/Media.ts +61 -0
- package/src/domain/Music.ts +121 -0
- package/src/domain/Transcript.ts +83 -0
- package/src/embedding-model/Embedding.ts +117 -0
- package/src/embedding-model/EmbeddingModel.ts +107 -0
- package/src/index.ts +15 -1
- package/src/language-model/LanguageModel.ts +2 -22
- package/src/loop/Loop.test.ts +114 -2
- package/src/loop/Loop.ts +69 -5
- package/src/math/Vector.ts +138 -0
- package/src/music-generator/MusicGenerator.test.ts +170 -0
- package/src/music-generator/MusicGenerator.ts +123 -0
- package/src/observability/Metrics.ts +1 -1
- package/src/speech-synthesizer/SpeechSynthesizer.test.ts +141 -0
- package/src/speech-synthesizer/SpeechSynthesizer.ts +131 -0
- package/src/streaming/JSONL.ts +12 -0
- package/src/streaming/SSE.ts +1 -1
- package/src/structured-format/StructuredFormat.ts +2 -2
- package/src/testing/MockMusicGenerator.ts +170 -0
- package/src/testing/MockProvider.ts +2 -2
- package/src/testing/MockSpeechSynthesizer.ts +165 -0
- package/src/testing/MockTranscriber.ts +139 -0
- package/src/tool/HistoryCheck.ts +2 -5
- package/src/tool/Outcome.ts +36 -36
- package/src/tool/Resolvers.test.ts +11 -35
- package/src/tool/Resolvers.ts +5 -14
- package/src/tool/Tool.ts +9 -9
- package/src/tool/ToolEvent.ts +28 -24
- package/src/tool/Toolkit.test.ts +97 -2
- package/src/tool/Toolkit.ts +57 -33
- package/src/transcriber/Transcriber.test.ts +125 -0
- package/src/transcriber/Transcriber.ts +127 -0
- package/dist/Items-D1C2686t.d.mts.map +0 -1
- package/dist/Outcome-GiaNvt7i.d.mts +0 -32
- package/dist/Outcome-GiaNvt7i.d.mts.map +0 -1
- package/dist/StructuredFormat-B5ueioNr.d.mts.map +0 -1
- package/dist/Tool-5wxOCuOh.d.mts.map +0 -1
- package/dist/ToolEvent-wTMgb2GO.d.mts +0 -29
- package/dist/ToolEvent-wTMgb2GO.d.mts.map +0 -1
- package/dist/Turn-Bi83du4I.d.mts.map +0 -1
- package/dist/match/Match.d.mts +0 -16
- package/dist/match/Match.d.mts.map +0 -1
- package/dist/match/Match.mjs +0 -15
- package/dist/match/Match.mjs.map +0 -1
- package/src/match/Match.ts +0 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect-uai/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Low-level primitives (loop, conversation, items, tools, streaming codecs) for building AI agents with Effect.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agents",
|
|
@@ -20,6 +20,12 @@
|
|
|
20
20
|
"url": "https://github.com/betalyra/effect-uai",
|
|
21
21
|
"directory": "packages/core"
|
|
22
22
|
},
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"src",
|
|
26
|
+
"README.md",
|
|
27
|
+
"LICENSE"
|
|
28
|
+
],
|
|
23
29
|
"type": "module",
|
|
24
30
|
"main": "./dist/index.mjs",
|
|
25
31
|
"types": "./dist/index.d.mts",
|
|
@@ -32,25 +38,65 @@
|
|
|
32
38
|
"types": "./dist/domain/AiError.d.mts",
|
|
33
39
|
"import": "./dist/domain/AiError.mjs"
|
|
34
40
|
},
|
|
41
|
+
"./Audio": {
|
|
42
|
+
"types": "./dist/domain/Audio.d.mts",
|
|
43
|
+
"import": "./dist/domain/Audio.mjs"
|
|
44
|
+
},
|
|
45
|
+
"./Image": {
|
|
46
|
+
"types": "./dist/domain/Image.d.mts",
|
|
47
|
+
"import": "./dist/domain/Image.mjs"
|
|
48
|
+
},
|
|
35
49
|
"./Items": {
|
|
36
50
|
"types": "./dist/domain/Items.d.mts",
|
|
37
51
|
"import": "./dist/domain/Items.mjs"
|
|
38
52
|
},
|
|
53
|
+
"./Media": {
|
|
54
|
+
"types": "./dist/domain/Media.d.mts",
|
|
55
|
+
"import": "./dist/domain/Media.mjs"
|
|
56
|
+
},
|
|
57
|
+
"./Music": {
|
|
58
|
+
"types": "./dist/domain/Music.d.mts",
|
|
59
|
+
"import": "./dist/domain/Music.mjs"
|
|
60
|
+
},
|
|
61
|
+
"./Transcript": {
|
|
62
|
+
"types": "./dist/domain/Transcript.d.mts",
|
|
63
|
+
"import": "./dist/domain/Transcript.mjs"
|
|
64
|
+
},
|
|
39
65
|
"./Turn": {
|
|
40
66
|
"types": "./dist/domain/Turn.d.mts",
|
|
41
67
|
"import": "./dist/domain/Turn.mjs"
|
|
42
68
|
},
|
|
69
|
+
"./Embedding": {
|
|
70
|
+
"types": "./dist/embedding-model/Embedding.d.mts",
|
|
71
|
+
"import": "./dist/embedding-model/Embedding.mjs"
|
|
72
|
+
},
|
|
73
|
+
"./EmbeddingModel": {
|
|
74
|
+
"types": "./dist/embedding-model/EmbeddingModel.d.mts",
|
|
75
|
+
"import": "./dist/embedding-model/EmbeddingModel.mjs"
|
|
76
|
+
},
|
|
43
77
|
"./LanguageModel": {
|
|
44
78
|
"types": "./dist/language-model/LanguageModel.d.mts",
|
|
45
79
|
"import": "./dist/language-model/LanguageModel.mjs"
|
|
46
80
|
},
|
|
81
|
+
"./MusicGenerator": {
|
|
82
|
+
"types": "./dist/music-generator/MusicGenerator.d.mts",
|
|
83
|
+
"import": "./dist/music-generator/MusicGenerator.mjs"
|
|
84
|
+
},
|
|
85
|
+
"./SpeechSynthesizer": {
|
|
86
|
+
"types": "./dist/speech-synthesizer/SpeechSynthesizer.d.mts",
|
|
87
|
+
"import": "./dist/speech-synthesizer/SpeechSynthesizer.mjs"
|
|
88
|
+
},
|
|
89
|
+
"./Transcriber": {
|
|
90
|
+
"types": "./dist/transcriber/Transcriber.d.mts",
|
|
91
|
+
"import": "./dist/transcriber/Transcriber.mjs"
|
|
92
|
+
},
|
|
47
93
|
"./Loop": {
|
|
48
94
|
"types": "./dist/loop/Loop.d.mts",
|
|
49
95
|
"import": "./dist/loop/Loop.mjs"
|
|
50
96
|
},
|
|
51
|
-
"./
|
|
52
|
-
"types": "./dist/
|
|
53
|
-
"import": "./dist/
|
|
97
|
+
"./Vector": {
|
|
98
|
+
"types": "./dist/math/Vector.d.mts",
|
|
99
|
+
"import": "./dist/math/Vector.mjs"
|
|
54
100
|
},
|
|
55
101
|
"./Tool": {
|
|
56
102
|
"types": "./dist/tool/Tool.d.mts",
|
|
@@ -99,27 +145,33 @@
|
|
|
99
145
|
"./testing/MockProvider": {
|
|
100
146
|
"types": "./dist/testing/MockProvider.d.mts",
|
|
101
147
|
"import": "./dist/testing/MockProvider.mjs"
|
|
148
|
+
},
|
|
149
|
+
"./testing/MockMusicGenerator": {
|
|
150
|
+
"types": "./dist/testing/MockMusicGenerator.d.mts",
|
|
151
|
+
"import": "./dist/testing/MockMusicGenerator.mjs"
|
|
152
|
+
},
|
|
153
|
+
"./testing/MockSpeechSynthesizer": {
|
|
154
|
+
"types": "./dist/testing/MockSpeechSynthesizer.d.mts",
|
|
155
|
+
"import": "./dist/testing/MockSpeechSynthesizer.mjs"
|
|
156
|
+
},
|
|
157
|
+
"./testing/MockTranscriber": {
|
|
158
|
+
"types": "./dist/testing/MockTranscriber.d.mts",
|
|
159
|
+
"import": "./dist/testing/MockTranscriber.mjs"
|
|
102
160
|
}
|
|
103
161
|
},
|
|
104
|
-
"files": [
|
|
105
|
-
"dist",
|
|
106
|
-
"src",
|
|
107
|
-
"README.md",
|
|
108
|
-
"LICENSE"
|
|
109
|
-
],
|
|
110
162
|
"publishConfig": {
|
|
111
163
|
"access": "public"
|
|
112
164
|
},
|
|
113
165
|
"dependencies": {
|
|
114
166
|
"@standard-schema/spec": "^1.1.0"
|
|
115
167
|
},
|
|
116
|
-
"peerDependencies": {
|
|
117
|
-
"effect": "4.0.0-beta.57"
|
|
118
|
-
},
|
|
119
168
|
"devDependencies": {
|
|
120
169
|
"effect": "4.0.0-beta.57",
|
|
121
170
|
"typescript": "^6.0.3"
|
|
122
171
|
},
|
|
172
|
+
"peerDependencies": {
|
|
173
|
+
"effect": "4.0.0-beta.57"
|
|
174
|
+
},
|
|
123
175
|
"scripts": {
|
|
124
176
|
"build": "tsdown",
|
|
125
177
|
"typecheck": "tsc --noEmit"
|
package/src/domain/AiError.ts
CHANGED
|
@@ -80,6 +80,26 @@ export class IncompleteTurn extends Data.TaggedError("IncompleteTurn")<{
|
|
|
80
80
|
raw?: unknown
|
|
81
81
|
}> {}
|
|
82
82
|
|
|
83
|
+
/**
|
|
84
|
+
* The provider does not implement the requested capability for this
|
|
85
|
+
* specific request. Distinct from `InvalidRequest` (the request shape is
|
|
86
|
+
* malformed) and `AuthFailed` (the request was rejected).
|
|
87
|
+
*
|
|
88
|
+
* Reserved for request-data-dependent gaps where the provider supports
|
|
89
|
+
* the method in general but not for these inputs — e.g. Google's
|
|
90
|
+
* `streamSynthesisFrom` works only for Chirp 3 HD voices; calling it
|
|
91
|
+
* with a Neural2 voice ID fails `Unsupported`.
|
|
92
|
+
*
|
|
93
|
+
* Blanket provider-level gaps (e.g. OpenAI has no incremental-text-in
|
|
94
|
+
* TTS at all) are gated at compile time via capability marker tags
|
|
95
|
+
* (`TtsIncrementalText`, `SttStreaming`) on the R channel instead.
|
|
96
|
+
*/
|
|
97
|
+
export class Unsupported extends Data.TaggedError("Unsupported")<{
|
|
98
|
+
provider: string
|
|
99
|
+
capability: string
|
|
100
|
+
reason?: string
|
|
101
|
+
}> {}
|
|
102
|
+
|
|
83
103
|
export type AiError =
|
|
84
104
|
| RateLimited
|
|
85
105
|
| Unavailable
|
|
@@ -91,3 +111,4 @@ export type AiError =
|
|
|
91
111
|
| Cancelled
|
|
92
112
|
| IncompleteTurn
|
|
93
113
|
| GenerationFailed
|
|
114
|
+
| Unsupported
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { MediaBase64, MediaBytes, MediaUrl } from "./Media.js"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MIME types we care about across STT input and TTS output. Container-
|
|
5
|
+
* level only — sample rate / encoding flavours live on `AudioFormat`.
|
|
6
|
+
*
|
|
7
|
+
* Per-provider request types narrow this further. The `(string & {})`
|
|
8
|
+
* tail keeps autocomplete on the literals while still accepting any
|
|
9
|
+
* string, so unusual formats work without an SDK update.
|
|
10
|
+
*/
|
|
11
|
+
export type AudioMimeType =
|
|
12
|
+
| "audio/mpeg"
|
|
13
|
+
| "audio/wav"
|
|
14
|
+
| "audio/x-wav"
|
|
15
|
+
| "audio/ogg"
|
|
16
|
+
| "audio/opus"
|
|
17
|
+
| "audio/flac"
|
|
18
|
+
| "audio/aac"
|
|
19
|
+
| "audio/mp4"
|
|
20
|
+
| "audio/webm"
|
|
21
|
+
| "audio/L16"
|
|
22
|
+
| "audio/pcm"
|
|
23
|
+
| "audio/mulaw"
|
|
24
|
+
| "audio/alaw"
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
26
|
+
| (string & {})
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Audio at rest — instantiates `MediaSource` with the audio MIME union.
|
|
30
|
+
* Used for sync STT input.
|
|
31
|
+
*
|
|
32
|
+
* URL variant is best-effort: some providers (OpenAI, Cartesia, Azure
|
|
33
|
+
* short-audio) reject URL ingestion and the adapter must upload via the
|
|
34
|
+
* `bytes` or `base64` variant instead. Adapter layers reject unsupported
|
|
35
|
+
* shapes up front with `AiError.InvalidRequest`.
|
|
36
|
+
*/
|
|
37
|
+
export type AudioSource =
|
|
38
|
+
| MediaUrl<AudioMimeType>
|
|
39
|
+
| MediaBase64<AudioMimeType>
|
|
40
|
+
| MediaBytes<AudioMimeType>
|
|
41
|
+
|
|
42
|
+
export const isAudioUrl = (s: AudioSource): s is MediaUrl<AudioMimeType> => s._tag === "url"
|
|
43
|
+
export const isAudioBase64 = (s: AudioSource): s is MediaBase64<AudioMimeType> =>
|
|
44
|
+
s._tag === "base64"
|
|
45
|
+
export const isAudioBytes = (s: AudioSource): s is MediaBytes<AudioMimeType> => s._tag === "bytes"
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Structural audio format. Used both as TTS output spec and as STT
|
|
49
|
+
* streaming-input declaration. Providers that use compound slugs
|
|
50
|
+
* (`mp3_44100_128`, `audio-16khz-128kbitrate-mono-mp3`,
|
|
51
|
+
* `aura-2-thalia-en`) are encoded at the adapter layer.
|
|
52
|
+
*/
|
|
53
|
+
export type AudioFormat = {
|
|
54
|
+
readonly container: "mp3" | "wav" | "ogg" | "opus" | "flac" | "aac" | "webm" | "raw"
|
|
55
|
+
readonly encoding:
|
|
56
|
+
| "pcm_s16le"
|
|
57
|
+
| "pcm_f32le"
|
|
58
|
+
| "pcm_mulaw"
|
|
59
|
+
| "pcm_alaw"
|
|
60
|
+
| "mp3"
|
|
61
|
+
| "opus"
|
|
62
|
+
| "vorbis"
|
|
63
|
+
| "flac"
|
|
64
|
+
| "aac"
|
|
65
|
+
readonly sampleRate: 8000 | 16000 | 22050 | 24000 | 32000 | 44100 | 48000
|
|
66
|
+
/** mp3 / opus only. */
|
|
67
|
+
readonly bitRate?: number
|
|
68
|
+
readonly channels?: 1 | 2
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Streamed audio chunk. `bytes` carries the codec-encoded payload as
|
|
73
|
+
* declared on the stream's `AudioFormat`. No per-chunk timestamp here —
|
|
74
|
+
* providers that emit timing do so via `TranscriptEvent.words[]`.
|
|
75
|
+
*/
|
|
76
|
+
export type AudioChunk = {
|
|
77
|
+
readonly bytes: Uint8Array
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Full audio result for sync TTS. Format mirrors the request; provider
|
|
82
|
+
* layers normalize.
|
|
83
|
+
*/
|
|
84
|
+
export type AudioBlob = {
|
|
85
|
+
readonly format: AudioFormat
|
|
86
|
+
readonly bytes: Uint8Array
|
|
87
|
+
readonly durationSeconds?: number
|
|
88
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { Schema } from "effect"
|
|
2
|
+
import type { MediaBase64, MediaBytes, MediaSource, MediaUrl } from "./Media.js"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Image MIME types AI providers typically accept. The first four are the
|
|
6
|
+
* universal subset (Cohere v4, Voyage multimodal, Jina v4, Google
|
|
7
|
+
* `gemini-embedding-2`); HEIC / HEIF are Google-specific. The
|
|
8
|
+
* `(string & {})` tail keeps autocomplete on the literals while still
|
|
9
|
+
* accepting any string, so a newly-supported format works without an
|
|
10
|
+
* SDK update.
|
|
11
|
+
*/
|
|
12
|
+
export type ImageMimeType =
|
|
13
|
+
| "image/png"
|
|
14
|
+
| "image/jpeg"
|
|
15
|
+
| "image/webp"
|
|
16
|
+
| "image/gif"
|
|
17
|
+
| "image/heic"
|
|
18
|
+
| "image/heif"
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
20
|
+
| (string & {})
|
|
21
|
+
|
|
22
|
+
const ImageMimeTypeSchema = Schema.String as unknown as Schema.Schema<ImageMimeType>
|
|
23
|
+
|
|
24
|
+
export type ImageUrlSource = MediaUrl<ImageMimeType>
|
|
25
|
+
export type ImageBase64Source = MediaBase64<ImageMimeType>
|
|
26
|
+
export type ImageBytesSource = MediaBytes<ImageMimeType>
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Where an image lives. Provider layers normalize across these:
|
|
30
|
+
* `bytes` becomes a base64 data URI for OpenAI / Anthropic, an
|
|
31
|
+
* `inlineData` part for Gemini, and a separate field for Cohere /
|
|
32
|
+
* Voyage. URL constraints (must be HTTPS, must be public, …) are
|
|
33
|
+
* provider-specific and validated at the layer, not in the type.
|
|
34
|
+
*/
|
|
35
|
+
export type ImageSource = MediaSource<ImageMimeType>
|
|
36
|
+
|
|
37
|
+
export const ImageUrlSource = Schema.TaggedStruct("url", {
|
|
38
|
+
url: Schema.String,
|
|
39
|
+
mimeType: Schema.optional(ImageMimeTypeSchema),
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
export const ImageBase64Source = Schema.TaggedStruct("base64", {
|
|
43
|
+
base64: Schema.String,
|
|
44
|
+
mimeType: ImageMimeTypeSchema,
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
export const ImageBytesSource = Schema.TaggedStruct("bytes", {
|
|
48
|
+
bytes: Schema.Uint8Array,
|
|
49
|
+
mimeType: ImageMimeTypeSchema,
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
export const ImageSource: Schema.Schema<ImageSource> = Schema.Union([
|
|
53
|
+
ImageUrlSource,
|
|
54
|
+
ImageBase64Source,
|
|
55
|
+
ImageBytesSource,
|
|
56
|
+
]) as unknown as Schema.Schema<ImageSource>
|
|
57
|
+
|
|
58
|
+
export const imageUrl = (url: string, mimeType?: ImageMimeType): ImageUrlSource =>
|
|
59
|
+
mimeType !== undefined ? { _tag: "url", url, mimeType } : { _tag: "url", url }
|
|
60
|
+
|
|
61
|
+
export const imageBase64 = (base64: string, mimeType: ImageMimeType): ImageBase64Source => ({
|
|
62
|
+
_tag: "base64",
|
|
63
|
+
base64,
|
|
64
|
+
mimeType,
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
export const imageBytes = (bytes: Uint8Array, mimeType: ImageMimeType): ImageBytesSource => ({
|
|
68
|
+
_tag: "bytes",
|
|
69
|
+
bytes,
|
|
70
|
+
mimeType,
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
export const isImageUrl = Schema.is(ImageUrlSource)
|
|
74
|
+
export const isImageBase64 = Schema.is(ImageBase64Source)
|
|
75
|
+
export const isImageBytes = Schema.is(ImageBytesSource)
|
package/src/domain/Items.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Schema } from "effect"
|
|
2
|
+
import { ImageSource } from "./Image.js"
|
|
2
3
|
|
|
3
4
|
// ---------------------------------------------------------------------------
|
|
4
5
|
// Content blocks (inside Message.content)
|
|
@@ -10,39 +11,13 @@ export const InputText = Schema.Struct({
|
|
|
10
11
|
})
|
|
11
12
|
export type InputText = typeof InputText.Type
|
|
12
13
|
|
|
13
|
-
/**
|
|
14
|
-
* Where an image lives. `url` covers HTTP(S) URLs (the model fetches
|
|
15
|
-
* them); `base64` covers inline bytes embedded in the request. Provider
|
|
16
|
-
* encoders dispatch on `_tag`. File-id / uploaded-asset references are
|
|
17
|
-
* provider-specific and stay out of this union for now.
|
|
18
|
-
*/
|
|
19
|
-
export const ImageUrlSource = Schema.Struct({
|
|
20
|
-
_tag: Schema.Literal("url"),
|
|
21
|
-
url: Schema.String,
|
|
22
|
-
})
|
|
23
|
-
export type ImageUrlSource = typeof ImageUrlSource.Type
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Inline image bytes. `data` is **already base64-encoded** (matches what
|
|
27
|
-
* the wire formats expect; no double-encoding needed downstream).
|
|
28
|
-
* `media_type` is the MIME type, e.g. `"image/png"`.
|
|
29
|
-
*/
|
|
30
|
-
export const ImageBase64Source = Schema.Struct({
|
|
31
|
-
_tag: Schema.Literal("base64"),
|
|
32
|
-
media_type: Schema.String,
|
|
33
|
-
data: Schema.String,
|
|
34
|
-
})
|
|
35
|
-
export type ImageBase64Source = typeof ImageBase64Source.Type
|
|
36
|
-
|
|
37
|
-
export const ImageSource = Schema.Union([ImageUrlSource, ImageBase64Source])
|
|
38
|
-
export type ImageSource = typeof ImageSource.Type
|
|
39
|
-
|
|
40
|
-
export const isImageUrlSource = (s: ImageSource): s is ImageUrlSource => s._tag === "url"
|
|
41
|
-
export const isImageBase64Source = (s: ImageSource): s is ImageBase64Source => s._tag === "base64"
|
|
42
|
-
|
|
43
14
|
/**
|
|
44
15
|
* User-provided image content block. Pair with `InputText` inside a
|
|
45
16
|
* `Message.content` array to ask "what's in this image?" style questions.
|
|
17
|
+
*
|
|
18
|
+
* `source` is the cross-modality `ImageSource` from `domain/Image.ts` -
|
|
19
|
+
* url, base64, or raw bytes. Provider codecs encode bytes to whatever
|
|
20
|
+
* wire format the provider wants.
|
|
46
21
|
*/
|
|
47
22
|
export const InputImage = Schema.Struct({
|
|
48
23
|
type: Schema.Literal("input_image"),
|
|
@@ -91,11 +66,10 @@ export type FilePath = typeof FilePath.Type
|
|
|
91
66
|
export const Annotation = Schema.Union([UrlCitation, FileCitation, ContainerFileCitation, FilePath])
|
|
92
67
|
export type Annotation = typeof Annotation.Type
|
|
93
68
|
|
|
94
|
-
export const isUrlCitation = (
|
|
95
|
-
export const isFileCitation = (
|
|
96
|
-
export const isContainerFileCitation = (
|
|
97
|
-
|
|
98
|
-
export const isFilePath = (a: Annotation): a is FilePath => a.type === "file_path"
|
|
69
|
+
export const isUrlCitation = Schema.is(UrlCitation)
|
|
70
|
+
export const isFileCitation = Schema.is(FileCitation)
|
|
71
|
+
export const isContainerFileCitation = Schema.is(ContainerFileCitation)
|
|
72
|
+
export const isFilePath = Schema.is(FilePath)
|
|
99
73
|
|
|
100
74
|
export const OutputText = Schema.Struct({
|
|
101
75
|
type: Schema.Literal("output_text"),
|
|
@@ -183,18 +157,15 @@ export type Item = typeof Item.Type
|
|
|
183
157
|
// Type guards
|
|
184
158
|
// ---------------------------------------------------------------------------
|
|
185
159
|
|
|
186
|
-
export const isInputText = (
|
|
187
|
-
export const isInputImage = (
|
|
188
|
-
|
|
189
|
-
export const
|
|
190
|
-
|
|
191
|
-
export const
|
|
192
|
-
|
|
193
|
-
export const
|
|
194
|
-
export const
|
|
195
|
-
export const isFunctionCallOutput = (item: Item): item is FunctionCallOutput =>
|
|
196
|
-
item.type === "function_call_output"
|
|
197
|
-
export const isReasoning = (item: Item): item is Reasoning => item.type === "reasoning"
|
|
160
|
+
export const isInputText = Schema.is(InputText)
|
|
161
|
+
export const isInputImage = Schema.is(InputImage)
|
|
162
|
+
export const isOutputText = Schema.is(OutputText)
|
|
163
|
+
export const isRefusal = Schema.is(Refusal)
|
|
164
|
+
|
|
165
|
+
export const isMessage = Schema.is(Message)
|
|
166
|
+
export const isFunctionCall = Schema.is(FunctionCall)
|
|
167
|
+
export const isFunctionCallOutput = Schema.is(FunctionCallOutput)
|
|
168
|
+
export const isReasoning = Schema.is(Reasoning)
|
|
198
169
|
|
|
199
170
|
// ---------------------------------------------------------------------------
|
|
200
171
|
// Usage and stop reason
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-modality media reference shape.
|
|
3
|
+
*
|
|
4
|
+
* Every "media at rest" reference - image, audio, video, document - is one
|
|
5
|
+
* of three variants:
|
|
6
|
+
*
|
|
7
|
+
* - `url` : a remote address (HTTP, GCS, etc.). The model fetches it.
|
|
8
|
+
* `mimeType` is optional - servers usually set Content-Type.
|
|
9
|
+
* Some providers (Gemini `fileData`) want it explicit.
|
|
10
|
+
*
|
|
11
|
+
* - `base64` : an inline base64-encoded payload. Always carries a
|
|
12
|
+
* `mimeType` so the consumer knows how to decode.
|
|
13
|
+
*
|
|
14
|
+
* - `bytes` : raw `Uint8Array`. Provider layers normalize to base64 or
|
|
15
|
+
* multipart upload at the wire boundary - users don't need
|
|
16
|
+
* to encode themselves.
|
|
17
|
+
*
|
|
18
|
+
* Per-modality files (`Image.ts`, future `Audio.ts` / `Video.ts` /
|
|
19
|
+
* `Document.ts`) instantiate this shape with their typed MIME union to
|
|
20
|
+
* get autocomplete on common formats while keeping the structural type
|
|
21
|
+
* uniform across modalities.
|
|
22
|
+
*
|
|
23
|
+
* Streaming media (live mic feed, streaming TTS playback) is *not*
|
|
24
|
+
* modeled here. Streams carry effect parameters (`Stream<A, E, R>`) and
|
|
25
|
+
* lifecycle (Scope, cancellation) that don't apply to media at rest. The
|
|
26
|
+
* complementary type lives alongside this one as `*Stream` in each
|
|
27
|
+
* per-modality file when those modalities land.
|
|
28
|
+
*
|
|
29
|
+
* Provider-uploaded asset references (OpenAI Files `file_id`, Gemini
|
|
30
|
+
* Files API URIs, Anthropic file IDs) are also out of scope here -
|
|
31
|
+
* they're a separate union (`FileRef`) added when needed.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
export type MediaUrl<M extends string = string> = {
|
|
35
|
+
readonly _tag: "url"
|
|
36
|
+
readonly url: string
|
|
37
|
+
readonly mimeType?: M
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type MediaBase64<M extends string = string> = {
|
|
41
|
+
readonly _tag: "base64"
|
|
42
|
+
readonly base64: string
|
|
43
|
+
readonly mimeType: M
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type MediaBytes<M extends string = string> = {
|
|
47
|
+
readonly _tag: "bytes"
|
|
48
|
+
readonly bytes: Uint8Array
|
|
49
|
+
readonly mimeType: M
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type MediaSource<M extends string = string> = MediaUrl<M> | MediaBase64<M> | MediaBytes<M>
|
|
53
|
+
|
|
54
|
+
export const isMediaUrl = <M extends string>(s: MediaSource<M>): s is MediaUrl<M> =>
|
|
55
|
+
s._tag === "url"
|
|
56
|
+
|
|
57
|
+
export const isMediaBase64 = <M extends string>(s: MediaSource<M>): s is MediaBase64<M> =>
|
|
58
|
+
s._tag === "base64"
|
|
59
|
+
|
|
60
|
+
export const isMediaBytes = <M extends string>(s: MediaSource<M>): s is MediaBytes<M> =>
|
|
61
|
+
s._tag === "bytes"
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import type { AudioBlob, AudioFormat } from "./Audio.js"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Prompt fragment with a relative weight. Native to Lyria RealTime
|
|
5
|
+
* (`{ text, weight }` pairs blended in the model). Single-prompt
|
|
6
|
+
* providers (Suno, Mureka, MiniMax) flatten to text at the adapter
|
|
7
|
+
* layer.
|
|
8
|
+
*/
|
|
9
|
+
export type WeightedPrompt = {
|
|
10
|
+
readonly text: string
|
|
11
|
+
/** Default `1.0`. Range typically `[0, 1]`; provider-dependent. */
|
|
12
|
+
readonly weight?: number
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Cross-provider music-generation request. Provider-specific extras
|
|
17
|
+
* (Lyria `mode`, ElevenLabs `composition_plan`, Suno custom-mode `title`,
|
|
18
|
+
* MiniMax `lyrics_optimizer`) live on each provider's typed request
|
|
19
|
+
* which extends this and narrows `model`.
|
|
20
|
+
*/
|
|
21
|
+
export type CommonGenerateMusicRequest = {
|
|
22
|
+
/** Model identifier. Each provider narrows. */
|
|
23
|
+
readonly model: string
|
|
24
|
+
/** Single prompt string or weighted-prompt list (blended where supported). */
|
|
25
|
+
readonly prompts: string | ReadonlyArray<WeightedPrompt>
|
|
26
|
+
/**
|
|
27
|
+
* Lyrics text, optionally with section tags like `[Verse]` / `[Chorus]` /
|
|
28
|
+
* `[Bridge]` / `[Outro]`. Ignored for instrumental-only providers or
|
|
29
|
+
* when `instrumental: true`.
|
|
30
|
+
*/
|
|
31
|
+
readonly lyrics?: string
|
|
32
|
+
/** Target duration in seconds. Provider may treat as a hint or hard limit. */
|
|
33
|
+
readonly durationSeconds?: number
|
|
34
|
+
/** Beats per minute (60–200 typical). */
|
|
35
|
+
readonly bpm?: number
|
|
36
|
+
/**
|
|
37
|
+
* Musical key/mode hint. Provider-specific vocabulary (e.g. Lyria
|
|
38
|
+
* RealTime uses enum values like `"C_MAJOR"`, `"A_MINOR"`).
|
|
39
|
+
*/
|
|
40
|
+
readonly scale?: string
|
|
41
|
+
/** Skip vocals / lyrics. */
|
|
42
|
+
readonly instrumental?: boolean
|
|
43
|
+
/** Preferred output format. Provider may override. */
|
|
44
|
+
readonly outputFormat?: AudioFormat
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Streamed-output request. Same shape as the sync request — the
|
|
49
|
+
* streaming variant only differs in how the response is delivered.
|
|
50
|
+
*/
|
|
51
|
+
export type CommonStreamGenerateMusicRequest = CommonGenerateMusicRequest
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Bidirectional-session input. The user pushes one of these per
|
|
55
|
+
* change: a new prompt blend, a config delta, or a playback control.
|
|
56
|
+
* Lyria RealTime is the only provider currently surfacing these.
|
|
57
|
+
*/
|
|
58
|
+
export type MusicSessionInput =
|
|
59
|
+
| { readonly _tag: "prompts"; readonly prompts: ReadonlyArray<WeightedPrompt> }
|
|
60
|
+
| {
|
|
61
|
+
readonly _tag: "config"
|
|
62
|
+
readonly config: {
|
|
63
|
+
readonly bpm?: number
|
|
64
|
+
readonly scale?: string
|
|
65
|
+
readonly density?: number
|
|
66
|
+
readonly brightness?: number
|
|
67
|
+
readonly guidance?: number
|
|
68
|
+
readonly temperature?: number
|
|
69
|
+
readonly topK?: number
|
|
70
|
+
readonly seed?: number
|
|
71
|
+
readonly muteBass?: boolean
|
|
72
|
+
readonly muteDrums?: boolean
|
|
73
|
+
readonly onlyBassAndDrums?: boolean
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
| { readonly _tag: "control"; readonly action: "play" | "pause" | "stop" | "reset_context" }
|
|
77
|
+
|
|
78
|
+
export const promptsInput = (prompts: ReadonlyArray<WeightedPrompt>): MusicSessionInput => ({
|
|
79
|
+
_tag: "prompts",
|
|
80
|
+
prompts,
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
export const configInput = (
|
|
84
|
+
config: (MusicSessionInput & { _tag: "config" })["config"],
|
|
85
|
+
): MusicSessionInput => ({ _tag: "config", config })
|
|
86
|
+
|
|
87
|
+
export const controlInput = (
|
|
88
|
+
action: (MusicSessionInput & { _tag: "control" })["action"],
|
|
89
|
+
): MusicSessionInput => ({ _tag: "control", action })
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Sync-generation result. Extends `AudioBlob` with provider-side
|
|
93
|
+
* metadata that's common across music providers:
|
|
94
|
+
*
|
|
95
|
+
* - `songId` — Suno task id, ElevenLabs `song_id`, etc. Used for
|
|
96
|
+
* back-reference (re-download, stem export, follow-up edits).
|
|
97
|
+
* - `lyrics` — generated lyrics when the model returned them (Lyria
|
|
98
|
+
* text part, Mureka, Suno).
|
|
99
|
+
* - `sections` — structured section markers (Lyria optional JSON
|
|
100
|
+
* structure response).
|
|
101
|
+
* - `watermark` — presence marker (Lyria SynthID is always set).
|
|
102
|
+
*/
|
|
103
|
+
export type MusicResult = AudioBlob & {
|
|
104
|
+
readonly songId?: string
|
|
105
|
+
readonly lyrics?: string
|
|
106
|
+
readonly sections?: ReadonlyArray<{
|
|
107
|
+
readonly label: string
|
|
108
|
+
readonly startSeconds: number
|
|
109
|
+
readonly endSeconds: number
|
|
110
|
+
}>
|
|
111
|
+
readonly watermark?: { readonly kind: string }
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export const isPromptsInput = (
|
|
115
|
+
i: MusicSessionInput,
|
|
116
|
+
): i is MusicSessionInput & { _tag: "prompts" } => i._tag === "prompts"
|
|
117
|
+
export const isConfigInput = (i: MusicSessionInput): i is MusicSessionInput & { _tag: "config" } =>
|
|
118
|
+
i._tag === "config"
|
|
119
|
+
export const isControlInput = (
|
|
120
|
+
i: MusicSessionInput,
|
|
121
|
+
): i is MusicSessionInput & { _tag: "control" } => i._tag === "control"
|