@effect/ai 0.14.1 → 0.16.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/AiEmbeddingModel/package.json +6 -0
- package/AiLanguageModel/package.json +6 -0
- package/AiTool/package.json +6 -0
- package/dist/cjs/AiChat.js +65 -86
- package/dist/cjs/AiChat.js.map +1 -1
- package/dist/cjs/{Embeddings.js → AiEmbeddingModel.js} +12 -12
- package/dist/cjs/AiEmbeddingModel.js.map +1 -0
- package/dist/cjs/AiError.js +8 -1
- package/dist/cjs/AiError.js.map +1 -1
- package/dist/cjs/AiInput.js +335 -248
- package/dist/cjs/AiInput.js.map +1 -1
- package/dist/cjs/AiLanguageModel.js +311 -0
- package/dist/cjs/AiLanguageModel.js.map +1 -0
- package/dist/cjs/AiModel.js +11 -5
- package/dist/cjs/AiModel.js.map +1 -1
- package/dist/cjs/AiPlan.js +10 -3
- package/dist/cjs/AiPlan.js.map +1 -1
- package/dist/cjs/AiResponse.js +481 -165
- package/dist/cjs/AiResponse.js.map +1 -1
- package/dist/cjs/AiTelemetry.js +10 -3
- package/dist/cjs/AiTelemetry.js.map +1 -1
- package/dist/cjs/AiTool.js +93 -0
- package/dist/cjs/AiTool.js.map +1 -0
- package/dist/cjs/AiToolkit.js +121 -98
- package/dist/cjs/AiToolkit.js.map +1 -1
- package/dist/cjs/Tokenizer.js +14 -16
- package/dist/cjs/Tokenizer.js.map +1 -1
- package/dist/cjs/index.js +7 -9
- package/dist/cjs/internal/aiPlan.js +6 -9
- package/dist/cjs/internal/aiPlan.js.map +1 -1
- package/dist/cjs/internal/common.js +22 -0
- package/dist/cjs/internal/common.js.map +1 -0
- package/dist/dts/AiChat.d.ts +58 -44
- package/dist/dts/AiChat.d.ts.map +1 -1
- package/dist/dts/{Embeddings.d.ts → AiEmbeddingModel.d.ts} +13 -14
- package/dist/dts/AiEmbeddingModel.d.ts.map +1 -0
- package/dist/dts/AiError.d.ts +4 -3
- package/dist/dts/AiError.d.ts.map +1 -1
- package/dist/dts/AiInput.d.ts +441 -146
- package/dist/dts/AiInput.d.ts.map +1 -1
- package/dist/dts/AiLanguageModel.d.ts +263 -0
- package/dist/dts/AiLanguageModel.d.ts.map +1 -0
- package/dist/dts/AiModel.d.ts +21 -20
- package/dist/dts/AiModel.d.ts.map +1 -1
- package/dist/dts/AiPlan.d.ts +90 -26
- package/dist/dts/AiPlan.d.ts.map +1 -1
- package/dist/dts/AiResponse.d.ts +711 -100
- package/dist/dts/AiResponse.d.ts.map +1 -1
- package/dist/dts/AiTelemetry.d.ts +175 -157
- package/dist/dts/AiTelemetry.d.ts.map +1 -1
- package/dist/dts/AiTool.d.ts +288 -0
- package/dist/dts/AiTool.d.ts.map +1 -0
- package/dist/dts/AiToolkit.d.ts +50 -111
- package/dist/dts/AiToolkit.d.ts.map +1 -1
- package/dist/dts/Tokenizer.d.ts +8 -6
- package/dist/dts/Tokenizer.d.ts.map +1 -1
- package/dist/dts/index.d.ts +8 -12
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/common.d.ts +2 -0
- package/dist/dts/internal/common.d.ts.map +1 -0
- package/dist/esm/AiChat.js +62 -83
- package/dist/esm/AiChat.js.map +1 -1
- package/dist/esm/{Embeddings.js → AiEmbeddingModel.js} +10 -10
- package/dist/esm/AiEmbeddingModel.js.map +1 -0
- package/dist/esm/AiError.js +8 -1
- package/dist/esm/AiError.js.map +1 -1
- package/dist/esm/AiInput.js +316 -238
- package/dist/esm/AiInput.js.map +1 -1
- package/dist/esm/AiLanguageModel.js +300 -0
- package/dist/esm/AiLanguageModel.js.map +1 -0
- package/dist/esm/AiModel.js +11 -5
- package/dist/esm/AiModel.js.map +1 -1
- package/dist/esm/AiPlan.js +8 -2
- package/dist/esm/AiPlan.js.map +1 -1
- package/dist/esm/AiResponse.js +467 -162
- package/dist/esm/AiResponse.js.map +1 -1
- package/dist/esm/AiTelemetry.js +8 -2
- package/dist/esm/AiTelemetry.js.map +1 -1
- package/dist/esm/AiTool.js +82 -0
- package/dist/esm/AiTool.js.map +1 -0
- package/dist/esm/AiToolkit.js +118 -96
- package/dist/esm/AiToolkit.js.map +1 -1
- package/dist/esm/Tokenizer.js +14 -16
- package/dist/esm/Tokenizer.js.map +1 -1
- package/dist/esm/index.js +8 -12
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/aiPlan.js +4 -7
- package/dist/esm/internal/aiPlan.js.map +1 -1
- package/dist/esm/internal/common.js +14 -0
- package/dist/esm/internal/common.js.map +1 -0
- package/package.json +28 -36
- package/src/AiChat.ts +182 -207
- package/src/{Embeddings.ts → AiEmbeddingModel.ts} +19 -18
- package/src/AiError.ts +8 -1
- package/src/AiInput.ts +434 -313
- package/src/AiLanguageModel.ts +569 -0
- package/src/AiModel.ts +47 -29
- package/src/AiPlan.ts +102 -30
- package/src/AiResponse.ts +743 -187
- package/src/AiTelemetry.ts +214 -197
- package/src/AiTool.ts +496 -0
- package/src/AiToolkit.ts +200 -240
- package/src/Tokenizer.ts +18 -22
- package/src/index.ts +9 -14
- package/src/internal/aiPlan.ts +12 -14
- package/src/internal/common.ts +12 -0
- package/AiModels/package.json +0 -6
- package/AiRole/package.json +0 -6
- package/Completions/package.json +0 -6
- package/Embeddings/package.json +0 -6
- package/dist/cjs/AiModels.js +0 -54
- package/dist/cjs/AiModels.js.map +0 -1
- package/dist/cjs/AiRole.js +0 -106
- package/dist/cjs/AiRole.js.map +0 -1
- package/dist/cjs/Completions.js +0 -256
- package/dist/cjs/Completions.js.map +0 -1
- package/dist/cjs/Embeddings.js.map +0 -1
- package/dist/dts/AiModels.d.ts +0 -34
- package/dist/dts/AiModels.d.ts.map +0 -1
- package/dist/dts/AiRole.d.ts +0 -111
- package/dist/dts/AiRole.d.ts.map +0 -1
- package/dist/dts/Completions.d.ts +0 -128
- package/dist/dts/Completions.d.ts.map +0 -1
- package/dist/dts/Embeddings.d.ts.map +0 -1
- package/dist/esm/AiModels.js +0 -44
- package/dist/esm/AiModels.js.map +0 -1
- package/dist/esm/AiRole.js +0 -93
- package/dist/esm/AiRole.js.map +0 -1
- package/dist/esm/Completions.js +0 -245
- package/dist/esm/Completions.js.map +0 -1
- package/dist/esm/Embeddings.js.map +0 -1
- package/src/AiModels.ts +0 -77
- package/src/AiRole.ts +0 -122
- package/src/Completions.ts +0 -434
package/src/AiInput.ts
CHANGED
|
@@ -1,227 +1,197 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @since 1.0.0
|
|
3
3
|
*/
|
|
4
|
-
import type { PlatformError } from "@effect/platform/Error"
|
|
5
|
-
import * as FileSystem from "@effect/platform/FileSystem"
|
|
6
|
-
import * as Path from "@effect/platform/Path"
|
|
7
|
-
import * as Chunk from "effect/Chunk"
|
|
8
|
-
import * as Context from "effect/Context"
|
|
9
|
-
import * as Effect from "effect/Effect"
|
|
10
|
-
import * as Encoding from "effect/Encoding"
|
|
11
4
|
import { dual } from "effect/Function"
|
|
12
|
-
import * as Option from "effect/Option"
|
|
13
|
-
import * as ParseResult from "effect/ParseResult"
|
|
14
5
|
import * as Predicate from "effect/Predicate"
|
|
15
|
-
import * as
|
|
16
|
-
import
|
|
17
|
-
import * as
|
|
18
|
-
|
|
19
|
-
const constDisableValidation = { disableValidation: true } as const
|
|
6
|
+
import * as Schema from "effect/Schema"
|
|
7
|
+
import * as AiResponse from "./AiResponse.js"
|
|
8
|
+
import * as InternalCommon from "./internal/common.js"
|
|
20
9
|
|
|
21
10
|
/**
|
|
22
11
|
* @since 1.0.0
|
|
23
|
-
* @category
|
|
12
|
+
* @category Type Ids
|
|
24
13
|
*/
|
|
25
|
-
export const
|
|
14
|
+
export const TypeId = Symbol.for("@effect/ai/AiInput")
|
|
26
15
|
|
|
27
16
|
/**
|
|
28
17
|
* @since 1.0.0
|
|
29
|
-
* @category
|
|
18
|
+
* @category Type Ids
|
|
30
19
|
*/
|
|
31
|
-
export type
|
|
20
|
+
export type TypeId = typeof TypeId
|
|
32
21
|
|
|
33
22
|
/**
|
|
23
|
+
* Represents input to a large language model.
|
|
24
|
+
*
|
|
34
25
|
* @since 1.0.0
|
|
35
|
-
* @category
|
|
26
|
+
* @category Models
|
|
36
27
|
*/
|
|
37
|
-
export class
|
|
38
|
-
|
|
28
|
+
export class AiInput extends Schema.Class<AiInput>(
|
|
29
|
+
"@effect/ai/AiInput"
|
|
30
|
+
)({
|
|
31
|
+
messages: Schema.Array(Schema.suspend(() => Message))
|
|
39
32
|
}) {
|
|
40
33
|
/**
|
|
41
34
|
* @since 1.0.0
|
|
42
35
|
*/
|
|
43
|
-
readonly [
|
|
44
|
-
/**
|
|
45
|
-
* @since 1.0.0
|
|
46
|
-
*/
|
|
47
|
-
static fromContent(content: string): TextPart {
|
|
48
|
-
return new TextPart({ content }, constDisableValidation)
|
|
49
|
-
}
|
|
36
|
+
readonly [TypeId]: TypeId = TypeId
|
|
50
37
|
}
|
|
51
38
|
|
|
52
39
|
/**
|
|
53
40
|
* @since 1.0.0
|
|
54
|
-
* @category
|
|
41
|
+
* @category Models
|
|
42
|
+
*/
|
|
43
|
+
export const FromJson = Schema.parseJson(AiInput)
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Represents raw input types that can be converted into an `AiInput`.
|
|
47
|
+
*
|
|
48
|
+
* @since 1.0.0
|
|
49
|
+
* @category Models
|
|
50
|
+
*/
|
|
51
|
+
export type Raw =
|
|
52
|
+
| string
|
|
53
|
+
| Message
|
|
54
|
+
| Iterable<Message>
|
|
55
|
+
| AiInput
|
|
56
|
+
| AiResponse.AiResponse
|
|
57
|
+
| AiResponse.WithStructuredOutput<any>
|
|
58
|
+
| AiResponse.WithToolCallResults<any>
|
|
59
|
+
|
|
60
|
+
// =============================================================================
|
|
61
|
+
// Message
|
|
62
|
+
// =============================================================================
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @since 1.0.0
|
|
66
|
+
* @category Type Ids
|
|
55
67
|
*/
|
|
56
|
-
export const
|
|
68
|
+
export const MessageTypeId = Symbol.for("@effect/ai/AiInput/Message")
|
|
57
69
|
|
|
58
70
|
/**
|
|
59
71
|
* @since 1.0.0
|
|
60
|
-
* @category
|
|
72
|
+
* @category Type Ids
|
|
61
73
|
*/
|
|
62
|
-
export type
|
|
74
|
+
export type MessageTypeId = typeof MessageTypeId
|
|
63
75
|
|
|
64
76
|
/**
|
|
65
77
|
* @since 1.0.0
|
|
66
|
-
* @category
|
|
78
|
+
* @category Models
|
|
67
79
|
*/
|
|
68
|
-
export class
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
)
|
|
80
|
+
export class UserMessage extends Schema.TaggedClass<UserMessage>(
|
|
81
|
+
"@effect/ai/AiInput/Message/UserMessage"
|
|
82
|
+
)("UserMessage", {
|
|
83
|
+
parts: Schema.Array(Schema.suspend(() => UserMessagePart)),
|
|
84
|
+
userName: Schema.optional(Schema.String)
|
|
74
85
|
}) {
|
|
75
86
|
/**
|
|
76
87
|
* @since 1.0.0
|
|
77
88
|
*/
|
|
78
|
-
readonly [
|
|
89
|
+
readonly [MessageTypeId]: MessageTypeId = MessageTypeId
|
|
79
90
|
}
|
|
80
91
|
|
|
81
|
-
const base64ContentTypeRegex = /^data:(.*?);base64$/
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* @since 1.0.0
|
|
85
|
-
* @category base64
|
|
86
|
-
*/
|
|
87
|
-
export interface Base64DataUrl extends
|
|
88
|
-
Schema_.transformOrFail<
|
|
89
|
-
typeof Schema_.String,
|
|
90
|
-
Schema_.Struct<{
|
|
91
|
-
data: Schema_.Schema<Uint8Array>
|
|
92
|
-
contentType: typeof Schema_.String
|
|
93
|
-
}>
|
|
94
|
-
>
|
|
95
|
-
{}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* @since 1.0.0
|
|
99
|
-
* @category base64
|
|
100
|
-
*/
|
|
101
|
-
export const Base64DataUrl: Base64DataUrl = Schema_.transformOrFail(
|
|
102
|
-
Schema_.String.annotations({
|
|
103
|
-
title: "Base64 Data URL",
|
|
104
|
-
description: "A base64 data URL"
|
|
105
|
-
}),
|
|
106
|
-
Schema_.Struct({
|
|
107
|
-
data: Schema_.Uint8ArrayFromSelf,
|
|
108
|
-
contentType: Schema_.String
|
|
109
|
-
}),
|
|
110
|
-
{
|
|
111
|
-
decode(base64Url, _, ast) {
|
|
112
|
-
const commaIndex = base64Url.indexOf(",")
|
|
113
|
-
if (commaIndex === -1) {
|
|
114
|
-
return ParseResult.fail(new ParseResult.Type(ast, base64Url))
|
|
115
|
-
}
|
|
116
|
-
const header = base64Url.slice(0, commaIndex)
|
|
117
|
-
const data = base64Url.slice(commaIndex + 1)
|
|
118
|
-
const contentType = base64ContentTypeRegex.exec(header)
|
|
119
|
-
if (contentType === null) {
|
|
120
|
-
return ParseResult.fail(new ParseResult.Type(ast, base64Url))
|
|
121
|
-
}
|
|
122
|
-
return Encoding.decodeBase64(data).pipe(
|
|
123
|
-
ParseResult.mapError((_) => new ParseResult.Type(ast, base64Url)),
|
|
124
|
-
ParseResult.map((data) => ({ data, contentType: contentType[1] }))
|
|
125
|
-
)
|
|
126
|
-
},
|
|
127
|
-
encode({ contentType, data }) {
|
|
128
|
-
const base64 = Encoding.encodeBase64(data)
|
|
129
|
-
return ParseResult.succeed(`data:${contentType};base64,${base64}`)
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
)
|
|
133
|
-
|
|
134
92
|
/**
|
|
135
93
|
* @since 1.0.0
|
|
136
|
-
* @category
|
|
94
|
+
* @category Models
|
|
137
95
|
*/
|
|
138
|
-
export class
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
Schema_.withConstructorDefault(() => "auto" as const)
|
|
143
|
-
)
|
|
96
|
+
export class AssistantMessage extends Schema.TaggedClass<AssistantMessage>(
|
|
97
|
+
"@effect/ai/AiInput/Message/AssistantMessage"
|
|
98
|
+
)("AssistantMessage", {
|
|
99
|
+
parts: Schema.Array(Schema.suspend(() => AssistantMessagePart))
|
|
144
100
|
}) {
|
|
145
101
|
/**
|
|
146
102
|
* @since 1.0.0
|
|
147
103
|
*/
|
|
148
|
-
readonly [
|
|
104
|
+
readonly [MessageTypeId]: MessageTypeId = MessageTypeId
|
|
105
|
+
}
|
|
149
106
|
|
|
107
|
+
/**
|
|
108
|
+
* @since 1.0.0
|
|
109
|
+
* @category Models
|
|
110
|
+
*/
|
|
111
|
+
export class ToolMessage extends Schema.TaggedClass<ToolMessage>(
|
|
112
|
+
"@effect/ai/AiInput/Message/ToolMessage"
|
|
113
|
+
)("ToolMessage", {
|
|
114
|
+
parts: Schema.Array(Schema.suspend(() => ToolMessagePart))
|
|
115
|
+
}) {
|
|
150
116
|
/**
|
|
151
117
|
* @since 1.0.0
|
|
152
118
|
*/
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
break
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
return new ImagePart({
|
|
184
|
-
image: { data, contentType },
|
|
185
|
-
quality
|
|
186
|
-
}, constDisableValidation)
|
|
187
|
-
})
|
|
188
|
-
)
|
|
189
|
-
}
|
|
119
|
+
readonly [MessageTypeId]: MessageTypeId = MessageTypeId
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @since 1.0.0
|
|
124
|
+
* @category Models
|
|
125
|
+
*/
|
|
126
|
+
export const Message: Schema.Union<[
|
|
127
|
+
typeof UserMessage,
|
|
128
|
+
typeof AssistantMessage,
|
|
129
|
+
typeof ToolMessage
|
|
130
|
+
]> = Schema.Union(
|
|
131
|
+
UserMessage,
|
|
132
|
+
AssistantMessage,
|
|
133
|
+
ToolMessage
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* @since 1.0.0
|
|
138
|
+
* @category Models
|
|
139
|
+
*/
|
|
140
|
+
export type Message = typeof Message.Type
|
|
141
|
+
|
|
142
|
+
// =============================================================================
|
|
143
|
+
// Part
|
|
144
|
+
// =============================================================================
|
|
190
145
|
|
|
146
|
+
/**
|
|
147
|
+
* @since 1.0.0
|
|
148
|
+
* @category Type Ids
|
|
149
|
+
*/
|
|
150
|
+
export const PartTypeId = Symbol.for("@effect/ai/AiInput/Message/Part")
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* @since 1.0.0
|
|
154
|
+
* @category Type Ids
|
|
155
|
+
*/
|
|
156
|
+
export type PartTypeId = typeof PartTypeId
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Represents a text part of a message.
|
|
160
|
+
*
|
|
161
|
+
* @since 1.0.0
|
|
162
|
+
* @category Models
|
|
163
|
+
*/
|
|
164
|
+
export class TextPart extends Schema.TaggedClass<TextPart>(
|
|
165
|
+
"@effect/ai/AiInput/TextPart"
|
|
166
|
+
)("TextPart", {
|
|
167
|
+
/**
|
|
168
|
+
* The text content.
|
|
169
|
+
*/
|
|
170
|
+
text: Schema.String
|
|
171
|
+
}) {
|
|
191
172
|
/**
|
|
192
173
|
* @since 1.0.0
|
|
193
174
|
*/
|
|
194
|
-
|
|
195
|
-
return Effect.promise(() => blob.arrayBuffer()).pipe(
|
|
196
|
-
Effect.map((buffer) =>
|
|
197
|
-
new ImagePart({
|
|
198
|
-
image: {
|
|
199
|
-
contentType: blob.type,
|
|
200
|
-
data: new Uint8Array(buffer)
|
|
201
|
-
},
|
|
202
|
-
quality
|
|
203
|
-
})
|
|
204
|
-
)
|
|
205
|
-
)
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
get asBase64(): string {
|
|
209
|
-
return Encoding.encodeBase64(this.image.data)
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
get asDataUri(): string {
|
|
213
|
-
return `data:${this.image.contentType};base64,${this.asBase64}`
|
|
214
|
-
}
|
|
175
|
+
readonly [PartTypeId]: PartTypeId = PartTypeId
|
|
215
176
|
}
|
|
216
177
|
|
|
217
178
|
/**
|
|
179
|
+
* Represents an image part of a message with binary image data.
|
|
180
|
+
*
|
|
218
181
|
* @since 1.0.0
|
|
219
|
-
* @category
|
|
182
|
+
* @category Models
|
|
220
183
|
*/
|
|
221
|
-
export class
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
184
|
+
export class ImagePart extends Schema.TaggedClass<ImagePart>(
|
|
185
|
+
"@effect/ai/AiInput/ImagePart"
|
|
186
|
+
)("ImagePart", {
|
|
187
|
+
/**
|
|
188
|
+
* The binary image data.
|
|
189
|
+
*/
|
|
190
|
+
data: Schema.Uint8ArrayFromBase64,
|
|
191
|
+
/**
|
|
192
|
+
* The optional MIME type for the image.
|
|
193
|
+
*/
|
|
194
|
+
mediaType: Schema.optional(Schema.String)
|
|
225
195
|
}) {
|
|
226
196
|
/**
|
|
227
197
|
* @since 1.0.0
|
|
@@ -230,15 +200,19 @@ export class ToolCallPart extends Schema_.TaggedClass<ToolCallPart>("@effect/ai/
|
|
|
230
200
|
}
|
|
231
201
|
|
|
232
202
|
/**
|
|
203
|
+
* Represents an image part of a message with a URL pointing to the image.
|
|
204
|
+
*
|
|
233
205
|
* @since 1.0.0
|
|
234
|
-
* @category
|
|
206
|
+
* @category Models
|
|
235
207
|
*/
|
|
236
|
-
export class
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
208
|
+
export class ImageUrlPart extends Schema.TaggedClass<ImageUrlPart>(
|
|
209
|
+
"@effect/ai/AiInput/ImageUrlPart"
|
|
210
|
+
)("ImageUrlPart", {
|
|
211
|
+
/**
|
|
212
|
+
* The URL that points to the image.
|
|
213
|
+
*/
|
|
214
|
+
url: Schema.URL
|
|
215
|
+
}) {
|
|
242
216
|
/**
|
|
243
217
|
* @since 1.0.0
|
|
244
218
|
*/
|
|
@@ -246,231 +220,378 @@ export class ToolCallResolvedPart
|
|
|
246
220
|
}
|
|
247
221
|
|
|
248
222
|
/**
|
|
223
|
+
* Represents a file part of a message with binary file data.
|
|
224
|
+
*
|
|
249
225
|
* @since 1.0.0
|
|
250
|
-
* @category
|
|
226
|
+
* @category Models
|
|
251
227
|
*/
|
|
252
|
-
export
|
|
228
|
+
export class FilePart extends Schema.TaggedClass<FilePart>(
|
|
229
|
+
"@effect/ai/AiInput/FilePart"
|
|
230
|
+
)("FilePart", {
|
|
231
|
+
/**
|
|
232
|
+
* The binary file data.
|
|
233
|
+
*/
|
|
234
|
+
data: Schema.Uint8ArrayFromBase64,
|
|
235
|
+
/**
|
|
236
|
+
* The optional name of the file.
|
|
237
|
+
*/
|
|
238
|
+
name: Schema.optional(Schema.String),
|
|
239
|
+
/**
|
|
240
|
+
* The optional MIME type for the image.
|
|
241
|
+
*/
|
|
242
|
+
mediaType: Schema.optional(Schema.String)
|
|
243
|
+
}) {
|
|
244
|
+
/**
|
|
245
|
+
* @since 1.0.0
|
|
246
|
+
*/
|
|
247
|
+
readonly [PartTypeId]: PartTypeId = PartTypeId
|
|
248
|
+
}
|
|
253
249
|
|
|
254
250
|
/**
|
|
251
|
+
* Represents a file part of a message with a URL pointing to the file.
|
|
252
|
+
*
|
|
255
253
|
* @since 1.0.0
|
|
256
|
-
* @category
|
|
254
|
+
* @category Models
|
|
257
255
|
*/
|
|
258
|
-
export
|
|
256
|
+
export class FileUrlPart extends Schema.TaggedClass<FileUrlPart>(
|
|
257
|
+
"@effect/ai/AiInput/FileUrlPart"
|
|
258
|
+
)("FileUrlPart", {
|
|
259
|
+
/**
|
|
260
|
+
* The URL that points to the file.
|
|
261
|
+
*/
|
|
262
|
+
url: Schema.URL
|
|
263
|
+
}) {
|
|
264
|
+
/**
|
|
265
|
+
* @since 1.0.0
|
|
266
|
+
*/
|
|
267
|
+
readonly [PartTypeId]: PartTypeId = PartTypeId
|
|
268
|
+
}
|
|
259
269
|
|
|
260
270
|
/**
|
|
271
|
+
* Represents a part of a message containing reasoning that the model used to
|
|
272
|
+
* generate its output.
|
|
273
|
+
*
|
|
261
274
|
* @since 1.0.0
|
|
262
|
-
* @category
|
|
275
|
+
* @category Models
|
|
263
276
|
*/
|
|
264
|
-
export
|
|
277
|
+
export class ReasoningPart extends Schema.TaggedClass<ReasoningPart>(
|
|
278
|
+
"@effect/ai/AiInput/ReasoningPart"
|
|
279
|
+
)("ReasoningPart", {
|
|
280
|
+
/**
|
|
281
|
+
* The reasoning text that the model used to return the output.
|
|
282
|
+
*/
|
|
283
|
+
reasoningText: Schema.String,
|
|
284
|
+
/**
|
|
285
|
+
* An optional signature which verifies that the reasoning text was generated
|
|
286
|
+
* by the model.
|
|
287
|
+
*/
|
|
288
|
+
signature: Schema.optional(Schema.String)
|
|
289
|
+
}) {
|
|
265
290
|
/**
|
|
266
291
|
* @since 1.0.0
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
export type Schema = Schema_.Union<[
|
|
270
|
-
typeof TextPart,
|
|
271
|
-
typeof ToolCallPart,
|
|
272
|
-
typeof ToolCallResolvedPart,
|
|
273
|
-
typeof ImagePart,
|
|
274
|
-
typeof ImageUrlPart
|
|
275
|
-
]>
|
|
292
|
+
*/
|
|
293
|
+
readonly [PartTypeId]: PartTypeId = PartTypeId
|
|
276
294
|
}
|
|
277
295
|
|
|
278
296
|
/**
|
|
297
|
+
* Represents a part of a message containing content in the model's reasoning
|
|
298
|
+
* that was encrypted by the model provider for safety reasons.
|
|
299
|
+
*
|
|
279
300
|
* @since 1.0.0
|
|
280
|
-
* @category
|
|
301
|
+
* @category Models
|
|
281
302
|
*/
|
|
282
|
-
export
|
|
303
|
+
export class RedactedReasoningPart extends Schema.TaggedClass<RedactedReasoningPart>(
|
|
304
|
+
"@effect/ai/AiInput/RedactedReasoningPart"
|
|
305
|
+
)("RedactedReasoningPart", {
|
|
306
|
+
/**
|
|
307
|
+
* The content in the reasoning that was encrypted by the model provider for
|
|
308
|
+
* safety reasons.
|
|
309
|
+
*/
|
|
310
|
+
redactedText: Schema.String
|
|
311
|
+
}) {
|
|
312
|
+
/**
|
|
313
|
+
* @since 1.0.0
|
|
314
|
+
*/
|
|
315
|
+
readonly [PartTypeId]: PartTypeId = PartTypeId
|
|
316
|
+
}
|
|
283
317
|
|
|
284
318
|
/**
|
|
319
|
+
* Represents the identifier generated by a model when a tool call is requested.
|
|
320
|
+
*
|
|
285
321
|
* @since 1.0.0
|
|
286
|
-
* @category
|
|
322
|
+
* @category Models
|
|
287
323
|
*/
|
|
288
|
-
export const
|
|
324
|
+
export const ToolCallId: Schema.brand<typeof Schema.String, "@effect/ai/ToolCallId"> = InternalCommon.ToolCallId
|
|
289
325
|
|
|
290
326
|
/**
|
|
291
327
|
* @since 1.0.0
|
|
292
|
-
* @category
|
|
328
|
+
* @category Models
|
|
293
329
|
*/
|
|
294
|
-
export type
|
|
330
|
+
export type ToolCallId = typeof ToolCallId.Type
|
|
295
331
|
|
|
296
332
|
/**
|
|
333
|
+
* Represents a part of a message containing a tool call that the model has
|
|
334
|
+
* requested invocation of.
|
|
335
|
+
*
|
|
297
336
|
* @since 1.0.0
|
|
298
|
-
* @category
|
|
337
|
+
* @category Models
|
|
299
338
|
*/
|
|
300
|
-
export class
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
}) {
|
|
339
|
+
export class ToolCallPart extends Schema.TaggedClass<ToolCallPart>(
|
|
340
|
+
"@effect/ai/AiInput/ToolCallPart"
|
|
341
|
+
)("ToolCallPart", {
|
|
304
342
|
/**
|
|
305
|
-
*
|
|
343
|
+
* The identifier generated by a model when requesting a tool call.
|
|
306
344
|
*/
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* @since 1.0.0
|
|
310
|
-
*/
|
|
311
|
-
static is(u: unknown): u is Message {
|
|
312
|
-
return Predicate.hasProperty(u, MessageTypeId)
|
|
313
|
-
}
|
|
345
|
+
id: ToolCallId,
|
|
314
346
|
/**
|
|
315
|
-
*
|
|
347
|
+
* The name of the tool to call.
|
|
316
348
|
*/
|
|
317
|
-
|
|
318
|
-
if (typeof input === "string") {
|
|
319
|
-
return new Message({ role, parts: Chunk.of(TextPart.fromContent(input)) }, constDisableValidation)
|
|
320
|
-
} else if (isPart(input)) {
|
|
321
|
-
return new Message({ role, parts: Chunk.of(input) }, constDisableValidation)
|
|
322
|
-
}
|
|
323
|
-
return new Message({ role, parts: Chunk.fromIterable(input) }, constDisableValidation)
|
|
324
|
-
}
|
|
349
|
+
name: Schema.String,
|
|
325
350
|
/**
|
|
326
|
-
*
|
|
351
|
+
* The arguments to call the tool with as a JSON-serializable object that
|
|
352
|
+
* matches the tool call input schema.
|
|
327
353
|
*/
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
return Option.none()
|
|
331
|
-
}
|
|
332
|
-
return Option.some(
|
|
333
|
-
new Message({
|
|
334
|
-
role: response.role,
|
|
335
|
-
parts: Chunk.map(response.parts, (part) => {
|
|
336
|
-
switch (part._tag) {
|
|
337
|
-
case "Text": {
|
|
338
|
-
return TextPart.fromContent(part.content)
|
|
339
|
-
}
|
|
340
|
-
case "ToolCall": {
|
|
341
|
-
return new ToolCallPart(part, constDisableValidation)
|
|
342
|
-
}
|
|
343
|
-
case "ImageUrl": {
|
|
344
|
-
return new ImageUrlPart(part, constDisableValidation)
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
})
|
|
348
|
-
}, constDisableValidation)
|
|
349
|
-
)
|
|
350
|
-
}
|
|
354
|
+
params: Schema.Unknown
|
|
355
|
+
}) {
|
|
351
356
|
/**
|
|
352
357
|
* @since 1.0.0
|
|
353
358
|
*/
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
}
|
|
359
|
-
const toolPartsChunk = Chunk.unsafeFromArray(toolParts)
|
|
360
|
-
return Option.match(Message.fromResponse(response.response), {
|
|
361
|
-
onNone: () => new Message({ role: AiRole.model, parts: toolPartsChunk }, constDisableValidation),
|
|
362
|
-
onSome: (message) =>
|
|
363
|
-
new Message({
|
|
364
|
-
role: message.role,
|
|
365
|
-
parts: Chunk.appendAll(message.parts, toolPartsChunk)
|
|
366
|
-
}, constDisableValidation)
|
|
367
|
-
})
|
|
359
|
+
readonly [PartTypeId]: PartTypeId = PartTypeId
|
|
360
|
+
|
|
361
|
+
constructor(props: any, options?: Schema.MakeOptions) {
|
|
362
|
+
super(props, options)
|
|
368
363
|
}
|
|
369
364
|
}
|
|
370
365
|
|
|
371
366
|
/**
|
|
367
|
+
* Represents a part of a message containing the results of tool calls that the
|
|
368
|
+
* model requested invocation of.
|
|
369
|
+
*
|
|
372
370
|
* @since 1.0.0
|
|
373
|
-
* @category
|
|
371
|
+
* @category Models
|
|
374
372
|
*/
|
|
375
|
-
export
|
|
373
|
+
export class ToolCallResultPart extends Schema.TaggedClass<ToolCallResultPart>(
|
|
374
|
+
"@effect/ai/AiInput/ToolCallResultPart"
|
|
375
|
+
)("ToolCallResultPart", {
|
|
376
|
+
/**
|
|
377
|
+
* The identifier generated by a model when requesting a tool call.
|
|
378
|
+
*/
|
|
379
|
+
id: ToolCallId,
|
|
380
|
+
/**
|
|
381
|
+
* The result of the tool call as a JSON-serializable object.
|
|
382
|
+
*/
|
|
383
|
+
result: Schema.Unknown
|
|
384
|
+
}) {
|
|
376
385
|
/**
|
|
377
386
|
* @since 1.0.0
|
|
378
|
-
* @category message
|
|
379
387
|
*/
|
|
380
|
-
|
|
388
|
+
readonly [PartTypeId]: PartTypeId = PartTypeId
|
|
381
389
|
}
|
|
382
390
|
|
|
383
391
|
/**
|
|
392
|
+
* The valid parts of a user message.
|
|
393
|
+
*
|
|
384
394
|
* @since 1.0.0
|
|
385
|
-
* @category
|
|
395
|
+
* @category Models
|
|
386
396
|
*/
|
|
387
|
-
export const
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
onNone: Chunk.empty,
|
|
401
|
-
onSome: Chunk.of
|
|
402
|
-
})
|
|
403
|
-
} else if (WithResolved.is(input)) {
|
|
404
|
-
return Chunk.of(Message.fromWithResolved(input))
|
|
405
|
-
} else if (Message.is(input)) {
|
|
406
|
-
return Chunk.of(input)
|
|
407
|
-
}
|
|
408
|
-
return Chunk.of(Message.fromInput(input, options?.role))
|
|
409
|
-
}
|
|
397
|
+
export const UserMessagePart: Schema.Union<[
|
|
398
|
+
typeof TextPart,
|
|
399
|
+
typeof ImagePart,
|
|
400
|
+
typeof ImageUrlPart,
|
|
401
|
+
typeof FilePart,
|
|
402
|
+
typeof FileUrlPart
|
|
403
|
+
]> = Schema.Union(
|
|
404
|
+
TextPart,
|
|
405
|
+
ImagePart,
|
|
406
|
+
ImageUrlPart,
|
|
407
|
+
FilePart,
|
|
408
|
+
FileUrlPart
|
|
409
|
+
)
|
|
410
410
|
|
|
411
411
|
/**
|
|
412
412
|
* @since 1.0.0
|
|
413
|
-
* @category
|
|
413
|
+
* @category Models
|
|
414
414
|
*/
|
|
415
|
-
export
|
|
415
|
+
export type UserMessagePart = typeof UserMessagePart.Type
|
|
416
416
|
|
|
417
417
|
/**
|
|
418
|
+
* The valid parts of an assistant message.
|
|
419
|
+
*
|
|
418
420
|
* @since 1.0.0
|
|
419
|
-
* @category
|
|
421
|
+
* @category Models
|
|
420
422
|
*/
|
|
421
|
-
export const
|
|
423
|
+
export const AssistantMessagePart: Schema.Union<[
|
|
424
|
+
typeof TextPart,
|
|
425
|
+
typeof ReasoningPart,
|
|
426
|
+
typeof RedactedReasoningPart,
|
|
427
|
+
typeof ToolCallPart
|
|
428
|
+
]> = Schema.Union(
|
|
429
|
+
TextPart,
|
|
430
|
+
ReasoningPart,
|
|
431
|
+
RedactedReasoningPart,
|
|
432
|
+
ToolCallPart
|
|
433
|
+
)
|
|
422
434
|
|
|
423
435
|
/**
|
|
424
436
|
* @since 1.0.0
|
|
425
|
-
* @category
|
|
437
|
+
* @category Models
|
|
426
438
|
*/
|
|
427
|
-
export
|
|
439
|
+
export type AssistantMessagePart = typeof AssistantMessagePart.Type
|
|
428
440
|
|
|
429
441
|
/**
|
|
442
|
+
* The valid parts of a tool message.
|
|
443
|
+
*
|
|
430
444
|
* @since 1.0.0
|
|
431
|
-
* @category
|
|
445
|
+
* @category Models
|
|
432
446
|
*/
|
|
433
|
-
export
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
447
|
+
export const ToolMessagePart: typeof ToolCallResultPart = ToolCallResultPart
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* @since 1.0.0
|
|
451
|
+
* @category Models
|
|
452
|
+
*/
|
|
453
|
+
export type ToolMessagePart = typeof ToolMessagePart.Type
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* @since 1.0.0
|
|
457
|
+
* @category Guards
|
|
458
|
+
*/
|
|
459
|
+
export const is = (u: unknown): u is AiInput => Predicate.hasProperty(u, TypeId)
|
|
441
460
|
|
|
442
461
|
/**
|
|
443
462
|
* @since 1.0.0
|
|
444
|
-
* @category
|
|
463
|
+
* @category Guards
|
|
445
464
|
*/
|
|
446
|
-
export
|
|
465
|
+
export const isMessage = (u: unknown): u is Message => Predicate.hasProperty(u, MessageTypeId)
|
|
447
466
|
|
|
448
467
|
/**
|
|
449
468
|
* @since 1.0.0
|
|
450
|
-
* @category
|
|
469
|
+
* @category Guards
|
|
451
470
|
*/
|
|
452
|
-
export
|
|
453
|
-
|
|
454
|
-
string
|
|
455
|
-
>() {}
|
|
471
|
+
export const isPart = (u: unknown): u is UserMessagePart | AssistantMessagePart | ToolMessagePart =>
|
|
472
|
+
Predicate.hasProperty(u, PartTypeId)
|
|
456
473
|
|
|
457
474
|
/**
|
|
458
475
|
* @since 1.0.0
|
|
459
|
-
* @category
|
|
476
|
+
* @category Constructors
|
|
460
477
|
*/
|
|
461
|
-
export const
|
|
478
|
+
export const empty: AiInput = new AiInput({ messages: [] })
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Constructs a new `AiInput` from raw user input.
|
|
482
|
+
*
|
|
483
|
+
* @since 1.0.0
|
|
484
|
+
* @category Constructors
|
|
485
|
+
*/
|
|
486
|
+
export const make = (input: Raw): AiInput => {
|
|
487
|
+
if (Predicate.isString(input)) {
|
|
488
|
+
const textPart = new TextPart({ text: input })
|
|
489
|
+
const message = new UserMessage({ parts: [textPart] })
|
|
490
|
+
return new AiInput({ messages: [message] })
|
|
491
|
+
}
|
|
492
|
+
if (isMessage(input)) {
|
|
493
|
+
return new AiInput({ messages: [input] })
|
|
494
|
+
}
|
|
495
|
+
if (Predicate.isIterable(input)) {
|
|
496
|
+
return new AiInput({ messages: Array.from(input) })
|
|
497
|
+
}
|
|
498
|
+
if (is(input)) {
|
|
499
|
+
return input
|
|
500
|
+
}
|
|
501
|
+
if (AiResponse.isStructured(input)) {
|
|
502
|
+
const assistantMessages = fromResponse(input).messages
|
|
503
|
+
const toolPart = new ToolCallResultPart({
|
|
504
|
+
id: input.id,
|
|
505
|
+
result: input.value
|
|
506
|
+
})
|
|
507
|
+
const toolMessage = new ToolMessage({ parts: [toolPart] })
|
|
508
|
+
return new AiInput({ messages: [...assistantMessages, toolMessage] })
|
|
509
|
+
}
|
|
510
|
+
if (AiResponse.hasToolCallResults(input)) {
|
|
511
|
+
const assistantMessages = fromResponse(input).messages
|
|
512
|
+
const toolParts: Array<ToolCallResultPart> = []
|
|
513
|
+
for (const [id, result] of input.encodedResults) {
|
|
514
|
+
toolParts.push(new ToolCallResultPart({ id, result }))
|
|
515
|
+
}
|
|
516
|
+
const toolMessage = new ToolMessage({ parts: toolParts })
|
|
517
|
+
return new AiInput({ messages: [...assistantMessages, toolMessage] })
|
|
518
|
+
}
|
|
519
|
+
return fromResponse(input)
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
const EXCLUDED_RESPONSE_PARTS: Array<AiResponse.Part["_tag"]> = [
|
|
523
|
+
"MetadataPart",
|
|
524
|
+
"ReasoningPart",
|
|
525
|
+
"RedactedReasoningPart",
|
|
526
|
+
"FinishPart"
|
|
527
|
+
]
|
|
528
|
+
|
|
529
|
+
const validResponseParts = (part: AiResponse.Part): part is AiResponse.TextPart | AiResponse.ToolCallPart =>
|
|
530
|
+
!EXCLUDED_RESPONSE_PARTS.includes(part._tag)
|
|
531
|
+
|
|
532
|
+
const fromResponse = (
|
|
533
|
+
response: AiResponse.AiResponse
|
|
534
|
+
): AiInput => {
|
|
535
|
+
if (response.parts.length === 0) {
|
|
536
|
+
return empty
|
|
537
|
+
}
|
|
538
|
+
const parts = response.parts
|
|
539
|
+
.filter(validResponseParts)
|
|
540
|
+
.map((part) =>
|
|
541
|
+
part._tag === "TextPart"
|
|
542
|
+
? new TextPart({ text: part.text })
|
|
543
|
+
: new ToolCallPart({
|
|
544
|
+
id: part.id,
|
|
545
|
+
name: part.name,
|
|
546
|
+
params: part.params
|
|
547
|
+
})
|
|
548
|
+
)
|
|
549
|
+
const message = new AssistantMessage({ parts })
|
|
550
|
+
return new AiInput({ messages: [message] })
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Concatenates the messages of one `AiInput` onto the messages of another,
|
|
555
|
+
* creating a new `AiInput` with the messages from both.
|
|
556
|
+
*
|
|
557
|
+
* @since 1.0.0
|
|
558
|
+
* @category Combination
|
|
559
|
+
*/
|
|
560
|
+
export const concat: {
|
|
462
561
|
/**
|
|
562
|
+
* Concatenates the messages of one `AiInput` onto the messages of another,
|
|
563
|
+
* creating a new `AiInput` with the messages from both.
|
|
564
|
+
*
|
|
463
565
|
* @since 1.0.0
|
|
464
|
-
* @category
|
|
566
|
+
* @category Combination
|
|
465
567
|
*/
|
|
466
|
-
(
|
|
568
|
+
(other: AiInput): (self: AiInput) => AiInput
|
|
467
569
|
/**
|
|
570
|
+
* Concatenates the messages of one `AiInput` onto the messages of another,
|
|
571
|
+
* creating a new `AiInput` with the messages from both.
|
|
572
|
+
*
|
|
468
573
|
* @since 1.0.0
|
|
469
|
-
* @category
|
|
574
|
+
* @category Combination
|
|
470
575
|
*/
|
|
471
|
-
|
|
472
|
-
} = dual
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
576
|
+
(self: AiInput, other: AiInput): AiInput
|
|
577
|
+
} = dual<
|
|
578
|
+
/**
|
|
579
|
+
* Concatenates the messages of one `AiInput` onto the messages of another,
|
|
580
|
+
* creating a new `AiInput` with the messages from both.
|
|
581
|
+
*
|
|
582
|
+
* @since 1.0.0
|
|
583
|
+
* @category Combination
|
|
584
|
+
*/
|
|
585
|
+
(other: AiInput) => (self: AiInput) => AiInput,
|
|
586
|
+
/**
|
|
587
|
+
* Concatenates the messages of one `AiInput` onto the messages of another,
|
|
588
|
+
* creating a new `AiInput` with the messages from both.
|
|
589
|
+
*
|
|
590
|
+
* @since 1.0.0
|
|
591
|
+
* @category Combination
|
|
592
|
+
*/
|
|
593
|
+
(self: AiInput, other: AiInput) => AiInput
|
|
594
|
+
>(2, (self, other) =>
|
|
595
|
+
AiInput.make({
|
|
596
|
+
messages: [...self.messages, ...other.messages]
|
|
597
|
+
}))
|