@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
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Embeddings.js","names":["dataLoader","Context","Effect","identity","Option","Request","RequestResolver","Schema","AiError","Embeddings","Tag","EmbeddingRequest","TaggedRequest","failure","success","mutable","Array","Number","payload","input","String","makeBatchedResolver","embedMany","makeBatched","requests","map","request","pipe","flatMap","forEach","embeddings","index","succeed","discard","catchAll","error","fail","make","options","gen","cache","fromNullable","config","makeCache","optionFromOptional","resolver","maxBatchSize","batchN","embed","match","onNone","onSome","withRequestCaching","withRequestCache","withSpan","captureStackTrace","of","makeDataLoader","resolverDelayed","window"],"sources":["../../src/Embeddings.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
package/src/AiModels.ts
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @since 1.0.0
|
|
3
|
-
*/
|
|
4
|
-
import * as Context from "effect/Context"
|
|
5
|
-
import * as Effect from "effect/Effect"
|
|
6
|
-
import * as Equal from "effect/Equal"
|
|
7
|
-
import * as Hash from "effect/Hash"
|
|
8
|
-
import * as Layer from "effect/Layer"
|
|
9
|
-
import * as RcMap from "effect/RcMap"
|
|
10
|
-
import type * as Scope from "effect/Scope"
|
|
11
|
-
import type { AiModel } from "./AiModel.js"
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @since 1.0.0
|
|
15
|
-
* @category tags
|
|
16
|
-
*/
|
|
17
|
-
export class AiModels extends Context.Tag("@effect/ai/AiModels")<
|
|
18
|
-
AiModels,
|
|
19
|
-
AiModels.Service
|
|
20
|
-
>() {}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* @since 1.0.0
|
|
24
|
-
*/
|
|
25
|
-
export declare namespace AiModels {
|
|
26
|
-
/**
|
|
27
|
-
* @since 1.0.0
|
|
28
|
-
* @category models
|
|
29
|
-
*/
|
|
30
|
-
export interface Service {
|
|
31
|
-
readonly build: <Provides, Requires>(
|
|
32
|
-
model: AiModel<Provides, Requires>,
|
|
33
|
-
context: Context.Context<Requires>
|
|
34
|
-
) => Effect.Effect<Context.Context<Provides>, never, Scope.Scope>
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
class AiModelsKey {
|
|
39
|
-
constructor(
|
|
40
|
-
readonly model: AiModel<any, any>,
|
|
41
|
-
readonly service: unknown
|
|
42
|
-
) {}
|
|
43
|
-
|
|
44
|
-
[Equal.symbol](that: AiModelsKey): boolean {
|
|
45
|
-
return this.service === that.service && this.model.cacheKey === that.model.cacheKey
|
|
46
|
-
}
|
|
47
|
-
[Hash.symbol](): number {
|
|
48
|
-
return Hash.combine(Hash.hash(this.service))(Hash.hash(this.model.cacheKey))
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const make = Effect.gen(function*() {
|
|
53
|
-
const services = yield* RcMap.make({
|
|
54
|
-
idleTimeToLive: "1 minute",
|
|
55
|
-
lookup: (key: AiModelsKey) => Effect.provideService(key.model.provides, key.model.requires, key.service)
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
const build = <Provides, Requires>(
|
|
59
|
-
model: AiModel<Provides, Requires>,
|
|
60
|
-
context: Context.Context<Requires>
|
|
61
|
-
): Effect.Effect<Context.Context<Provides>, never, Scope.Scope> =>
|
|
62
|
-
Effect.map(
|
|
63
|
-
RcMap.get(
|
|
64
|
-
services,
|
|
65
|
-
new AiModelsKey(model, Context.get(context, model.requires as any))
|
|
66
|
-
),
|
|
67
|
-
(context) => model.updateContext(context)
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
return { build } as const
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* @since 1.0.0
|
|
75
|
-
* @category layers
|
|
76
|
-
*/
|
|
77
|
-
export const layer: Layer.Layer<AiModels> = Layer.scoped(AiModels, make)
|
package/src/AiRole.ts
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @since 1.0.0
|
|
3
|
-
*/
|
|
4
|
-
import * as Option from "effect/Option"
|
|
5
|
-
import * as Schema from "effect/Schema"
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @since 1.0.0
|
|
9
|
-
* @category type ids
|
|
10
|
-
*/
|
|
11
|
-
export const TypeId: unique symbol = Symbol.for("@effect/ai/AiRole")
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @since 1.0.0
|
|
15
|
-
* @category type ids
|
|
16
|
-
*/
|
|
17
|
-
export type TypeId = typeof TypeId
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @since 1.0.0
|
|
21
|
-
* @category models
|
|
22
|
-
*/
|
|
23
|
-
export type AiRole = User | UserWithName | Model
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* @since 1.0.0
|
|
27
|
-
* @category models
|
|
28
|
-
*/
|
|
29
|
-
export class User extends Schema.TaggedClass<User>("@effect/ai/AiRole/User")("User", {}) {
|
|
30
|
-
/**
|
|
31
|
-
* @since 1.0.0
|
|
32
|
-
*/
|
|
33
|
-
readonly [TypeId]: TypeId = TypeId
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @since 1.0.0
|
|
37
|
-
*/
|
|
38
|
-
readonly kind = "user" as const
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* @since 1.0.0
|
|
42
|
-
*/
|
|
43
|
-
readonly nameOption: Option.Option<string> = Option.none()
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* @since 1.0.0
|
|
48
|
-
* @category constructors
|
|
49
|
-
*/
|
|
50
|
-
export const user: AiRole = new User()
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* @since 1.0.0
|
|
54
|
-
* @category models
|
|
55
|
-
*/
|
|
56
|
-
export class UserWithName extends Schema.TaggedClass<UserWithName>("@effect/ai/AiRole/UserWithName")("UserWithName", {
|
|
57
|
-
name: Schema.String
|
|
58
|
-
}) {
|
|
59
|
-
/**
|
|
60
|
-
* @since 1.0.0
|
|
61
|
-
*/
|
|
62
|
-
readonly [TypeId]: TypeId = TypeId
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* @since 1.0.0
|
|
66
|
-
*/
|
|
67
|
-
readonly kind = "user" as const
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* @since 1.0.0
|
|
71
|
-
*/
|
|
72
|
-
get nameOption(): Option.Option<string> {
|
|
73
|
-
return Option.some(this.name)
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* @since 1.0.0
|
|
79
|
-
* @category constructors
|
|
80
|
-
*/
|
|
81
|
-
export const userWithName = (name: string): AiRole => new UserWithName({ name }, { disableValidation: true })
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* @since 1.0.0
|
|
85
|
-
* @category models
|
|
86
|
-
*/
|
|
87
|
-
export class Model extends Schema.TaggedClass<Model>("@effect/ai/AiRole/Model")("Model", {}) {
|
|
88
|
-
/**
|
|
89
|
-
* @since 1.0.0
|
|
90
|
-
*/
|
|
91
|
-
readonly [TypeId]: TypeId = TypeId
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* @since 1.0.0
|
|
95
|
-
*/
|
|
96
|
-
readonly kind = "model" as const
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* @since 1.0.0
|
|
100
|
-
*/
|
|
101
|
-
readonly nameOption: Option.Option<string> = Option.none()
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* @since 1.0.0
|
|
106
|
-
* @category constructors
|
|
107
|
-
*/
|
|
108
|
-
export const model: AiRole = new Model()
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* @since 1.0.0
|
|
112
|
-
* @category roles
|
|
113
|
-
*/
|
|
114
|
-
export const AiRole: Schema.Union<[
|
|
115
|
-
typeof User,
|
|
116
|
-
typeof UserWithName,
|
|
117
|
-
typeof Model
|
|
118
|
-
]> = Schema.Union(
|
|
119
|
-
User,
|
|
120
|
-
UserWithName,
|
|
121
|
-
Model
|
|
122
|
-
)
|
package/src/Completions.ts
DELETED
|
@@ -1,434 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @since 1.0.0
|
|
3
|
-
*/
|
|
4
|
-
import * as Chunk from "effect/Chunk"
|
|
5
|
-
import * as Context from "effect/Context"
|
|
6
|
-
import * as Effect from "effect/Effect"
|
|
7
|
-
import * as HashMap from "effect/HashMap"
|
|
8
|
-
import * as JsonSchema from "effect/JSONSchema"
|
|
9
|
-
import * as Option from "effect/Option"
|
|
10
|
-
import * as Predicate from "effect/Predicate"
|
|
11
|
-
import * as Schema from "effect/Schema"
|
|
12
|
-
import * as AST from "effect/SchemaAST"
|
|
13
|
-
import * as Stream from "effect/Stream"
|
|
14
|
-
import type { Span } from "effect/Tracer"
|
|
15
|
-
import type { Concurrency } from "effect/Types"
|
|
16
|
-
import { AiError } from "./AiError.js"
|
|
17
|
-
import type { Message } from "./AiInput.js"
|
|
18
|
-
import * as AiInput from "./AiInput.js"
|
|
19
|
-
import type { AiResponse, ToolCallId, ToolCallPart } from "./AiResponse.js"
|
|
20
|
-
import { WithResolved } from "./AiResponse.js"
|
|
21
|
-
import type * as AiToolkit from "./AiToolkit.js"
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* @since 1.0.0
|
|
25
|
-
* @category tags
|
|
26
|
-
*/
|
|
27
|
-
export class Completions extends Context.Tag("@effect/ai/Completions")<
|
|
28
|
-
Completions,
|
|
29
|
-
Completions.Service
|
|
30
|
-
>() {}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* @since 1.0.0
|
|
34
|
-
* @category models
|
|
35
|
-
*/
|
|
36
|
-
export declare namespace Completions {
|
|
37
|
-
/**
|
|
38
|
-
* @since 1.0.0
|
|
39
|
-
* @category models
|
|
40
|
-
*/
|
|
41
|
-
export type StructuredSchema<A, I, R> = TaggedSchema<A, I, R> | IdentifiedSchema<A, I, R>
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* @since 1.0.0
|
|
45
|
-
* @category models
|
|
46
|
-
*/
|
|
47
|
-
export interface TaggedSchema<A, I, R> extends Schema.Schema<A, I, R> {
|
|
48
|
-
readonly _tag: string
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* @since 1.0.0
|
|
53
|
-
* @category models
|
|
54
|
-
*/
|
|
55
|
-
export interface IdentifiedSchema<A, I, R> extends Schema.Schema<A, I, R> {
|
|
56
|
-
readonly identifier: string
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* @since 1.0.0
|
|
61
|
-
* @category models
|
|
62
|
-
*/
|
|
63
|
-
export interface Service {
|
|
64
|
-
readonly create: (input: AiInput.Input) => Effect.Effect<AiResponse, AiError>
|
|
65
|
-
readonly stream: (input: AiInput.Input) => Stream.Stream<AiResponse, AiError>
|
|
66
|
-
readonly structured: {
|
|
67
|
-
<A, I, R>(options: {
|
|
68
|
-
readonly input: AiInput.Input
|
|
69
|
-
readonly schema: StructuredSchema<A, I, R>
|
|
70
|
-
}): Effect.Effect<WithResolved<A>, AiError, R>
|
|
71
|
-
<A, I, R>(options: {
|
|
72
|
-
readonly input: AiInput.Input
|
|
73
|
-
readonly schema: Schema.Schema<A, I, R>
|
|
74
|
-
readonly toolCallId: string
|
|
75
|
-
}): Effect.Effect<WithResolved<A>, AiError, R>
|
|
76
|
-
}
|
|
77
|
-
readonly toolkit: <Tools extends AiToolkit.Tool.AnySchema>(
|
|
78
|
-
options: {
|
|
79
|
-
readonly input: AiInput.Input
|
|
80
|
-
readonly tools: AiToolkit.Handlers<Tools>
|
|
81
|
-
readonly required?: Tools["_tag"] | boolean | undefined
|
|
82
|
-
readonly concurrency?: Concurrency | undefined
|
|
83
|
-
}
|
|
84
|
-
) => Effect.Effect<
|
|
85
|
-
WithResolved<AiToolkit.Tool.Success<Tools>>,
|
|
86
|
-
AiError | AiToolkit.Tool.Failure<Tools>,
|
|
87
|
-
AiToolkit.Tool.Context<Tools>
|
|
88
|
-
>
|
|
89
|
-
readonly toolkitStream: <Tools extends AiToolkit.Tool.AnySchema>(
|
|
90
|
-
options: {
|
|
91
|
-
readonly input: AiInput.Input
|
|
92
|
-
readonly tools: AiToolkit.Handlers<Tools>
|
|
93
|
-
readonly required?: Tools["_tag"] | boolean | undefined
|
|
94
|
-
readonly concurrency?: Concurrency | undefined
|
|
95
|
-
}
|
|
96
|
-
) => Stream.Stream<
|
|
97
|
-
WithResolved<AiToolkit.Tool.Success<Tools>>,
|
|
98
|
-
AiError | AiToolkit.Tool.Failure<Tools>,
|
|
99
|
-
AiToolkit.Tool.Context<Tools>
|
|
100
|
-
>
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const constEmptyMap = new Map<never, never>()
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* @since 1.0.0
|
|
108
|
-
* @category models
|
|
109
|
-
*/
|
|
110
|
-
export interface CompletionOptions {
|
|
111
|
-
readonly system: Option.Option<string>
|
|
112
|
-
readonly input: Chunk.NonEmptyChunk<Message>
|
|
113
|
-
readonly tools: Array<{
|
|
114
|
-
readonly name: string
|
|
115
|
-
readonly description: string
|
|
116
|
-
readonly parameters: JsonSchema.JsonSchema7
|
|
117
|
-
readonly structured: boolean
|
|
118
|
-
}>
|
|
119
|
-
readonly required: boolean | string
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* @since 1.0.0
|
|
124
|
-
* @category constructors
|
|
125
|
-
*/
|
|
126
|
-
export const make = (options: {
|
|
127
|
-
readonly create: (options: {
|
|
128
|
-
readonly system: Option.Option<string>
|
|
129
|
-
readonly input: Chunk.NonEmptyChunk<Message>
|
|
130
|
-
readonly tools: Array<{
|
|
131
|
-
readonly name: string
|
|
132
|
-
readonly description: string
|
|
133
|
-
readonly parameters: JsonSchema.JsonSchema7
|
|
134
|
-
readonly structured: boolean
|
|
135
|
-
}>
|
|
136
|
-
readonly required: boolean | string
|
|
137
|
-
readonly span: Span
|
|
138
|
-
}) => Effect.Effect<AiResponse, AiError>
|
|
139
|
-
readonly stream: (options: {
|
|
140
|
-
readonly system: Option.Option<string>
|
|
141
|
-
readonly input: Chunk.NonEmptyChunk<Message>
|
|
142
|
-
readonly tools: Array<{
|
|
143
|
-
readonly name: string
|
|
144
|
-
readonly description: string
|
|
145
|
-
readonly parameters: JsonSchema.JsonSchema7
|
|
146
|
-
readonly structured: boolean
|
|
147
|
-
}>
|
|
148
|
-
readonly required: boolean | string
|
|
149
|
-
readonly span: Span
|
|
150
|
-
}) => Stream.Stream<AiResponse, AiError>
|
|
151
|
-
}): Effect.Effect<Completions.Service> =>
|
|
152
|
-
Effect.map(Effect.serviceOption(AiInput.SystemInstruction), (parentSystem) => {
|
|
153
|
-
return Completions.of({
|
|
154
|
-
create(input) {
|
|
155
|
-
return Effect.useSpan(
|
|
156
|
-
"Completions.create",
|
|
157
|
-
{ captureStackTrace: false },
|
|
158
|
-
(span) =>
|
|
159
|
-
Effect.serviceOption(AiInput.SystemInstruction).pipe(
|
|
160
|
-
Effect.flatMap((system) =>
|
|
161
|
-
options.create({
|
|
162
|
-
input: AiInput.make(input) as Chunk.NonEmptyChunk<Message>,
|
|
163
|
-
system: Option.orElse(system, () => parentSystem),
|
|
164
|
-
tools: [],
|
|
165
|
-
required: false,
|
|
166
|
-
span
|
|
167
|
-
})
|
|
168
|
-
)
|
|
169
|
-
)
|
|
170
|
-
)
|
|
171
|
-
},
|
|
172
|
-
stream(input_) {
|
|
173
|
-
const input = AiInput.make(input_)
|
|
174
|
-
return Effect.makeSpanScoped("Completions.stream", { captureStackTrace: false }).pipe(
|
|
175
|
-
Effect.zip(Effect.serviceOption(AiInput.SystemInstruction)),
|
|
176
|
-
Effect.map(([span, system]) =>
|
|
177
|
-
options.stream({
|
|
178
|
-
input: input as Chunk.NonEmptyChunk<Message>,
|
|
179
|
-
system: Option.orElse(system, () => parentSystem),
|
|
180
|
-
tools: [],
|
|
181
|
-
required: false,
|
|
182
|
-
span
|
|
183
|
-
})
|
|
184
|
-
),
|
|
185
|
-
Stream.unwrapScoped
|
|
186
|
-
)
|
|
187
|
-
},
|
|
188
|
-
structured(opts) {
|
|
189
|
-
const input = AiInput.make(opts.input)
|
|
190
|
-
const decode = Schema.decodeUnknown(opts.schema)
|
|
191
|
-
const toolId = "toolCallId" in opts
|
|
192
|
-
? opts.toolCallId
|
|
193
|
-
: "_tag" in opts.schema
|
|
194
|
-
? opts.schema._tag
|
|
195
|
-
: opts.schema.identifier
|
|
196
|
-
return Effect.useSpan(
|
|
197
|
-
"Completions.structured",
|
|
198
|
-
{ attributes: { toolId }, captureStackTrace: false },
|
|
199
|
-
(span) =>
|
|
200
|
-
Effect.serviceOption(AiInput.SystemInstruction).pipe(
|
|
201
|
-
Effect.flatMap((system) =>
|
|
202
|
-
options.create({
|
|
203
|
-
input: input as Chunk.NonEmptyChunk<Message>,
|
|
204
|
-
system: Option.orElse(system, () => parentSystem),
|
|
205
|
-
tools: [convertTool(toolId, opts.schema, true)],
|
|
206
|
-
required: true,
|
|
207
|
-
span
|
|
208
|
-
})
|
|
209
|
-
),
|
|
210
|
-
Effect.flatMap((response) =>
|
|
211
|
-
Chunk.findFirst(
|
|
212
|
-
response.parts,
|
|
213
|
-
(part): part is ToolCallPart => part._tag === "ToolCall" && part.name === toolId
|
|
214
|
-
).pipe(
|
|
215
|
-
Option.match({
|
|
216
|
-
onNone: () =>
|
|
217
|
-
Effect.fail(
|
|
218
|
-
new AiError({
|
|
219
|
-
module: "Completions",
|
|
220
|
-
method: "structured",
|
|
221
|
-
description: `Tool call '${toolId}' not found in response`
|
|
222
|
-
})
|
|
223
|
-
),
|
|
224
|
-
onSome: (toolCall) =>
|
|
225
|
-
Effect.matchEffect(decode(toolCall.params), {
|
|
226
|
-
onFailure: (cause) =>
|
|
227
|
-
new AiError({
|
|
228
|
-
module: "Completions",
|
|
229
|
-
method: "structured",
|
|
230
|
-
description: `Failed to decode tool call '${toolId}' parameters`,
|
|
231
|
-
cause
|
|
232
|
-
}),
|
|
233
|
-
onSuccess: (resolved) =>
|
|
234
|
-
Effect.succeed(
|
|
235
|
-
new WithResolved({
|
|
236
|
-
response,
|
|
237
|
-
resolved: new Map([[toolCall.id, resolved]]),
|
|
238
|
-
encoded: new Map([[toolCall.id, toolCall.params]])
|
|
239
|
-
})
|
|
240
|
-
)
|
|
241
|
-
})
|
|
242
|
-
})
|
|
243
|
-
)
|
|
244
|
-
)
|
|
245
|
-
)
|
|
246
|
-
)
|
|
247
|
-
},
|
|
248
|
-
toolkit({ concurrency, input: inputInput, required = false, tools }) {
|
|
249
|
-
const input = AiInput.make(inputInput)
|
|
250
|
-
const toolArr: Array<{
|
|
251
|
-
name: string
|
|
252
|
-
description: string
|
|
253
|
-
parameters: JsonSchema.JsonSchema7
|
|
254
|
-
structured: boolean
|
|
255
|
-
}> = []
|
|
256
|
-
for (const [, tool] of tools.toolkit.tools) {
|
|
257
|
-
toolArr.push(convertTool(tool._tag, tool as any))
|
|
258
|
-
}
|
|
259
|
-
return Effect.useSpan(
|
|
260
|
-
"Completions.toolkit",
|
|
261
|
-
{ attributes: { concurrency, required }, captureStackTrace: false },
|
|
262
|
-
(span) =>
|
|
263
|
-
Effect.serviceOption(AiInput.SystemInstruction).pipe(
|
|
264
|
-
Effect.flatMap((system) =>
|
|
265
|
-
options.create({
|
|
266
|
-
input: input as Chunk.NonEmptyChunk<Message>,
|
|
267
|
-
system: Option.orElse(system, () => parentSystem),
|
|
268
|
-
tools: toolArr,
|
|
269
|
-
required: required as any,
|
|
270
|
-
span
|
|
271
|
-
})
|
|
272
|
-
),
|
|
273
|
-
Effect.flatMap((response) => resolveParts({ response, tools, concurrency, method: "toolkit" }))
|
|
274
|
-
) as any
|
|
275
|
-
)
|
|
276
|
-
},
|
|
277
|
-
toolkitStream({ concurrency, input, required = false, tools }) {
|
|
278
|
-
const toolArr: Array<{
|
|
279
|
-
name: string
|
|
280
|
-
description: string
|
|
281
|
-
parameters: JsonSchema.JsonSchema7
|
|
282
|
-
structured: boolean
|
|
283
|
-
}> = []
|
|
284
|
-
for (const [, tool] of tools.toolkit.tools) {
|
|
285
|
-
toolArr.push(convertTool(tool._tag, tool as any))
|
|
286
|
-
}
|
|
287
|
-
return Effect.makeSpanScoped("Completions.stream", {
|
|
288
|
-
captureStackTrace: false,
|
|
289
|
-
attributes: { required, concurrency }
|
|
290
|
-
}).pipe(
|
|
291
|
-
Effect.zip(Effect.serviceOption(AiInput.SystemInstruction)),
|
|
292
|
-
Effect.map(([span, system]) =>
|
|
293
|
-
options.stream({
|
|
294
|
-
input: AiInput.make(input) as Chunk.NonEmptyChunk<Message>,
|
|
295
|
-
system: Option.orElse(system, () => parentSystem),
|
|
296
|
-
tools: toolArr,
|
|
297
|
-
required: required as any,
|
|
298
|
-
span
|
|
299
|
-
})
|
|
300
|
-
),
|
|
301
|
-
Stream.unwrapScoped,
|
|
302
|
-
Stream.mapEffect(
|
|
303
|
-
(chunk) => resolveParts({ response: chunk, tools, concurrency, method: "toolkitStream" }),
|
|
304
|
-
{ concurrency: "unbounded" }
|
|
305
|
-
)
|
|
306
|
-
) as any
|
|
307
|
-
}
|
|
308
|
-
})
|
|
309
|
-
})
|
|
310
|
-
|
|
311
|
-
const convertTool = <A, I, R>(
|
|
312
|
-
name: string,
|
|
313
|
-
schema: Schema.Schema<A, I, R>,
|
|
314
|
-
structured = false
|
|
315
|
-
) => ({
|
|
316
|
-
name,
|
|
317
|
-
description: getDescription(schema.ast),
|
|
318
|
-
parameters: makeJsonSchema(AST.omit(schema.ast, ["_tag"])),
|
|
319
|
-
structured
|
|
320
|
-
})
|
|
321
|
-
|
|
322
|
-
const makeJsonSchema = (ast: AST.AST): JsonSchema.JsonSchema7 => {
|
|
323
|
-
const $defs = {}
|
|
324
|
-
const schema = JsonSchema.fromAST(ast, {
|
|
325
|
-
definitions: $defs,
|
|
326
|
-
topLevelReferenceStrategy: "skip"
|
|
327
|
-
})
|
|
328
|
-
if (Object.keys($defs).length === 0) return schema
|
|
329
|
-
;(schema as any).$defs = $defs
|
|
330
|
-
return schema
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
const getDescription = (ast: AST.AST): string => {
|
|
334
|
-
const annotations = ast._tag === "Transformation" ?
|
|
335
|
-
{
|
|
336
|
-
...ast.to.annotations,
|
|
337
|
-
...ast.annotations
|
|
338
|
-
} :
|
|
339
|
-
ast.annotations
|
|
340
|
-
return AST.DescriptionAnnotationId in annotations ? annotations[AST.DescriptionAnnotationId] as string : ""
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
const resolveParts = (
|
|
344
|
-
options: {
|
|
345
|
-
readonly response: AiResponse
|
|
346
|
-
readonly tools: AiToolkit.Handlers<any>
|
|
347
|
-
readonly concurrency: Concurrency | undefined
|
|
348
|
-
readonly method: string
|
|
349
|
-
}
|
|
350
|
-
) => {
|
|
351
|
-
const toolNames: Array<string> = []
|
|
352
|
-
const toolParts = Chunk.filter(
|
|
353
|
-
options.response.parts,
|
|
354
|
-
(part): part is ToolCallPart => {
|
|
355
|
-
if (part._tag === "ToolCall") {
|
|
356
|
-
toolNames.push(part.name)
|
|
357
|
-
return true
|
|
358
|
-
}
|
|
359
|
-
return false
|
|
360
|
-
}
|
|
361
|
-
)
|
|
362
|
-
if (Chunk.isEmpty(toolParts)) {
|
|
363
|
-
return Effect.succeed(
|
|
364
|
-
new WithResolved({
|
|
365
|
-
response: options.response,
|
|
366
|
-
resolved: constEmptyMap,
|
|
367
|
-
encoded: constEmptyMap
|
|
368
|
-
})
|
|
369
|
-
)
|
|
370
|
-
}
|
|
371
|
-
const resolved = new Map<ToolCallId, AiToolkit.Tool.Success<any>>()
|
|
372
|
-
const encoded = new Map<ToolCallId, unknown>()
|
|
373
|
-
return Effect.annotateCurrentSpan("toolCalls", toolNames).pipe(
|
|
374
|
-
Effect.zipRight(Effect.forEach(
|
|
375
|
-
toolParts,
|
|
376
|
-
(part) => {
|
|
377
|
-
const tool = HashMap.unsafeGet(options.tools.toolkit.tools, part.name)
|
|
378
|
-
const handler = HashMap.unsafeGet(options.tools.handlers, part.name)
|
|
379
|
-
const decodeParams = Schema.decodeUnknown(tool as any)
|
|
380
|
-
const encodeSuccess = Schema.encode(tool.success)
|
|
381
|
-
return decodeParams(injectTag(part.params, part.name)).pipe(
|
|
382
|
-
Effect.mapError((cause) =>
|
|
383
|
-
new AiError({
|
|
384
|
-
module: "Completions",
|
|
385
|
-
method: options.method,
|
|
386
|
-
description: `Failed to decode tool call '${part.name}' parameters`,
|
|
387
|
-
cause
|
|
388
|
-
})
|
|
389
|
-
),
|
|
390
|
-
Effect.flatMap(handler),
|
|
391
|
-
Effect.tap((value) => {
|
|
392
|
-
return encodeSuccess(value).pipe(
|
|
393
|
-
Effect.mapError((cause) =>
|
|
394
|
-
new AiError({
|
|
395
|
-
module: "Completions",
|
|
396
|
-
method: options.method,
|
|
397
|
-
description: `Failed to encode tool call '${part.name}' result`,
|
|
398
|
-
cause
|
|
399
|
-
})
|
|
400
|
-
),
|
|
401
|
-
Effect.map((encodedValue) => {
|
|
402
|
-
resolved.set(part.id, value)
|
|
403
|
-
encoded.set(part.id, encodedValue)
|
|
404
|
-
})
|
|
405
|
-
)
|
|
406
|
-
})
|
|
407
|
-
)
|
|
408
|
-
},
|
|
409
|
-
{ concurrency: options.concurrency, discard: true }
|
|
410
|
-
)),
|
|
411
|
-
Effect.as(new WithResolved({ response: options.response, resolved, encoded }))
|
|
412
|
-
)
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
/**
|
|
416
|
-
* Certain providers (i.e. Anthropic) do not do a great job returning the
|
|
417
|
-
* `_tag` enum with the parameters for a tool call. This method ensures that
|
|
418
|
-
* the `_tag` is injected into the tool call parameters to avoid issues when
|
|
419
|
-
* decoding.
|
|
420
|
-
*/
|
|
421
|
-
function injectTag(params: unknown, tag: string) {
|
|
422
|
-
// If for some reason we do not receive an object back for the tool call
|
|
423
|
-
// input parameters, just return them unchanged
|
|
424
|
-
if (!Predicate.isObject(params)) {
|
|
425
|
-
return params
|
|
426
|
-
}
|
|
427
|
-
// If the tool's `_tag` is already present in input parameters, return them
|
|
428
|
-
// unchanged
|
|
429
|
-
if (Predicate.hasProperty(params, "_tag")) {
|
|
430
|
-
return params
|
|
431
|
-
}
|
|
432
|
-
// Otherwise inject the tool's `_tag` into the input parameters
|
|
433
|
-
return { ...params, _tag: tag }
|
|
434
|
-
}
|