@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.
Files changed (134) hide show
  1. package/AiEmbeddingModel/package.json +6 -0
  2. package/AiLanguageModel/package.json +6 -0
  3. package/AiTool/package.json +6 -0
  4. package/dist/cjs/AiChat.js +65 -86
  5. package/dist/cjs/AiChat.js.map +1 -1
  6. package/dist/cjs/{Embeddings.js → AiEmbeddingModel.js} +12 -12
  7. package/dist/cjs/AiEmbeddingModel.js.map +1 -0
  8. package/dist/cjs/AiError.js +8 -1
  9. package/dist/cjs/AiError.js.map +1 -1
  10. package/dist/cjs/AiInput.js +335 -248
  11. package/dist/cjs/AiInput.js.map +1 -1
  12. package/dist/cjs/AiLanguageModel.js +311 -0
  13. package/dist/cjs/AiLanguageModel.js.map +1 -0
  14. package/dist/cjs/AiModel.js +11 -5
  15. package/dist/cjs/AiModel.js.map +1 -1
  16. package/dist/cjs/AiPlan.js +10 -3
  17. package/dist/cjs/AiPlan.js.map +1 -1
  18. package/dist/cjs/AiResponse.js +481 -165
  19. package/dist/cjs/AiResponse.js.map +1 -1
  20. package/dist/cjs/AiTelemetry.js +10 -3
  21. package/dist/cjs/AiTelemetry.js.map +1 -1
  22. package/dist/cjs/AiTool.js +93 -0
  23. package/dist/cjs/AiTool.js.map +1 -0
  24. package/dist/cjs/AiToolkit.js +121 -98
  25. package/dist/cjs/AiToolkit.js.map +1 -1
  26. package/dist/cjs/Tokenizer.js +14 -16
  27. package/dist/cjs/Tokenizer.js.map +1 -1
  28. package/dist/cjs/index.js +7 -9
  29. package/dist/cjs/internal/aiPlan.js +6 -9
  30. package/dist/cjs/internal/aiPlan.js.map +1 -1
  31. package/dist/cjs/internal/common.js +22 -0
  32. package/dist/cjs/internal/common.js.map +1 -0
  33. package/dist/dts/AiChat.d.ts +58 -44
  34. package/dist/dts/AiChat.d.ts.map +1 -1
  35. package/dist/dts/{Embeddings.d.ts → AiEmbeddingModel.d.ts} +13 -14
  36. package/dist/dts/AiEmbeddingModel.d.ts.map +1 -0
  37. package/dist/dts/AiError.d.ts +4 -3
  38. package/dist/dts/AiError.d.ts.map +1 -1
  39. package/dist/dts/AiInput.d.ts +441 -146
  40. package/dist/dts/AiInput.d.ts.map +1 -1
  41. package/dist/dts/AiLanguageModel.d.ts +263 -0
  42. package/dist/dts/AiLanguageModel.d.ts.map +1 -0
  43. package/dist/dts/AiModel.d.ts +21 -20
  44. package/dist/dts/AiModel.d.ts.map +1 -1
  45. package/dist/dts/AiPlan.d.ts +90 -26
  46. package/dist/dts/AiPlan.d.ts.map +1 -1
  47. package/dist/dts/AiResponse.d.ts +711 -100
  48. package/dist/dts/AiResponse.d.ts.map +1 -1
  49. package/dist/dts/AiTelemetry.d.ts +175 -157
  50. package/dist/dts/AiTelemetry.d.ts.map +1 -1
  51. package/dist/dts/AiTool.d.ts +288 -0
  52. package/dist/dts/AiTool.d.ts.map +1 -0
  53. package/dist/dts/AiToolkit.d.ts +50 -111
  54. package/dist/dts/AiToolkit.d.ts.map +1 -1
  55. package/dist/dts/Tokenizer.d.ts +8 -6
  56. package/dist/dts/Tokenizer.d.ts.map +1 -1
  57. package/dist/dts/index.d.ts +8 -12
  58. package/dist/dts/index.d.ts.map +1 -1
  59. package/dist/dts/internal/common.d.ts +2 -0
  60. package/dist/dts/internal/common.d.ts.map +1 -0
  61. package/dist/esm/AiChat.js +62 -83
  62. package/dist/esm/AiChat.js.map +1 -1
  63. package/dist/esm/{Embeddings.js → AiEmbeddingModel.js} +10 -10
  64. package/dist/esm/AiEmbeddingModel.js.map +1 -0
  65. package/dist/esm/AiError.js +8 -1
  66. package/dist/esm/AiError.js.map +1 -1
  67. package/dist/esm/AiInput.js +316 -238
  68. package/dist/esm/AiInput.js.map +1 -1
  69. package/dist/esm/AiLanguageModel.js +300 -0
  70. package/dist/esm/AiLanguageModel.js.map +1 -0
  71. package/dist/esm/AiModel.js +11 -5
  72. package/dist/esm/AiModel.js.map +1 -1
  73. package/dist/esm/AiPlan.js +8 -2
  74. package/dist/esm/AiPlan.js.map +1 -1
  75. package/dist/esm/AiResponse.js +467 -162
  76. package/dist/esm/AiResponse.js.map +1 -1
  77. package/dist/esm/AiTelemetry.js +8 -2
  78. package/dist/esm/AiTelemetry.js.map +1 -1
  79. package/dist/esm/AiTool.js +82 -0
  80. package/dist/esm/AiTool.js.map +1 -0
  81. package/dist/esm/AiToolkit.js +118 -96
  82. package/dist/esm/AiToolkit.js.map +1 -1
  83. package/dist/esm/Tokenizer.js +14 -16
  84. package/dist/esm/Tokenizer.js.map +1 -1
  85. package/dist/esm/index.js +8 -12
  86. package/dist/esm/index.js.map +1 -1
  87. package/dist/esm/internal/aiPlan.js +4 -7
  88. package/dist/esm/internal/aiPlan.js.map +1 -1
  89. package/dist/esm/internal/common.js +14 -0
  90. package/dist/esm/internal/common.js.map +1 -0
  91. package/package.json +28 -36
  92. package/src/AiChat.ts +182 -207
  93. package/src/{Embeddings.ts → AiEmbeddingModel.ts} +19 -18
  94. package/src/AiError.ts +8 -1
  95. package/src/AiInput.ts +434 -313
  96. package/src/AiLanguageModel.ts +569 -0
  97. package/src/AiModel.ts +47 -29
  98. package/src/AiPlan.ts +102 -30
  99. package/src/AiResponse.ts +743 -187
  100. package/src/AiTelemetry.ts +214 -197
  101. package/src/AiTool.ts +496 -0
  102. package/src/AiToolkit.ts +200 -240
  103. package/src/Tokenizer.ts +18 -22
  104. package/src/index.ts +9 -14
  105. package/src/internal/aiPlan.ts +12 -14
  106. package/src/internal/common.ts +12 -0
  107. package/AiModels/package.json +0 -6
  108. package/AiRole/package.json +0 -6
  109. package/Completions/package.json +0 -6
  110. package/Embeddings/package.json +0 -6
  111. package/dist/cjs/AiModels.js +0 -54
  112. package/dist/cjs/AiModels.js.map +0 -1
  113. package/dist/cjs/AiRole.js +0 -106
  114. package/dist/cjs/AiRole.js.map +0 -1
  115. package/dist/cjs/Completions.js +0 -256
  116. package/dist/cjs/Completions.js.map +0 -1
  117. package/dist/cjs/Embeddings.js.map +0 -1
  118. package/dist/dts/AiModels.d.ts +0 -34
  119. package/dist/dts/AiModels.d.ts.map +0 -1
  120. package/dist/dts/AiRole.d.ts +0 -111
  121. package/dist/dts/AiRole.d.ts.map +0 -1
  122. package/dist/dts/Completions.d.ts +0 -128
  123. package/dist/dts/Completions.d.ts.map +0 -1
  124. package/dist/dts/Embeddings.d.ts.map +0 -1
  125. package/dist/esm/AiModels.js +0 -44
  126. package/dist/esm/AiModels.js.map +0 -1
  127. package/dist/esm/AiRole.js +0 -93
  128. package/dist/esm/AiRole.js.map +0 -1
  129. package/dist/esm/Completions.js +0 -245
  130. package/dist/esm/Completions.js.map +0 -1
  131. package/dist/esm/Embeddings.js.map +0 -1
  132. package/src/AiModels.ts +0 -77
  133. package/src/AiRole.ts +0 -122
  134. package/src/Completions.ts +0 -434
