@effect/ai 0.8.0 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -18,6 +18,10 @@ export * as AiResponse from "./AiResponse.js";
18
18
  * @since 1.0.0
19
19
  */
20
20
  export * as AiRole from "./AiRole.js";
21
+ /**
22
+ * @since 1.0.0
23
+ */
24
+ export * as AiTelemetry from "./AiTelemetry.js";
21
25
  /**
22
26
  * @since 1.0.0
23
27
  */
@@ -26,6 +30,10 @@ export * as AiToolkit from "./AiToolkit.js";
26
30
  * @since 1.0.0
27
31
  */
28
32
  export * as Completions from "./Completions.js";
33
+ /**
34
+ * @since 1.0.0
35
+ */
36
+ export * as Embeddings from "./Embeddings.js";
29
37
  /**
30
38
  * @since 1.0.0
31
39
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["AiChat","AiError","AiInput","AiResponse","AiRole","AiToolkit","Completions","Tokenizer"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA;;;AAGA,OAAO,KAAKA,MAAM,MAAM,aAAa;AAErC;;;AAGA,OAAO,KAAKC,OAAO,MAAM,cAAc;AAEvC;;;AAGA,OAAO,KAAKC,OAAO,MAAM,cAAc;AAEvC;;;AAGA,OAAO,KAAKC,UAAU,MAAM,iBAAiB;AAE7C;;;AAGA,OAAO,KAAKC,MAAM,MAAM,aAAa;AAErC;;;AAGA,OAAO,KAAKC,SAAS,MAAM,gBAAgB;AAE3C;;;AAGA,OAAO,KAAKC,WAAW,MAAM,kBAAkB;AAE/C;;;AAGA,OAAO,KAAKC,SAAS,MAAM,gBAAgB","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["AiChat","AiError","AiInput","AiResponse","AiRole","AiTelemetry","AiToolkit","Completions","Embeddings","Tokenizer"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA;;;AAGA,OAAO,KAAKA,MAAM,MAAM,aAAa;AAErC;;;AAGA,OAAO,KAAKC,OAAO,MAAM,cAAc;AAEvC;;;AAGA,OAAO,KAAKC,OAAO,MAAM,cAAc;AAEvC;;;AAGA,OAAO,KAAKC,UAAU,MAAM,iBAAiB;AAE7C;;;AAGA,OAAO,KAAKC,MAAM,MAAM,aAAa;AAErC;;;AAGA,OAAO,KAAKC,WAAW,MAAM,kBAAkB;AAE/C;;;AAGA,OAAO,KAAKC,SAAS,MAAM,gBAAgB;AAE3C;;;AAGA,OAAO,KAAKC,WAAW,MAAM,kBAAkB;AAE/C;;;AAGA,OAAO,KAAKC,UAAU,MAAM,iBAAiB;AAE7C;;;AAGA,OAAO,KAAKC,SAAS,MAAM,gBAAgB","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect/ai",
3
- "version": "0.8.0",
3
+ "version": "0.8.2",
4
4
  "description": "Effect modules for working with AI apis",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -11,8 +11,9 @@
11
11
  "sideEffects": [],
12
12
  "dependencies": {},
13
13
  "peerDependencies": {
14
- "@effect/platform": "^0.75.0",
15
- "effect": "^3.12.6"
14
+ "@effect/experimental": "^0.39.2",
15
+ "@effect/platform": "^0.75.2",
16
+ "effect": "^3.12.8"
16
17
  },
17
18
  "publishConfig": {
18
19
  "provenance": true
@@ -52,6 +53,11 @@
52
53
  "import": "./dist/esm/AiRole.js",
53
54
  "default": "./dist/cjs/AiRole.js"
54
55
  },
56
+ "./AiTelemetry": {
57
+ "types": "./dist/dts/AiTelemetry.d.ts",
58
+ "import": "./dist/esm/AiTelemetry.js",
59
+ "default": "./dist/cjs/AiTelemetry.js"
60
+ },
55
61
  "./AiToolkit": {
56
62
  "types": "./dist/dts/AiToolkit.d.ts",
57
63
  "import": "./dist/esm/AiToolkit.js",
@@ -62,6 +68,11 @@
62
68
  "import": "./dist/esm/Completions.js",
63
69
  "default": "./dist/cjs/Completions.js"
64
70
  },
71
+ "./Embeddings": {
72
+ "types": "./dist/dts/Embeddings.d.ts",
73
+ "import": "./dist/esm/Embeddings.js",
74
+ "default": "./dist/cjs/Embeddings.js"
75
+ },
65
76
  "./Tokenizer": {
66
77
  "types": "./dist/dts/Tokenizer.d.ts",
67
78
  "import": "./dist/esm/Tokenizer.js",
@@ -85,12 +96,18 @@
85
96
  "AiRole": [
86
97
  "./dist/dts/AiRole.d.ts"
87
98
  ],
99
+ "AiTelemetry": [
100
+ "./dist/dts/AiTelemetry.d.ts"
101
+ ],
88
102
  "AiToolkit": [
89
103
  "./dist/dts/AiToolkit.d.ts"
90
104
  ],
91
105
  "Completions": [
92
106
  "./dist/dts/Completions.d.ts"
93
107
  ],
108
+ "Embeddings": [
109
+ "./dist/dts/Embeddings.d.ts"
110
+ ],
94
111
  "Tokenizer": [
95
112
  "./dist/dts/Tokenizer.d.ts"
96
113
  ]
package/src/AiChat.ts CHANGED
@@ -39,10 +39,17 @@ export declare namespace AiChat {
39
39
  readonly exportJson: Effect.Effect<string>
40
40
  readonly send: (input: AiInput.Input) => Effect.Effect<AiResponse, AiError>
41
41
  readonly stream: (input: AiInput.Input) => Stream.Stream<AiResponse, AiError>
42
- readonly structured: <A, I, R>(
43
- tool: Completions.StructuredSchema<A, I, R>,
44
- input: AiInput.Input
45
- ) => Effect.Effect<A, AiError, R>
42
+ readonly structured: {
43
+ <A, I, R>(options: {
44
+ readonly input: AiInput.Input
45
+ readonly schema: Completions.StructuredSchema<A, I, R>
46
+ }): Effect.Effect<A, AiError, R>
47
+ <A, I, R>(options: {
48
+ readonly input: AiInput.Input
49
+ readonly schema: Schema.Schema<A, I, R>
50
+ readonly toolCallId: string
51
+ }): Effect.Effect<A, AiError, R>
52
+ }
46
53
  readonly toolkit: <Tools extends AiToolkit.Tool.AnySchema>(
47
54
  options: {
48
55
  readonly input: AiInput.Input
@@ -74,180 +81,164 @@ export declare namespace AiChat {
74
81
  * @since 1.0.0
75
82
  * @category constructors
76
83
  */