@@ -1,175 +1,167 @@
1
- import * as FileSystem from "@effect/platform/FileSystem";
2
- import * as Path from "@effect/platform/Path";
3
- import * as Chunk from "effect/Chunk";
4
- import * as Context from "effect/Context";
5
- import * as Effect from "effect/Effect";
6
- import * as Encoding from "effect/Encoding";
1
+ /**
2
+ * @since 1.0.0
3
+ */
7
4
  import { dual } from "effect/Function";
8
- import * as Option from "effect/Option";
9
- import * as ParseResult from "effect/ParseResult";
10
5
  import * as Predicate from "effect/Predicate";
11
- import * as Schema_ from "effect/Schema";
12
- import { AiResponse, ToolCallId, WithResolved } from "./AiResponse.js";
13
- import * as AiRole from "./AiRole.js";
14
- const constDisableValidation = {
15
- disableValidation: true
16
- };
6
+ import * as Schema from "effect/Schema";
7
+ import * as AiResponse from "./AiResponse.js";
8
+ import * as InternalCommon from "./internal/common.js";
17
9
  /**
18
10
  * @since 1.0.0
19
- * @category parts
11
+ * @category Type Ids
20
12
  */
21
- export const PartTypeId = /*#__PURE__*/Symbol("@effect/ai/AiInput/Part");
13
+ export const TypeId = /*#__PURE__*/Symbol.for("@effect/ai/AiInput");
22
14
  /**
15
+ * Represents input to a large language model.
16
+ *
23
17
  * @since 1.0.0
24
- * @category parts
18
+ * @category Models
25
19
  */
26
- export class TextPart extends /*#__PURE__*/Schema_.TaggedClass("@effect/ai/AiInput/TextPart")("Text", {
27
- content: Schema_.String
20
+ export class AiInput extends /*#__PURE__*/Schema.Class("@effect/ai/AiInput")({
21
+ messages: /*#__PURE__*/Schema.Array( /*#__PURE__*/Schema.suspend(() => Message))
28
22
  }) {
29
23
  /**
30
24
  * @since 1.0.0
31
25
  */
32
- [PartTypeId] = PartTypeId;
26
+ [TypeId] = TypeId;
27
+ }
28
+ /**
29
+ * @since 1.0.0
30
+ * @category Models
31
+ */
32
+ export const FromJson = /*#__PURE__*/Schema.parseJson(AiInput);
33
+ // =============================================================================
34
+ // Message
35
+ // =============================================================================
36
+ /**
37
+ * @since 1.0.0
38
+ * @category Type Ids
39
+ */
40
+ export const MessageTypeId = /*#__PURE__*/Symbol.for("@effect/ai/AiInput/Message");
41
+ /**
42
+ * @since 1.0.0
43
+ * @category Models
44
+ */
45
+ export class UserMessage extends /*#__PURE__*/Schema.TaggedClass("@effect/ai/AiInput/Message/UserMessage")("UserMessage", {
46
+ parts: /*#__PURE__*/Schema.Array( /*#__PURE__*/Schema.suspend(() => UserMessagePart)),
47
+ userName: /*#__PURE__*/Schema.optional(Schema.String)
48
+ }) {
33
49
  /**
34
50
  * @since 1.0.0
35
51
  */
36
- static fromContent(content) {
37
- return new TextPart({
38
- content
39
- }, constDisableValidation);
40
- }
52
+ [MessageTypeId] = MessageTypeId;
41
53
  }
42
54
  /**
43
55
  * @since 1.0.0
44
- * @category parts
56
+ * @category Models
45
57
  */
46
- export const ImageQuality = /*#__PURE__*/Schema_.Literal("low", "high", "auto");
58
+ export class AssistantMessage extends /*#__PURE__*/Schema.TaggedClass("@effect/ai/AiInput/Message/AssistantMessage")("AssistantMessage", {
59
+ parts: /*#__PURE__*/Schema.Array( /*#__PURE__*/Schema.suspend(() => AssistantMessagePart))
60
+ }) {
61
+ /**
62
+ * @since 1.0.0
63
+ */
64
+ [MessageTypeId] = MessageTypeId;
65
+ }
47
66
  /**
48
67
  * @since 1.0.0
49
- * @category parts
68
+ * @category Models
50
69
  */
51
- export class ImageUrlPart extends /*#__PURE__*/Schema_.TaggedClass("@effect/ai/AiInput/ImageUrlPart")("ImageUrl", {
52
- url: Schema_.String,
53
- quality: /*#__PURE__*/ImageQuality.pipe(Schema_.propertySignature, /*#__PURE__*/Schema_.withConstructorDefault(() => "auto"))
70
+ export class ToolMessage extends /*#__PURE__*/Schema.TaggedClass("@effect/ai/AiInput/Message/ToolMessage")("ToolMessage", {
71
+ parts: /*#__PURE__*/Schema.Array( /*#__PURE__*/Schema.suspend(() => ToolMessagePart))
54
72
  }) {
55
73
  /**
56
74
  * @since 1.0.0
57
75
  */
58
- [PartTypeId] = PartTypeId;
76
+ [MessageTypeId] = MessageTypeId;
59
77
  }
60
- const base64ContentTypeRegex = /^data:(.*?);base64$/;
61
78
  /**
62
79
  * @since 1.0.0
63
- * @category base64
80
+ * @category Models
64
81
  */
65
- export const Base64DataUrl = /*#__PURE__*/Schema_.transformOrFail( /*#__PURE__*/Schema_.String.annotations({
66
- title: "Base64 Data URL",
67
- description: "A base64 data URL"
68
- }), /*#__PURE__*/Schema_.Struct({
69
- data: Schema_.Uint8ArrayFromSelf,
70
- contentType: Schema_.String
71
- }), {
72
- decode(base64Url, _, ast) {
73
- const commaIndex = base64Url.indexOf(",");
74
- if (commaIndex === -1) {
75
- return ParseResult.fail(new ParseResult.Type(ast, base64Url));
76
- }
77
- const header = base64Url.slice(0, commaIndex);
78
- const data = base64Url.slice(commaIndex + 1);
79
- const contentType = base64ContentTypeRegex.exec(header);
80
- if (contentType === null) {
81
- return ParseResult.fail(new ParseResult.Type(ast, base64Url));
82
- }
83
- return Encoding.decodeBase64(data).pipe(ParseResult.mapError(_ => new ParseResult.Type(ast, base64Url)), ParseResult.map(data => ({
84
- data,
85
- contentType: contentType[1]
86
- })));
87
- },
88
- encode({
89
- contentType,
90
- data
91
- }) {
92
- const base64 = Encoding.encodeBase64(data);
93
- return ParseResult.succeed(`data:${contentType};base64,${base64}`);
94
- }
95
- });
82
+ export const Message = /*#__PURE__*/Schema.Union(UserMessage, AssistantMessage, ToolMessage);
83
+ // =============================================================================
84
+ // Part
85
+ // =============================================================================
86
+ /**
87
+ * @since 1.0.0
88
+ * @category Type Ids
89
+ */
90
+ export const PartTypeId = /*#__PURE__*/Symbol.for("@effect/ai/AiInput/Message/Part");
96
91
  /**
92
+ * Represents a text part of a message.
93
+ *
97
94
  * @since 1.0.0
98
- * @category parts
95
+ * @category Models
99
96
  */
100
- export class ImagePart extends /*#__PURE__*/Schema_.TaggedClass("@effect/ai/AiInput/ImagePart")("Image", {
101
- image: Base64DataUrl,
102
- quality: /*#__PURE__*/ImageQuality.pipe(Schema_.propertySignature, /*#__PURE__*/Schema_.withConstructorDefault(() => "auto"))
97
+ export class TextPart extends /*#__PURE__*/Schema.TaggedClass("@effect/ai/AiInput/TextPart")("TextPart", {
98
+ /**
99
+ * The text content.
100
+ */
101
+ text: Schema.String
103
102
  }) {
104
103
  /**
105
104
  * @since 1.0.0
106
105
  */
107
106
  [PartTypeId] = PartTypeId;
107
+ }
108
+ /**
109
+ * Represents an image part of a message with binary image data.
110
+ *
111
+ * @since 1.0.0
112
+ * @category Models
113
+ */
114
+ export class ImagePart extends /*#__PURE__*/Schema.TaggedClass("@effect/ai/AiInput/ImagePart")("ImagePart", {
115
+ /**
116
+ * The binary image data.
117
+ */
118
+ data: Schema.Uint8ArrayFromBase64,
119
+ /**
120
+ * The optional MIME type for the image.
121
+ */
122
+ mediaType: /*#__PURE__*/Schema.optional(Schema.String)
123
+ }) {
108
124
  /**
109
125
  * @since 1.0.0
110
126
  */
111
- static fromPath(path, quality = "auto") {
112
- return FileSystem.FileSystem.pipe(Effect.bindTo("fs"), Effect.bind("Path", () => Path.Path), Effect.bind("data", ({
113
- fs
114
- }) => fs.readFile(path)), Effect.map(({
115
- Path,
116
- data
117
- }) => {
118
- const ext = Path.extname(path);
119
- let contentType;
120
- switch (ext) {
121
- case ".jpg":
122
- case ".jpeg":
123
- {
124
- contentType = "image/jpeg";
125
- break;
126
- }
127
- default:
128
- {
129
- if (ext.startsWith(".")) {
130
- contentType = `image/${ext.slice(1)}`;
131
- } else {
132
- contentType = "image/png";
133
- }
134
- break;
135
- }
136
- }
137
- return new ImagePart({
138
- image: {
139
- data,
140
- contentType
141
- },
142
- quality
143
- }, constDisableValidation);
144
- }));
145
- }
127
+ [PartTypeId] = PartTypeId;
128
+ }
129
+ /**
130
+ * Represents an image part of a message with a URL pointing to the image.
131
+ *
132
+ * @since 1.0.0
133
+ * @category Models
134
+ */
135
+ export class ImageUrlPart extends /*#__PURE__*/Schema.TaggedClass("@effect/ai/AiInput/ImageUrlPart")("ImageUrlPart", {
136
+ /**
137
+ * The URL that points to the image.
138
+ */
139
+ url: Schema.URL
140
+ }) {
146
141
  /**
147
142
  * @since 1.0.0
148
143
  */
149
- static fromBlob(blob, quality = "auto") {
150
- return Effect.promise(() => blob.arrayBuffer()).pipe(Effect.map(buffer => new ImagePart({
151
- image: {
152
- contentType: blob.type,
153
- data: new Uint8Array(buffer)
154
- },
155
- quality
156
- })));
157
- }
158
- get asBase64() {
159
- return Encoding.encodeBase64(this.image.data);
160
- }
161
- get asDataUri() {
162
- return `data:${this.image.contentType};base64,${this.asBase64}`;
163
- }
144
+ [PartTypeId] = PartTypeId;
164
145
  }
165
146
  /**
147
+ * Represents a file part of a message with binary file data.
148
+ *
166
149
  * @since 1.0.0
167
- * @category parts
150
+ * @category Models
168
151
  */
169
- export class ToolCallPart extends /*#__PURE__*/Schema_.TaggedClass("@effect/ai/AiInput/ToolCallPart")("ToolCall", {
170
- id: ToolCallId,
171
- name: Schema_.String,
172
- params: Schema_.Unknown
152
+ export class FilePart extends /*#__PURE__*/Schema.TaggedClass("@effect/ai/AiInput/FilePart")("FilePart", {
153
+ /**
154
+ * The binary file data.
155
+ */
156
+ data: Schema.Uint8ArrayFromBase64,
157
+ /**
158
+ * The optional name of the file.
159
+ */
160
+ name: /*#__PURE__*/Schema.optional(Schema.String),
161
+ /**
162
+ * The optional MIME type for the image.
163
+ */
164
+ mediaType: /*#__PURE__*/Schema.optional(Schema.String)
173
165
  }) {
174
166
  /**
175
167
  * @since 1.0.0
@@ -177,12 +169,16 @@ export class ToolCallPart extends /*#__PURE__*/Schema_.TaggedClass("@effect/ai/A
177
169
  [PartTypeId] = PartTypeId;
178
170
  }
179
171
  /**
172
+ * Represents a file part of a message with a URL pointing to the file.
173
+ *
180
174
  * @since 1.0.0
181
- * @category parts
175
+ * @category Models
182
176
  */
183
- export class ToolCallResolvedPart extends /*#__PURE__*/Schema_.TaggedClass("@effect/ai/AiInput/ToolCallResolvedPart")("ToolCallResolved", {
184
- toolCallId: ToolCallId,
185
- value: Schema_.Unknown
177
+ export class FileUrlPart extends /*#__PURE__*/Schema.TaggedClass("@effect/ai/AiInput/FileUrlPart")("FileUrlPart", {
178
+ /**
179
+ * The URL that points to the file.
180
+ */
181
+ url: Schema.URL
186
182
  }) {
187
183
  /**
188
184
  * @since 1.0.0
@@ -190,157 +186,239 @@ export class ToolCallResolvedPart extends /*#__PURE__*/Schema_.TaggedClass("@eff
190
186
  [PartTypeId] = PartTypeId;
191
187
  }
192
188
  /**
189
+ * Represents a part of a message containing reasoning that the model used to
190
+ * generate its output.
191
+ *
193
192
  * @since 1.0.0
194
- * @category parts
193
+ * @category Models
195
194
  */
196
- export const isPart = u => Predicate.hasProperty(u, PartTypeId);
195
+ export class ReasoningPart extends /*#__PURE__*/Schema.TaggedClass("@effect/ai/AiInput/ReasoningPart")("ReasoningPart", {
196
+ /**
197
+ * The reasoning text that the model used to return the output.
198
+ */
199
+ reasoningText: Schema.String,
200
+ /**
201
+ * An optional signature which verifies that the reasoning text was generated
202
+ * by the model.
203
+ */
204
+ signature: /*#__PURE__*/Schema.optional(Schema.String)
205
+ }) {
206
+ /**
207
+ * @since 1.0.0
208
+ */
209
+ [PartTypeId] = PartTypeId;
210
+ }
197
211
  /**
212
+ * Represents a part of a message containing content in the model's reasoning
213
+ * that was encrypted by the model provider for safety reasons.
214
+ *
198
215
  * @since 1.0.0
199
- * @category parts
216
+ * @category Models
200
217
  */
201
- export const Part = /*#__PURE__*/Schema_.Union(TextPart, ToolCallPart, ToolCallResolvedPart, ImagePart, ImageUrlPart);
218
+ export class RedactedReasoningPart extends /*#__PURE__*/Schema.TaggedClass("@effect/ai/AiInput/RedactedReasoningPart")("RedactedReasoningPart", {
219
+ /**
220
+ * The content in the reasoning that was encrypted by the model provider for
221
+ * safety reasons.
222
+ */
223
+ redactedText: Schema.String
224
+ }) {
225
+ /**
226
+ * @since 1.0.0
227
+ */
228
+ [PartTypeId] = PartTypeId;
229
+ }
202
230
  /**
231
+ * Represents the identifier generated by a model when a tool call is requested.
232
+ *
203
233
  * @since 1.0.0
204
- * @category message
234
+ * @category Models
205
235
  */
206
- export const MessageTypeId = /*#__PURE__*/Symbol("@effect/ai/AiInput/Message");
236
+ export const ToolCallId = InternalCommon.ToolCallId;
207
237
  /**
238
+ * Represents a part of a message containing a tool call that the model has
239
+ * requested invocation of.
240
+ *
208
241
  * @since 1.0.0
209
- * @category message
242
+ * @category Models
210
243
  */
211
- export class Message extends /*#__PURE__*/Schema_.Class("@effect/ai/AiInput/Message")({
212
- role: AiRole.AiRole,
213
- parts: /*#__PURE__*/Schema_.Chunk(Part)
214
- }) {
244
+ export class ToolCallPart extends /*#__PURE__*/Schema.TaggedClass("@effect/ai/AiInput/ToolCallPart")("ToolCallPart", {
215
245
  /**
216
- * @since 1.0.0
246
+ * The identifier generated by a model when requesting a tool call.
217
247
  */
218
- [MessageTypeId] = MessageTypeId;
248
+ id: ToolCallId,
219
249
  /**
220
- * @since 1.0.0
250
+ * The name of the tool to call.
221
251
  */
222
- static is(u) {
223
- return Predicate.hasProperty(u, MessageTypeId);
224
- }
252
+ name: Schema.String,
225
253
  /**
226
- * @since 1.0.0
254
+ * The arguments to call the tool with as a JSON-serializable object that
255
+ * matches the tool call input schema.
227
256
  */
228
- static fromInput(input, role = AiRole.user) {
229
- if (typeof input === "string") {
230
- return new Message({
231
- role,
232
- parts: Chunk.of(TextPart.fromContent(input))
233
- }, constDisableValidation);
234
- } else if (isPart(input)) {
235
- return new Message({
236
- role,
237
- parts: Chunk.of(input)
238
- }, constDisableValidation);
239
- }
240
- return new Message({
241
- role,
242
- parts: Chunk.fromIterable(input)
243
- }, constDisableValidation);
244
- }
257
+ params: Schema.Unknown
258
+ }) {
245
259
  /**
246
260
  * @since 1.0.0
247
261
  */
248
- static fromResponse(response) {
249
- if (Chunk.isEmpty(response.parts)) {
250
- return Option.none();
251
- }
252
- return Option.some(new Message({
253
- role: response.role,
254
- parts: Chunk.map(response.parts, part => {
255
- switch (part._tag) {
256
- case "Text":
257
- {
258
- return TextPart.fromContent(part.content);
259
- }
260
- case "ToolCall":
261
- {
262
- return new ToolCallPart(part, constDisableValidation);
263
- }
264
- case "ImageUrl":
265
- {
266
- return new ImageUrlPart(part, constDisableValidation);
267
- }
268
- }
269
- })
270
- }, constDisableValidation));
262
+ [PartTypeId] = PartTypeId;
263
+ constructor(props, options) {
264
+ super(props, options);
271
265
  }
266
+ }
267
+ /**
268
+ * Represents a part of a message containing the results of tool calls that the
269
+ * model requested invocation of.
270
+ *
271
+ * @since 1.0.0
272
+ * @category Models
273
+ */
274
+ export class ToolCallResultPart extends /*#__PURE__*/Schema.TaggedClass("@effect/ai/AiInput/ToolCallResultPart")("ToolCallResultPart", {
275
+ /**
276
+ * The identifier generated by a model when requesting a tool call.
277
+ */
278
+ id: ToolCallId,
279
+ /**
280
+ * The result of the tool call as a JSON-serializable object.
281
+ */
282
+ result: Schema.Unknown
283
+ }) {
272
284
  /**
273
285
  * @since 1.0.0
274
286
  */
275
- static fromWithResolved(response) {
276
- const toolParts = [];
277
- for (const [toolCallId, value] of response.encoded) {
278
- toolParts.push(new ToolCallResolvedPart({
279
- toolCallId,
280
- value
281
- }, constDisableValidation));
282
- }
283
- const toolPartsChunk = Chunk.unsafeFromArray(toolParts);
284
- return Option.match(Message.fromResponse(response.response), {
285
- onNone: () => new Message({
286
- role: AiRole.model,
287
- parts: toolPartsChunk
288
- }, constDisableValidation),
289
- onSome: message => new Message({
290
- role: message.role,
291
- parts: Chunk.appendAll(message.parts, toolPartsChunk)
292
- }, constDisableValidation)
293
- });
294
- }
287
+ [PartTypeId] = PartTypeId;
295
288
  }
296
289
  /**
290
+ * The valid parts of a user message.
291
+ *
297
292
  * @since 1.0.0
298
- * @category constructors
293
+ * @category Models
299
294
  */
300
- export const make = (input, options) => {
301
- if (typeof input !== "string" && Predicate.isIterable(input)) {
302
- const chunk = Chunk.fromIterable(input);
303
- if (Chunk.isEmpty(chunk)) {
304
- return chunk;
305
- } else if (Message.is(Chunk.unsafeHead(chunk))) {
306
- return chunk;
307
- }
308
- return Chunk.of(Message.fromInput(chunk, options?.role));
309
- } else if (AiResponse.is(input)) {
310
- return Option.match(Message.fromResponse(input), {
311
- onNone: Chunk.empty,
312
- onSome: Chunk.of
313
- });
314
- } else if (WithResolved.is(input)) {
315
- return Chunk.of(Message.fromWithResolved(input));
316
- } else if (Message.is(input)) {
317
- return Chunk.of(input);
318
- }
319
- return Chunk.of(Message.fromInput(input, options?.role));
320
- };
295
+ export const UserMessagePart = /*#__PURE__*/Schema.Union(TextPart, ImagePart, ImageUrlPart, FilePart, FileUrlPart);
321
296
  /**
297
+ * The valid parts of an assistant message.
298
+ *
322
299
  * @since 1.0.0
323
- * @category constructors
300
+ * @category Models
324
301
  */
325
- export const empty = /*#__PURE__*/Chunk.empty();
302
+ export const AssistantMessagePart = /*#__PURE__*/Schema.Union(TextPart, ReasoningPart, RedactedReasoningPart, ToolCallPart);
326
303
  /**
304
+ * The valid parts of a tool message.
305
+ *
327
306
  * @since 1.0.0
328
- * @category schemas
307
+ * @category Models
329
308
  */
330
- export const Schema = /*#__PURE__*/Schema_.Chunk(Message);
309
+ export const ToolMessagePart = ToolCallResultPart;
331
310
  /**
332
311
  * @since 1.0.0
333
- * @category schemas
312
+ * @category Guards
334
313
  */
335
- export const SchemaJson = /*#__PURE__*/Schema_.parseJson(Schema);
314
+ export const is = u => Predicate.hasProperty(u, TypeId);
336
315
  /**
337
316
  * @since 1.0.0
338
- * @category system
317
+ * @category Guards
339
318
  */
340
- export class SystemInstruction extends /*#__PURE__*/Context.Tag("@effect/ai/AiInput/SystemInstruction")() {}
319
+ export const isMessage = u => Predicate.hasProperty(u, MessageTypeId);
320
+ /**
321
+ * @since 1.0.0
322
+ * @category Guards
323
+ */
324
+ export const isPart = u => Predicate.hasProperty(u, PartTypeId);
325
+ /**
326
+ * @since 1.0.0
327
+ * @category Constructors
328
+ */
329
+ export const empty = /*#__PURE__*/new AiInput({
330
+ messages: []
331
+ });
332
+ /**
333
+ * Constructs a new `AiInput` from raw user input.
334
+ *
335
+ * @since 1.0.0
336
+ * @category Constructors
337
+ */
338
+ export const make = input => {
339
+ if (Predicate.isString(input)) {
340
+ const textPart = new TextPart({
341
+ text: input
342
+ });
343
+ const message = new UserMessage({
344
+ parts: [textPart]
345
+ });
346
+ return new AiInput({
347
+ messages: [message]
348
+ });
349
+ }
350
+ if (isMessage(input)) {
351
+ return new AiInput({
352
+ messages: [input]
353
+ });
354
+ }
355
+ if (Predicate.isIterable(input)) {
356
+ return new AiInput({
357
+ messages: Array.from(input)
358
+ });
359
+ }
360
+ if (is(input)) {
361
+ return input;
362
+ }
363
+ if (AiResponse.isStructured(input)) {
364
+ const assistantMessages = fromResponse(input).messages;
365
+ const toolPart = new ToolCallResultPart({
366
+ id: input.id,
367
+ result: input.value
368
+ });
369
+ const toolMessage = new ToolMessage({
370
+ parts: [toolPart]
371
+ });
372
+ return new AiInput({
373
+ messages: [...assistantMessages, toolMessage]
374
+ });
375
+ }
376
+ if (AiResponse.hasToolCallResults(input)) {
377
+ const assistantMessages = fromResponse(input).messages;
378
+ const toolParts = [];
379
+ for (const [id, result] of input.encodedResults) {
380
+ toolParts.push(new ToolCallResultPart({
381
+ id,
382
+ result
383
+ }));
384
+ }
385
+ const toolMessage = new ToolMessage({
386
+ parts: toolParts
387
+ });
388
+ return new AiInput({
389
+ messages: [...assistantMessages, toolMessage]
390
+ });
391
+ }
392
+ return fromResponse(input);
393
+ };
394
+ const EXCLUDED_RESPONSE_PARTS = ["MetadataPart", "ReasoningPart", "RedactedReasoningPart", "FinishPart"];
395
+ const validResponseParts = part => !EXCLUDED_RESPONSE_PARTS.includes(part._tag);
396
+ const fromResponse = response => {
397
+ if (response.parts.length === 0) {
398
+ return empty;
399
+ }
400
+ const parts = response.parts.filter(validResponseParts).map(part => part._tag === "TextPart" ? new TextPart({
401
+ text: part.text
402
+ }) : new ToolCallPart({
403
+ id: part.id,
404
+ name: part.name,
405
+ params: part.params
406
+ }));
407
+ const message = new AssistantMessage({
408
+ parts
409
+ });
410
+ return new AiInput({
411
+ messages: [message]
412
+ });
413
+ };
341
414
  /**
415
+ * Concatenates the messages of one `AiInput` onto the messages of another,
416
+ * creating a new `AiInput` with the messages from both.
417
+ *
342
418
  * @since 1.0.0
343
- * @category system
419
+ * @category Combination
344
420
  */
345
- export const provideSystem = /*#__PURE__*/dual(2, (effect, input) => Effect.provideService(effect, SystemInstruction, input));
421
+ export const concat = /*#__PURE__*/dual(2, (self, other) => AiInput.make({
422
+ messages: [...self.messages, ...other.messages]
423
+ }));
346
424
  //# sourceMappingURL=AiInput.js.map