77
- export const fromInput = (input: AiInput.Input): Effect.Effect<AiChat.Service, never, Completions> =>
78
- Ref.make(AiInput.make(input)).pipe(
79
- Effect.bindTo("historyRef"),
80
- Effect.bind("completions", () => Completions),
81
- Effect.map(({ completions, historyRef }) => new AiChatImpl(historyRef, completions))
82
- )
83
-
84
- class AiChatImpl implements AiChat.Service {
85
- readonly semaphore = Effect.unsafeMakeSemaphore(1)
86
-
87
- constructor(
88
- readonly historyRef: Ref.Ref<AiInput.AiInput>,
89
- readonly completions: Completions.Service
90
- ) {}
91
-
92
- get history() {
93
- return Ref.get(this.historyRef)
94
- }
84
+ export const fromInput = Effect.fnUntraced(
85
+ function*(input: AiInput.Input) {
86
+ const completions = yield* Completions
87
+ const history = yield* Ref.make(AiInput.make(input))
88
+ const semaphore = yield* Effect.makeSemaphore(1)
95
89
 
96
- get export() {
97
- return Ref.get(this.historyRef).pipe(
98
- Effect.flatMap(Schema.encode(AiInput.Schema)),
99
- Effect.orDie
100
- )
101
- }
102
-
103
- get exportJson() {
104
- return Ref.get(this.historyRef).pipe(
105
- Effect.flatMap(Schema.encode(AiInput.SchemaJson)),
106
- Effect.orDie
107
- )
108
- }
109
-
110
- send(input: AiInput.Input) {
111
- const newParts = AiInput.make(input)
112
- return Ref.get(this.historyRef).pipe(
113
- Effect.flatMap((parts) => {
114
- const allParts = Chunk.appendAll(parts, newParts)
115
- return this.completions.create(allParts).pipe(
116
- Effect.tap((response) => {
117
- const responseParts = AiInput.make(response)
118
- return Ref.set(this.historyRef, Chunk.appendAll(allParts, responseParts))
90
+ return AiChat.of({
91
+ history: Ref.get(history),
92
+ export: Ref.get(history).pipe(
93
+ Effect.flatMap(Schema.encode(AiInput.Schema)),
94
+ Effect.orDie
95
+ ),
96
+ exportJson: Ref.get(history).pipe(
97
+ Effect.flatMap(Schema.encode(AiInput.SchemaJson)),
98
+ Effect.orDie
99
+ ),
100
+ send(input) {
101
+ const newParts = AiInput.make(input)
102
+ return Ref.get(history).pipe(
103
+ Effect.flatMap((parts) => {
104
+ const allParts = Chunk.appendAll(parts, newParts)
105
+ return completions.create(allParts).pipe(
106
+ Effect.tap((response) => {
107
+ const responseParts = AiInput.make(response)
108
+ return Ref.set(history, Chunk.appendAll(allParts, responseParts))
109
+ })
110
+ )
111
+ }),
112
+ semaphore.withPermits(1),
113
+ Effect.withSpan("AiChat.send", {
114
+ attributes: { input },
115
+ captureStackTrace: false
119
116
  })
120
117
  )
121
- }),
122
- this.semaphore.withPermits(1),
123
- Effect.withSpan("AiChat.send", { attributes: { input }, captureStackTrace: false })
124
- )
125
- }
126
-
127
- stream(input: AiInput.Input) {
128
- return Stream.suspend(() => {
129
- let combined = AiResponse.empty
130
- return Stream.fromChannel(Channel.acquireUseRelease(
131
- this.semaphore.take(1).pipe(
132
- Effect.zipRight(Ref.get(this.historyRef)),
133
- Effect.map(Chunk.appendAll(AiInput.make(input)))
134
- ),
135
- (parts) =>
136
- this.completions.stream(parts).pipe(
137
- Stream.map((chunk) => {
138
- combined = combined.concat(chunk)
139
- return chunk
140
- }),
141
- Stream.toChannel
142
- ),
143
- (parts) =>
144
- Effect.zipRight(
145
- Ref.set(this.historyRef, Chunk.appendAll(parts, AiInput.make(combined))),
146
- this.semaphore.release(1)
147
- )
148
- ))
149
- }).pipe(Stream.withSpan("AiChat.stream", { attributes: { input }, captureStackTrace: false }))
150
- }
151
-
152
- structured<A, I, R>(
153
- schema: Completions.StructuredSchema<A, I, R>,
154
- input: AiInput.Input
155
- ): Effect.Effect<A, AiError, R> {
156
- const newParts = AiInput.make(input)
157
- return Ref.get(this.historyRef).pipe(
158
- Effect.flatMap((parts) => {
159
- const allParts = Chunk.appendAll(parts, newParts)
160
- return this.completions.structured({
161
- input: allParts,
162
- schema
163
- }).pipe(
164
- Effect.flatMap((response) => {
165
- const responseParts = AiInput.make(response)
166
- return Effect.as(
167
- Ref.set(this.historyRef, Chunk.appendAll(allParts, responseParts)),
168
- response.unsafeValue
118
+ },
119
+ stream(input) {
120
+ return Stream.suspend(() => {
121
+ let combined = AiResponse.empty
122
+ return Stream.fromChannel(Channel.acquireUseRelease(
123
+ semaphore.take(1).pipe(
124
+ Effect.zipRight(Ref.get(history)),
125
+ Effect.map(Chunk.appendAll(AiInput.make(input)))
126
+ ),
127
+ (parts) =>
128
+ completions.stream(parts).pipe(
129
+ Stream.map((chunk) => {
130
+ combined = combined.concat(chunk)
131
+ return chunk
132
+ }),
133
+ Stream.toChannel
134
+ ),
135
+ (parts) =>
136
+ Effect.zipRight(
137
+ Ref.set(history, Chunk.appendAll(parts, AiInput.make(combined))),
138
+ semaphore.release(1)
139
+ )
140
+ ))
141
+ }).pipe(Stream.withSpan("AiChat.stream", {
142
+ attributes: { input },
143
+ captureStackTrace: false
144
+ }))
145
+ },
146
+ structured(options) {
147
+ const newParts = AiInput.make(options.input)
148
+ return Ref.get(history).pipe(
149
+ Effect.flatMap((parts) => {
150
+ const allParts = Chunk.appendAll(parts, newParts)
151
+ return completions.structured({
152
+ ...options,
153
+ input: allParts
154
+ } as any).pipe(
155
+ Effect.flatMap((response) => {
156
+ const responseParts = AiInput.make(response)
157
+ return Effect.as(
158
+ Ref.set(history, Chunk.appendAll(allParts, responseParts)),
159
+ response.unsafeValue
160
+ )
161
+ })
169
162
  )
163
+ }),
164
+ semaphore.withPermits(1),
165
+ Effect.withSpan("AiChat.structured", {
166
+ attributes: {
167
+ input: options.input,
168
+ schema: "toolCallId" in options
169
+ ? options.toolCallId
170
+ : "_tag" in options.schema
171
+ ? options.schema._tag
172
+ : options.schema.identifier
173
+ },
174
+ captureStackTrace: false
170
175
  })
171
176
  )
172
- }),
173
- this.semaphore.withPermits(1),
174
- Effect.withSpan("AiChat.structured", {
175
- attributes: { input, schema: schema._tag ?? schema.identifier },
176
- captureStackTrace: false
177
- })
178
- )
179
- }
180
-
181
- toolkit<Tools extends AiToolkit.Tool.AnySchema>(
182
- options: {
183
- readonly input: AiInput.Input
184
- readonly tools: AiToolkit.Handlers<Tools>
185
- readonly required?: Tools["_tag"] | boolean | undefined
186
- readonly concurrency?: Concurrency | undefined
187
- }
188
- ): Effect.Effect<
189
- WithResolved<AiToolkit.Tool.Success<Tools>>,
190
- AiError | AiToolkit.Tool.Failure<Tools>,
191
- AiToolkit.Tool.Context<Tools>
192
- > {
193
- const newParts = AiInput.make(options.input)
194
- return Ref.get(this.historyRef).pipe(
195
- Effect.flatMap((parts) => {
196
- const allParts = Chunk.appendAll(parts, newParts)
197
- return this.completions.toolkit({
198
- ...options,
199
- input: allParts
200
- }).pipe(
201
- Effect.tap((response) => {
202
- const responseParts = AiInput.make(response)
203
- return Ref.set(this.historyRef, Chunk.appendAll(allParts, responseParts))
177
+ },
178
+ toolkit(options) {
179
+ const newParts = AiInput.make(options.input)
180
+ return Ref.get(history).pipe(
181
+ Effect.flatMap((parts) => {
182
+ const allParts = Chunk.appendAll(parts, newParts)
183
+ return completions.toolkit({
184
+ ...options,
185
+ input: allParts
186
+ }).pipe(
187
+ Effect.tap((response) => {
188
+ const responseParts = AiInput.make(response)
189
+ return Ref.set(history, Chunk.appendAll(allParts, responseParts))
190
+ })
191
+ )
192
+ }),
193
+ semaphore.withPermits(1),
194
+ Effect.withSpan("AiChat.toolkit", {
195
+ attributes: { input: options.input },
196
+ captureStackTrace: false
204
197
  })
205
198
  )
206
- }),
207
- this.semaphore.withPermits(1),
208
- Effect.withSpan("AiChat.toolkit", { attributes: { input: options.input }, captureStackTrace: false })
209
- )
210
- }
211
-
212
- toolkitStream<Tools extends AiToolkit.Tool.AnySchema>(
213
- options: {
214
- readonly input: AiInput.Input
215
- readonly tools: AiToolkit.Handlers<Tools>
216
- readonly required?: Tools["_tag"] | boolean | undefined
217
- readonly concurrency?: Concurrency | undefined
218
- }
219
- ): Stream.Stream<
220
- WithResolved<AiToolkit.Tool.Success<Tools>>,
221
- AiError | AiToolkit.Tool.Failure<Tools>,
222
- AiToolkit.Tool.Context<Tools>
223
- > {
224
- return Stream.suspend(() => {
225
- let combined = WithResolved.empty as WithResolved<AiToolkit.Tool.Success<Tools>>
226
- return Stream.fromChannel(Channel.acquireUseRelease(
227
- this.semaphore.take(1).pipe(
228
- Effect.zipRight(Ref.get(this.historyRef)),
229
- Effect.map(Chunk.appendAll(AiInput.make(options.input)))
230
- ),
231
- (parts) =>
232
- this.completions.toolkitStream({
233
- ...options,
234
- input: parts
235
- }).pipe(
236
- Stream.map((chunk) => {
237
- combined = combined.concat(chunk)
238
- return chunk
239
- }),
240
- Stream.toChannel
241
- ),
242
- (parts) =>
243
- Effect.zipRight(
244
- Ref.set(this.historyRef, Chunk.appendAll(parts, AiInput.make(combined))),
245
- this.semaphore.release(1)
246
- )
247
- ))
248
- }).pipe(Stream.withSpan("AiChat.toolkitStream", { attributes: { input: options.input }, captureStackTrace: false }))
199
+ },
200
+ toolkitStream<Tools extends AiToolkit.Tool.AnySchema>(options: {
201
+ readonly input: AiInput.Input
202
+ readonly tools: AiToolkit.Handlers<Tools>
203
+ readonly required?: Tools["_tag"] | boolean | undefined
204
+ readonly concurrency?: Concurrency | undefined
205
+ }): Stream.Stream<
206
+ WithResolved<AiToolkit.Tool.Success<Tools>>,
207
+ AiError | AiToolkit.Tool.Failure<Tools>,
208
+ AiToolkit.Tool.Context<Tools>
209
+ > {
210
+ return Stream.suspend(() => {
211
+ let combined = WithResolved.empty as WithResolved<AiToolkit.Tool.Success<Tools>>
212
+ return Stream.fromChannel(Channel.acquireUseRelease(
213
+ semaphore.take(1).pipe(
214
+ Effect.zipRight(Ref.get(history)),
215
+ Effect.map(Chunk.appendAll(AiInput.make(options.input)))
216
+ ),
217
+ (parts) =>
218
+ completions.toolkitStream({
219
+ ...options,
220
+ input: parts
221
+ }).pipe(
222
+ Stream.map((chunk) => {
223
+ combined = combined.concat(chunk)
224
+ return chunk
225
+ }),
226
+ Stream.toChannel
227
+ ),
228
+ (parts) =>
229
+ Effect.zipRight(
230
+ Ref.set(history, Chunk.appendAll(parts, AiInput.make(combined))),
231
+ semaphore.release(1)
232
+ )
233
+ ))
234
+ }).pipe(Stream.withSpan("AiChat.toolkitStream", {
235
+ attributes: { input: options.input },
236
+ captureStackTrace: false
237
+ }))
238
+ }
239
+ })
249
240
  }
250
- }
241
+ )
251
242
 
252
243
  /**
253
244
  * @since 1.0.0