@llm4ts/core 2.54.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/Capability.d.ts +0 -9
- package/dist/Capability.d.ts.map +1 -1
- package/dist/Capability.js +0 -38
- package/dist/Capability.js.map +1 -1
- package/dist/Connector.d.ts +2 -3
- package/dist/Connector.d.ts.map +1 -1
- package/dist/Connector.js +0 -5
- package/dist/Connector.js.map +1 -1
- package/dist/ConnectorRegistry.d.ts +0 -3
- package/dist/ConnectorRegistry.d.ts.map +1 -1
- package/dist/ConnectorRegistry.js +0 -3
- package/dist/ConnectorRegistry.js.map +1 -1
- package/dist/HttpClient.d.ts +0 -2
- package/dist/HttpClient.d.ts.map +1 -1
- package/dist/HttpClient.js +0 -2
- package/dist/HttpClient.js.map +1 -1
- package/dist/LlmService.d.ts +1 -2
- package/dist/LlmService.d.ts.map +1 -1
- package/dist/LlmService.js.map +1 -1
- package/dist/Models.d.ts +0 -21
- package/dist/Models.d.ts.map +1 -1
- package/dist/Models.js +0 -19
- package/dist/Models.js.map +1 -1
- package/dist/Streaming.d.ts +4 -11
- package/dist/Streaming.d.ts.map +1 -1
- package/dist/Streaming.js +2 -29
- package/dist/Streaming.js.map +1 -1
- package/dist/providers/AnthropicModels.d.ts +0 -43
- package/dist/providers/AnthropicModels.d.ts.map +1 -1
- package/dist/providers/AnthropicModels.js +0 -39
- package/dist/providers/AnthropicModels.js.map +1 -1
- package/dist/providers/AnthropicProvider.d.ts +2 -3
- package/dist/providers/AnthropicProvider.d.ts.map +1 -1
- package/dist/providers/AnthropicProvider.js +2 -49
- package/dist/providers/AnthropicProvider.js.map +1 -1
- package/dist/providers/GeminiApiProvider.d.ts +2 -3
- package/dist/providers/GeminiApiProvider.d.ts.map +1 -1
- package/dist/providers/GeminiApiProvider.js +2 -44
- package/dist/providers/GeminiApiProvider.js.map +1 -1
- package/dist/providers/GeminiModels.d.ts +0 -48
- package/dist/providers/GeminiModels.d.ts.map +1 -1
- package/dist/providers/GeminiModels.js +0 -40
- package/dist/providers/GeminiModels.js.map +1 -1
- package/dist/providers/LmStudioProvider.d.ts.map +1 -1
- package/dist/providers/LmStudioProvider.js +1 -4
- package/dist/providers/LmStudioProvider.js.map +1 -1
- package/dist/providers/MlxLmProvider.d.ts.map +1 -1
- package/dist/providers/MlxLmProvider.js +1 -2
- package/dist/providers/MlxLmProvider.js.map +1 -1
- package/dist/providers/MockProvider.d.ts.map +1 -1
- package/dist/providers/MockProvider.js +1 -6
- package/dist/providers/MockProvider.js.map +1 -1
- package/dist/providers/OllamaProvider.d.ts.map +1 -1
- package/dist/providers/OllamaProvider.js +1 -4
- package/dist/providers/OllamaProvider.js.map +1 -1
- package/dist/providers/OpenAIModels.d.ts +0 -58
- package/dist/providers/OpenAIModels.d.ts.map +1 -1
- package/dist/providers/OpenAIModels.js +0 -51
- package/dist/providers/OpenAIModels.js.map +1 -1
- package/dist/providers/OpenAIProvider.d.ts +2 -3
- package/dist/providers/OpenAIProvider.d.ts.map +1 -1
- package/dist/providers/OpenAIProvider.js +2 -46
- package/dist/providers/OpenAIProvider.js.map +1 -1
- package/package.json +2 -14
- package/src/Capability.ts +0 -50
- package/src/Connector.ts +2 -20
- package/src/ConnectorRegistry.ts +0 -15
- package/src/HttpClient.ts +0 -15
- package/src/LlmService.ts +1 -13
- package/src/Models.ts +0 -22
- package/src/Streaming.ts +3 -99
- package/src/providers/AnthropicModels.ts +0 -47
- package/src/providers/AnthropicProvider.ts +1 -87
- package/src/providers/GeminiApiProvider.ts +2 -83
- package/src/providers/GeminiModels.ts +0 -46
- package/src/providers/LmStudioProvider.ts +1 -7
- package/src/providers/MlxLmProvider.ts +1 -3
- package/src/providers/MockProvider.ts +0 -9
- package/src/providers/OllamaProvider.ts +1 -7
- package/src/providers/OpenAIModels.ts +0 -64
- package/src/providers/OpenAIProvider.ts +2 -83
- package/dist/ContextManagement.d.ts +0 -78
- package/dist/ContextManagement.d.ts.map +0 -1
- package/dist/ContextManagement.js +0 -222
- package/dist/ContextManagement.js.map +0 -1
- package/dist/Conversation.d.ts +0 -18
- package/dist/Conversation.d.ts.map +0 -1
- package/dist/Conversation.js +0 -17
- package/dist/Conversation.js.map +0 -1
- package/dist/RateLimiter.d.ts +0 -44
- package/dist/RateLimiter.d.ts.map +0 -1
- package/dist/RateLimiter.js +0 -155
- package/dist/RateLimiter.js.map +0 -1
- package/dist/observability/MeteredLlmService.d.ts +0 -16
- package/dist/observability/MeteredLlmService.d.ts.map +0 -1
- package/dist/observability/MeteredLlmService.js +0 -72
- package/dist/observability/MeteredLlmService.js.map +0 -1
- package/dist/observability/Metrics.d.ts +0 -76
- package/dist/observability/Metrics.d.ts.map +0 -1
- package/dist/observability/Metrics.js +0 -152
- package/dist/observability/Metrics.js.map +0 -1
- package/dist/observability/StructuredLogger.d.ts +0 -31
- package/dist/observability/StructuredLogger.d.ts.map +0 -1
- package/dist/observability/StructuredLogger.js +0 -39
- package/dist/observability/StructuredLogger.js.map +0 -1
- package/dist/observability/Tracing.d.ts +0 -38
- package/dist/observability/Tracing.d.ts.map +0 -1
- package/dist/observability/Tracing.js +0 -80
- package/dist/observability/Tracing.js.map +0 -1
- package/dist/providers/OpenCodeModels.d.ts +0 -61
- package/dist/providers/OpenCodeModels.d.ts.map +0 -1
- package/dist/providers/OpenCodeModels.js +0 -53
- package/dist/providers/OpenCodeModels.js.map +0 -1
- package/dist/providers/OpenCodeProvider.d.ts +0 -10
- package/dist/providers/OpenCodeProvider.d.ts.map +0 -1
- package/dist/providers/OpenCodeProvider.js +0 -154
- package/dist/providers/OpenCodeProvider.js.map +0 -1
- package/dist/tools/Tool.d.ts +0 -83
- package/dist/tools/Tool.d.ts.map +0 -1
- package/dist/tools/Tool.js +0 -278
- package/dist/tools/Tool.js.map +0 -1
- package/dist/tools/ToolCallingExecutor.d.ts +0 -18
- package/dist/tools/ToolCallingExecutor.d.ts.map +0 -1
- package/dist/tools/ToolCallingExecutor.js +0 -64
- package/dist/tools/ToolCallingExecutor.js.map +0 -1
- package/dist/tools/ToolRegistry.d.ts +0 -45
- package/dist/tools/ToolRegistry.d.ts.map +0 -1
- package/dist/tools/ToolRegistry.js +0 -133
- package/dist/tools/ToolRegistry.js.map +0 -1
- package/src/ContextManagement.ts +0 -367
- package/src/Conversation.ts +0 -21
- package/src/RateLimiter.ts +0 -238
- package/src/observability/MeteredLlmService.ts +0 -168
- package/src/observability/Metrics.ts +0 -200
- package/src/observability/StructuredLogger.ts +0 -67
- package/src/observability/Tracing.ts +0 -146
- package/src/providers/OpenCodeModels.ts +0 -60
- package/src/providers/OpenCodeProvider.ts +0 -278
- package/src/tools/Tool.ts +0 -376
- package/src/tools/ToolCallingExecutor.ts +0 -106
- package/src/tools/ToolRegistry.ts +0 -224
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llm4ts/core",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Effect-native LLM contracts, providers,
|
|
3
|
+
"version": "3.1.0",
|
|
4
|
+
"description": "Effect-native LLM contracts, providers, evaluation, and observability",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"sideEffects": false,
|
|
@@ -22,8 +22,6 @@
|
|
|
22
22
|
"./Connector": "./dist/Connector.js",
|
|
23
23
|
"./ConnectorConfig": "./dist/ConnectorConfig.js",
|
|
24
24
|
"./ConnectorRegistry": "./dist/ConnectorRegistry.js",
|
|
25
|
-
"./ContextManagement": "./dist/ContextManagement.js",
|
|
26
|
-
"./Conversation": "./dist/Conversation.js",
|
|
27
25
|
"./Errors": "./dist/Errors.js",
|
|
28
26
|
"./eval/Checks": "./dist/eval/Checks.js",
|
|
29
27
|
"./eval/Eval": "./dist/eval/Eval.js",
|
|
@@ -39,12 +37,8 @@
|
|
|
39
37
|
"./LabelScoring": "./dist/LabelScoring.js",
|
|
40
38
|
"./LlmService": "./dist/LlmService.js",
|
|
41
39
|
"./Models": "./dist/Models.js",
|
|
42
|
-
"./observability/Metrics": "./dist/observability/Metrics.js",
|
|
43
|
-
"./observability/MeteredLlmService": "./dist/observability/MeteredLlmService.js",
|
|
44
40
|
"./observability/Redaction": "./dist/observability/Redaction.js",
|
|
45
41
|
"./observability/StreamRecorder": "./dist/observability/StreamRecorder.js",
|
|
46
|
-
"./observability/StructuredLogger": "./dist/observability/StructuredLogger.js",
|
|
47
|
-
"./observability/Tracing": "./dist/observability/Tracing.js",
|
|
48
42
|
"./ProcessExecutor": "./dist/ProcessExecutor.js",
|
|
49
43
|
"./providers/AnthropicModels": "./dist/providers/AnthropicModels.js",
|
|
50
44
|
"./providers/AnthropicProvider": "./dist/providers/AnthropicProvider.js",
|
|
@@ -71,16 +65,10 @@
|
|
|
71
65
|
"./providers/OpenCodeCliConnector": "./dist/providers/OpenCodeCliConnector.js",
|
|
72
66
|
"./providers/OllamaModels": "./dist/providers/OllamaModels.js",
|
|
73
67
|
"./providers/OllamaProvider": "./dist/providers/OllamaProvider.js",
|
|
74
|
-
"./providers/OpenCodeModels": "./dist/providers/OpenCodeModels.js",
|
|
75
|
-
"./providers/OpenCodeProvider": "./dist/providers/OpenCodeProvider.js",
|
|
76
68
|
"./providers/PiConnector": "./dist/providers/PiConnector.js",
|
|
77
|
-
"./RateLimiter": "./dist/RateLimiter.js",
|
|
78
69
|
"./Streaming": "./dist/Streaming.js",
|
|
79
70
|
"./StructuredOutput": "./dist/StructuredOutput.js",
|
|
80
71
|
"./TemporaryFiles": "./dist/TemporaryFiles.js",
|
|
81
|
-
"./tools/Tool": "./dist/tools/Tool.js",
|
|
82
|
-
"./tools/ToolCallingExecutor": "./dist/tools/ToolCallingExecutor.js",
|
|
83
|
-
"./tools/ToolRegistry": "./dist/tools/ToolRegistry.js",
|
|
84
72
|
"./UsageLimits": "./dist/UsageLimits.js",
|
|
85
73
|
"./package.json": "./package.json"
|
|
86
74
|
},
|
package/src/Capability.ts
CHANGED
|
@@ -71,9 +71,6 @@ const levelRank = (level: GrantLevel): number => {
|
|
|
71
71
|
const minLevel = (first: GrantLevel, second: GrantLevel): GrantLevel =>
|
|
72
72
|
levelRank(first) <= levelRank(second) ? first : second
|
|
73
73
|
|
|
74
|
-
const maxLevel = (first: GrantLevel, second: GrantLevel): GrantLevel =>
|
|
75
|
-
levelRank(first) >= levelRank(second) ? first : second
|
|
76
|
-
|
|
77
74
|
export class ExecDenied extends Schema.TaggedClass<ExecDenied>()("Denied", {}) {}
|
|
78
75
|
export class ExecAllow extends Schema.TaggedClass<ExecAllow>()("Allow", {
|
|
79
76
|
commands: Schema.ReadonlySet(Schema.String)
|
|
@@ -104,19 +101,6 @@ const intersectExec = (first: ExecGrant, second: ExecGrant): ExecGrant => {
|
|
|
104
101
|
return allowExec([...first.commands].filter((command) => second.commands.has(command)))
|
|
105
102
|
}
|
|
106
103
|
|
|
107
|
-
const unionExec = (first: ExecGrant, second: ExecGrant): ExecGrant => {
|
|
108
|
-
if (first._tag === "All" || second._tag === "All") {
|
|
109
|
-
return ExecGrants.All
|
|
110
|
-
}
|
|
111
|
-
if (first._tag === "Denied") {
|
|
112
|
-
return second
|
|
113
|
-
}
|
|
114
|
-
if (second._tag === "Denied") {
|
|
115
|
-
return first
|
|
116
|
-
}
|
|
117
|
-
return allowExec(new Set([...first.commands, ...second.commands]))
|
|
118
|
-
}
|
|
119
|
-
|
|
120
104
|
export class Grants extends Schema.Class<Grants>("Grants")({
|
|
121
105
|
git: GrantLevel,
|
|
122
106
|
gh: GrantLevel,
|
|
@@ -164,18 +148,6 @@ export const intersectGrants = (first: Grants, second: Grants): Grants =>
|
|
|
164
148
|
declassify: first.declassify && second.declassify
|
|
165
149
|
})
|
|
166
150
|
|
|
167
|
-
export const unionGrants = (first: Grants, second: Grants): Grants =>
|
|
168
|
-
new Grants({
|
|
169
|
-
git: maxLevel(first.git, second.git),
|
|
170
|
-
gh: maxLevel(first.gh, second.gh),
|
|
171
|
-
ado: maxLevel(first.ado, second.ado),
|
|
172
|
-
basecamp: maxLevel(first.basecamp, second.basecamp),
|
|
173
|
-
exec: unionExec(first.exec, second.exec),
|
|
174
|
-
coder: first.coder || second.coder,
|
|
175
|
-
reasoning: first.reasoning || second.reasoning,
|
|
176
|
-
declassify: first.declassify || second.declassify
|
|
177
|
-
})
|
|
178
|
-
|
|
179
151
|
const execAllows = (grant: ExecGrant, command: string): boolean => {
|
|
180
152
|
switch (grant._tag) {
|
|
181
153
|
case "Denied":
|
|
@@ -230,25 +202,3 @@ export const restricted =
|
|
|
230
202
|
Effect.flatMap(CurrentGrants, (current) =>
|
|
231
203
|
Effect.provideService(effect, CurrentGrants, intersectGrants(current, grants))
|
|
232
204
|
)
|
|
233
|
-
|
|
234
|
-
export class CapabilityDenied extends Schema.TaggedError<CapabilityDenied>()("CapabilityDenied", {
|
|
235
|
-
required: Schema.Array(Capability),
|
|
236
|
-
granted: Grants
|
|
237
|
-
}) {
|
|
238
|
-
get message(): string {
|
|
239
|
-
const names = this.required.map((capability) =>
|
|
240
|
-
capability._tag === "Exec" ? `Exec(${capability.command})` : capability._tag
|
|
241
|
-
)
|
|
242
|
-
return `missing required capabilities: ${names.join(", ")}`
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
export const requireCapabilities =
|
|
247
|
-
(required: ReadonlyArray<Capability>) =>
|
|
248
|
-
<A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E | CapabilityDenied, R> =>
|
|
249
|
-
Effect.flatMap(CurrentGrants, (granted): Effect.Effect<A, E | CapabilityDenied, R> => {
|
|
250
|
-
const missing = required.filter((capability) => !allows(granted, capability))
|
|
251
|
-
return missing.length === 0
|
|
252
|
-
? effect
|
|
253
|
-
: Effect.fail(new CapabilityDenied({ required: missing, granted }))
|
|
254
|
-
})
|
package/src/Connector.ts
CHANGED
|
@@ -4,7 +4,7 @@ import * as Effect from "effect/Effect"
|
|
|
4
4
|
import * as Schema from "effect/Schema"
|
|
5
5
|
import type * as Stream from "effect/Stream"
|
|
6
6
|
import { CliSandbox } from "./ConnectorConfig.ts"
|
|
7
|
-
import {
|
|
7
|
+
import type { LlmError } from "./Errors.ts"
|
|
8
8
|
import { verbalizedScoreLabels } from "./LabelScoring.ts"
|
|
9
9
|
import type { LlmServiceShape, StructuredResult } from "./LlmService.ts"
|
|
10
10
|
import {
|
|
@@ -16,9 +16,7 @@ import {
|
|
|
16
16
|
type InteractionSupport,
|
|
17
17
|
type JsonSchema,
|
|
18
18
|
type LlmChunk,
|
|
19
|
-
type Message
|
|
20
|
-
type ToolCallResponse,
|
|
21
|
-
type ToolDefinition
|
|
19
|
+
type Message
|
|
22
20
|
} from "./Models.ts"
|
|
23
21
|
import type { ProcessExecutorShape, ProcessResult } from "./ProcessExecutor.ts"
|
|
24
22
|
import { parseFromText, withSchemaHint } from "./StructuredOutput.ts"
|
|
@@ -77,10 +75,6 @@ export interface ApiConnectorPrimitives {
|
|
|
77
75
|
readonly executeStreamWithHistory: (
|
|
78
76
|
messages: ReadonlyArray<Message>
|
|
79
77
|
) => Stream.Stream<LlmChunk, LlmError>
|
|
80
|
-
readonly executeWithTools: (
|
|
81
|
-
prompt: string,
|
|
82
|
-
tools: ReadonlyArray<ToolDefinition>
|
|
83
|
-
) => Effect.Effect<ToolCallResponse, LlmError>
|
|
84
78
|
readonly executeStructuredWithUsage: <A, E, RD, RE>(
|
|
85
79
|
prompt: string,
|
|
86
80
|
schema: Schema.ConstraintCodec<A, E, RD, RE>,
|
|
@@ -204,17 +198,6 @@ export interface CliConnectorPrimitives {
|
|
|
204
198
|
readonly capabilities?: ConnectorCapabilities
|
|
205
199
|
}
|
|
206
200
|
|
|
207
|
-
const unsupportedTools = (
|
|
208
|
-
id: ConnectorId,
|
|
209
|
-
_prompt: string,
|
|
210
|
-
_tools: ReadonlyArray<ToolDefinition>
|
|
211
|
-
): Effect.Effect<ToolCallResponse, LlmError> =>
|
|
212
|
-
Effect.fail(
|
|
213
|
-
InvalidRequestError.make({
|
|
214
|
-
message: `CLI connector ${id.value} does not support tool calling`
|
|
215
|
-
})
|
|
216
|
-
)
|
|
217
|
-
|
|
218
201
|
export const makeCliConnector = (primitives: CliConnectorPrimitives): CliConnectorShape => {
|
|
219
202
|
const executeStructured = <A, E, RD, RE>(
|
|
220
203
|
prompt: string,
|
|
@@ -258,7 +241,6 @@ export const makeCliConnector = (primitives: CliConnectorPrimitives): CliConnect
|
|
|
258
241
|
isAvailable,
|
|
259
242
|
executeStream: primitives.completeStream,
|
|
260
243
|
executeStreamWithHistory: (messages) => primitives.completeStream(flattenHistory(messages)),
|
|
261
|
-
executeWithTools: (prompt, tools) => unsupportedTools(primitives.id, prompt, tools),
|
|
262
244
|
executeStructured,
|
|
263
245
|
executeStructuredWithUsage,
|
|
264
246
|
scoreLabels: verbalizedScoreLabels(executeStructuredWithUsage)
|
package/src/ConnectorRegistry.ts
CHANGED
|
@@ -170,18 +170,3 @@ export const makeConnectorRegistry = (
|
|
|
170
170
|
healthCheckAll
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
|
-
|
|
174
|
-
export const resolveConnector = (
|
|
175
|
-
config: ConnectorConfig
|
|
176
|
-
): Effect.Effect<ConnectorShape, LlmError, ConnectorRegistry> =>
|
|
177
|
-
Effect.flatMap(ConnectorRegistry, (registry) => registry.resolve(config))
|
|
178
|
-
|
|
179
|
-
export const resolveApiConnector = (
|
|
180
|
-
config: ApiConnectorConfig
|
|
181
|
-
): Effect.Effect<ApiConnectorShape, LlmError, ConnectorRegistry> =>
|
|
182
|
-
Effect.flatMap(ConnectorRegistry, (registry) => registry.resolveApi(config))
|
|
183
|
-
|
|
184
|
-
export const resolveCliConnector = (
|
|
185
|
-
config: CliConnectorConfig
|
|
186
|
-
): Effect.Effect<CliConnectorShape, LlmError, ConnectorRegistry> =>
|
|
187
|
-
Effect.flatMap(ConnectorRegistry, (registry) => registry.resolveCli(config))
|
package/src/HttpClient.ts
CHANGED
|
@@ -185,18 +185,3 @@ export const makeRecordingHttpClient = Effect.fn("@llm4ts/core/HttpClient.makeRe
|
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
)
|
|
188
|
-
|
|
189
|
-
export const httpGet = (
|
|
190
|
-
url: string,
|
|
191
|
-
headers: Readonly<Record<string, string>> = emptyHeaders,
|
|
192
|
-
timeout: Duration.Duration
|
|
193
|
-
): Effect.Effect<string, LlmError, HttpClient> =>
|
|
194
|
-
Effect.flatMap(HttpClient, (client) => client.get(url, headers, timeout))
|
|
195
|
-
|
|
196
|
-
export const httpPostJson = (
|
|
197
|
-
url: string,
|
|
198
|
-
body: string,
|
|
199
|
-
headers: Readonly<Record<string, string>> = emptyHeaders,
|
|
200
|
-
timeout: Duration.Duration
|
|
201
|
-
): Effect.Effect<string, LlmError, HttpClient> =>
|
|
202
|
-
Effect.flatMap(HttpClient, (client) => client.postJson(url, body, headers, timeout))
|
package/src/LlmService.ts
CHANGED
|
@@ -4,15 +4,7 @@ import type * as Stream from "effect/Stream"
|
|
|
4
4
|
import type * as Schema from "effect/Schema"
|
|
5
5
|
import type * as Result from "effect/Result"
|
|
6
6
|
import type { LlmError, ParseError } from "./Errors.ts"
|
|
7
|
-
import type {
|
|
8
|
-
JsonSchema,
|
|
9
|
-
LabelDistribution,
|
|
10
|
-
LlmChunk,
|
|
11
|
-
Message,
|
|
12
|
-
TokenUsage,
|
|
13
|
-
ToolCallResponse,
|
|
14
|
-
ToolDefinition
|
|
15
|
-
} from "./Models.ts"
|
|
7
|
+
import type { JsonSchema, LabelDistribution, LlmChunk, Message, TokenUsage } from "./Models.ts"
|
|
16
8
|
|
|
17
9
|
export type StructuredResult<A> = readonly [
|
|
18
10
|
value: A,
|
|
@@ -25,10 +17,6 @@ export interface LlmServiceShape {
|
|
|
25
17
|
readonly executeStreamWithHistory: (
|
|
26
18
|
messages: ReadonlyArray<Message>
|
|
27
19
|
) => Stream.Stream<LlmChunk, LlmError>
|
|
28
|
-
readonly executeWithTools: (
|
|
29
|
-
prompt: string,
|
|
30
|
-
tools: ReadonlyArray<ToolDefinition>
|
|
31
|
-
) => Effect.Effect<ToolCallResponse, LlmError>
|
|
32
20
|
readonly executeStructured: <A, E, RD, RE>(
|
|
33
21
|
prompt: string,
|
|
34
22
|
schema: Schema.ConstraintCodec<A, E, RD, RE>,
|
package/src/Models.ts
CHANGED
|
@@ -223,31 +223,9 @@ export const withConfigDefaults = (config: LlmConfig): LlmConfig => {
|
|
|
223
223
|
return baseUrl === undefined ? config : new LlmConfig({ ...config, baseUrl })
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
-
export class ToolCall extends Schema.Class<ToolCall>("ToolCall")({
|
|
227
|
-
id: Schema.String,
|
|
228
|
-
name: Schema.String,
|
|
229
|
-
arguments: Schema.String
|
|
230
|
-
}) {}
|
|
231
|
-
|
|
232
|
-
const emptyToolCalls: ReadonlyArray<ToolCall> = Object.freeze([])
|
|
233
|
-
|
|
234
|
-
export class ToolCallResponse extends Schema.Class<ToolCallResponse>("ToolCallResponse")({
|
|
235
|
-
content: Schema.optionalKey(Schema.String),
|
|
236
|
-
toolCalls: Schema.Array(ToolCall).pipe(
|
|
237
|
-
Schema.withConstructorDefault(Effect.succeed(emptyToolCalls))
|
|
238
|
-
),
|
|
239
|
-
finishReason: Schema.String
|
|
240
|
-
}) {}
|
|
241
|
-
|
|
242
226
|
export const JsonSchema = Schema.Record(Schema.String, Schema.Json)
|
|
243
227
|
export type JsonSchema = typeof JsonSchema.Type
|
|
244
228
|
|
|
245
|
-
export class ToolDefinition extends Schema.Class<ToolDefinition>("ToolDefinition")({
|
|
246
|
-
name: Schema.String,
|
|
247
|
-
description: Schema.String,
|
|
248
|
-
parameters: JsonSchema
|
|
249
|
-
}) {}
|
|
250
|
-
|
|
251
229
|
export const Availability = Schema.Literals(["Healthy", "Degraded", "Unhealthy", "Unknown"])
|
|
252
230
|
export type Availability = typeof Availability.Type
|
|
253
231
|
|
package/src/Streaming.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import * as Clock from "effect/Clock"
|
|
2
|
-
import * as Deferred from "effect/Deferred"
|
|
3
2
|
import * as Duration from "effect/Duration"
|
|
4
3
|
import * as Effect from "effect/Effect"
|
|
5
|
-
import * as Schema from "effect/Schema"
|
|
6
4
|
import * as Stream from "effect/Stream"
|
|
7
|
-
import {
|
|
8
|
-
import { LlmChunk
|
|
5
|
+
import { TimeoutError, type LlmError } from "./Errors.ts"
|
|
6
|
+
import type { LlmChunk } from "./Models.ts"
|
|
7
|
+
import { LlmResponse, StreamProgress } from "./Models.ts"
|
|
9
8
|
|
|
10
9
|
const appendChunk = (response: LlmResponse, chunk: LlmChunk): LlmResponse => {
|
|
11
10
|
const usage = chunk.usage ?? response.usage
|
|
@@ -65,25 +64,6 @@ export const trackProgress = <R, R2>(
|
|
|
65
64
|
)
|
|
66
65
|
)
|
|
67
66
|
|
|
68
|
-
export const parsePartialJson = <A, E, RD, RE, R>(
|
|
69
|
-
stream: Stream.Stream<string, LlmError, R>,
|
|
70
|
-
schema: Schema.ConstraintCodec<A, E, RD, RE>
|
|
71
|
-
): Stream.Stream<A, LlmError, R | RD> =>
|
|
72
|
-
stream.pipe(
|
|
73
|
-
Stream.mapAccumEffect(
|
|
74
|
-
() => "",
|
|
75
|
-
(accumulated, chunk) => {
|
|
76
|
-
const next = accumulated + chunk
|
|
77
|
-
return Schema.decodeUnknownEffect(Schema.fromJsonString(schema))(next).pipe(
|
|
78
|
-
Effect.match({
|
|
79
|
-
onFailure: () => [next, []] as const,
|
|
80
|
-
onSuccess: (value) => [next, [value]] as const
|
|
81
|
-
})
|
|
82
|
-
)
|
|
83
|
-
}
|
|
84
|
-
)
|
|
85
|
-
)
|
|
86
|
-
|
|
87
67
|
const timeoutError = (duration: Duration.Input): TimeoutError =>
|
|
88
68
|
TimeoutError.make({ duration: Duration.fromInputUnsafe(duration) })
|
|
89
69
|
|
|
@@ -95,79 +75,3 @@ export const withTimeout = <R>(
|
|
|
95
75
|
duration,
|
|
96
76
|
orElse: () => Stream.fail(timeoutError(duration))
|
|
97
77
|
})
|
|
98
|
-
|
|
99
|
-
export const cancellable = <R>(
|
|
100
|
-
stream: Stream.Stream<LlmChunk, LlmError, R>
|
|
101
|
-
): Effect.Effect<
|
|
102
|
-
readonly [stream: Stream.Stream<LlmChunk, LlmError, R>, cancel: Effect.Effect<void>]
|
|
103
|
-
> =>
|
|
104
|
-
Effect.map(Deferred.make<void>(), (deferred) => [
|
|
105
|
-
Stream.interruptWhen(stream, Deferred.await(deferred)),
|
|
106
|
-
Deferred.succeed(deferred, undefined).pipe(Effect.asVoid)
|
|
107
|
-
])
|
|
108
|
-
|
|
109
|
-
export const withSnapshots = <R>(
|
|
110
|
-
stream: Stream.Stream<LlmChunk, LlmError, R>,
|
|
111
|
-
snapshotInterval: Duration.Input = "500 millis"
|
|
112
|
-
): Stream.Stream<string, LlmError, R> =>
|
|
113
|
-
stream.pipe(
|
|
114
|
-
Stream.scan(
|
|
115
|
-
() => "",
|
|
116
|
-
(content, chunk) => content + chunk.delta
|
|
117
|
-
),
|
|
118
|
-
Stream.debounce(snapshotInterval)
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
const chunkJson = Schema.fromJsonString(Schema.toCodecJson(LlmChunk))
|
|
122
|
-
|
|
123
|
-
export const toSSE = <R>(
|
|
124
|
-
stream: Stream.Stream<LlmChunk, LlmError, R>
|
|
125
|
-
): Stream.Stream<string, LlmError, R> =>
|
|
126
|
-
Stream.mapEffect(stream, (chunk) =>
|
|
127
|
-
Schema.encodeEffect(chunkJson)(chunk).pipe(
|
|
128
|
-
Effect.map((encoded) => `data: ${encoded}\n\n`),
|
|
129
|
-
Effect.mapError((error) =>
|
|
130
|
-
ParseError.make({
|
|
131
|
-
message: `Failed to encode SSE chunk: ${String(error)}`,
|
|
132
|
-
raw: chunk.delta
|
|
133
|
-
})
|
|
134
|
-
)
|
|
135
|
-
)
|
|
136
|
-
)
|
|
137
|
-
|
|
138
|
-
export const fromSSE = <R>(
|
|
139
|
-
stream: Stream.Stream<string, LlmError, R>
|
|
140
|
-
): Stream.Stream<LlmChunk, LlmError, R> =>
|
|
141
|
-
stream.pipe(
|
|
142
|
-
Stream.filter((line) => line.startsWith("data: ")),
|
|
143
|
-
Stream.map((line) => line.slice("data: ".length).trim()),
|
|
144
|
-
Stream.filter((payload) => payload.length > 0 && payload !== "[DONE]"),
|
|
145
|
-
Stream.mapEffect((payload) =>
|
|
146
|
-
Schema.decodeUnknownEffect(chunkJson)(payload).pipe(
|
|
147
|
-
Effect.mapError((error) =>
|
|
148
|
-
ParseError.make({
|
|
149
|
-
message: `Failed to parse SSE chunk: ${String(error)}`,
|
|
150
|
-
raw: payload
|
|
151
|
-
})
|
|
152
|
-
)
|
|
153
|
-
)
|
|
154
|
-
)
|
|
155
|
-
)
|
|
156
|
-
|
|
157
|
-
export const withHeartbeat = <R>(
|
|
158
|
-
stream: Stream.Stream<LlmChunk, LlmError, R>,
|
|
159
|
-
heartbeatTimeout: Duration.Input
|
|
160
|
-
): Stream.Stream<LlmChunk, LlmError, R> =>
|
|
161
|
-
withTimeout(stream, heartbeatTimeout).pipe(Stream.rechunk(1))
|
|
162
|
-
|
|
163
|
-
export const parallelStream = <A, B, R>(
|
|
164
|
-
inputs: Iterable<A>,
|
|
165
|
-
parallelism: number,
|
|
166
|
-
f: (input: A) => Stream.Stream<B, LlmError, R>
|
|
167
|
-
): Stream.Stream<B, LlmError, R> =>
|
|
168
|
-
Stream.fromIterable(inputs).pipe(
|
|
169
|
-
Stream.mapEffect((input) => Stream.runCollect(f(input)), {
|
|
170
|
-
concurrency: parallelism
|
|
171
|
-
}),
|
|
172
|
-
Stream.flatMap(Stream.fromIterable)
|
|
173
|
-
)
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as Schema from "effect/Schema"
|
|
2
|
-
import { JsonSchema } from "../Models.ts"
|
|
3
2
|
|
|
4
3
|
/** A prompt-cache breakpoint (ADR 0029): the prefix up to this block is cached. */
|
|
5
4
|
export class AnthropicCacheControl extends Schema.Class<AnthropicCacheControl>(
|
|
@@ -58,52 +57,6 @@ export class AnthropicResponse extends Schema.Class<AnthropicResponse>("Anthropi
|
|
|
58
57
|
stop_reason: Schema.optionalKey(Schema.NullOr(Schema.String))
|
|
59
58
|
}) {}
|
|
60
59
|
|
|
61
|
-
export class AnthropicToolInputSchema extends Schema.Class<AnthropicToolInputSchema>(
|
|
62
|
-
"AnthropicToolInputSchema"
|
|
63
|
-
)({
|
|
64
|
-
type: Schema.String,
|
|
65
|
-
properties: JsonSchema,
|
|
66
|
-
required: Schema.optionalKey(Schema.Array(Schema.String))
|
|
67
|
-
}) {}
|
|
68
|
-
|
|
69
|
-
export class AnthropicTool extends Schema.Class<AnthropicTool>("AnthropicTool")({
|
|
70
|
-
name: Schema.String,
|
|
71
|
-
description: Schema.String,
|
|
72
|
-
input_schema: AnthropicToolInputSchema
|
|
73
|
-
}) {}
|
|
74
|
-
|
|
75
|
-
export class AnthropicContentBlockFull extends Schema.Class<AnthropicContentBlockFull>(
|
|
76
|
-
"AnthropicContentBlockFull"
|
|
77
|
-
)({
|
|
78
|
-
type: Schema.String,
|
|
79
|
-
text: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
80
|
-
id: Schema.optionalKey(Schema.String),
|
|
81
|
-
name: Schema.optionalKey(Schema.String),
|
|
82
|
-
input: Schema.optionalKey(Schema.Json)
|
|
83
|
-
}) {}
|
|
84
|
-
|
|
85
|
-
export class AnthropicRequestWithTools extends Schema.Class<AnthropicRequestWithTools>(
|
|
86
|
-
"AnthropicRequestWithTools"
|
|
87
|
-
)({
|
|
88
|
-
model: Schema.String,
|
|
89
|
-
max_tokens: Schema.Int,
|
|
90
|
-
messages: Schema.Array(AnthropicMessage),
|
|
91
|
-
tools: Schema.Array(AnthropicTool),
|
|
92
|
-
temperature: Schema.optionalKey(Schema.Number),
|
|
93
|
-
system: Schema.optionalKey(Schema.Union([Schema.String, Schema.Array(AnthropicTextBlock)])),
|
|
94
|
-
output_config: Schema.optionalKey(AnthropicOutputConfig)
|
|
95
|
-
}) {}
|
|
96
|
-
|
|
97
|
-
export class AnthropicResponseWithTools extends Schema.Class<AnthropicResponseWithTools>(
|
|
98
|
-
"AnthropicResponseWithTools"
|
|
99
|
-
)({
|
|
100
|
-
id: Schema.optionalKey(Schema.String),
|
|
101
|
-
content: Schema.Array(AnthropicContentBlockFull),
|
|
102
|
-
model: Schema.optionalKey(Schema.String),
|
|
103
|
-
usage: Schema.optionalKey(AnthropicUsage),
|
|
104
|
-
stop_reason: Schema.optionalKey(Schema.NullOr(Schema.String))
|
|
105
|
-
}) {}
|
|
106
|
-
|
|
107
60
|
export class AnthropicStreamChunkDelta extends Schema.Class<AnthropicStreamChunkDelta>(
|
|
108
61
|
"AnthropicStreamChunkDelta"
|
|
109
62
|
)({
|
|
@@ -12,28 +12,20 @@ import {
|
|
|
12
12
|
ConnectorIds,
|
|
13
13
|
LlmChunk,
|
|
14
14
|
TokenUsage,
|
|
15
|
-
ToolCall,
|
|
16
|
-
ToolCallResponse,
|
|
17
15
|
type JsonSchema,
|
|
18
16
|
type LlmConfig,
|
|
19
|
-
type Message
|
|
20
|
-
type ToolDefinition
|
|
17
|
+
type Message
|
|
21
18
|
} from "../Models.ts"
|
|
22
19
|
import { collect } from "../Streaming.ts"
|
|
23
20
|
import { parseFromText } from "../StructuredOutput.ts"
|
|
24
|
-
import type { AnthropicContentBlockFull } from "./AnthropicModels.ts"
|
|
25
21
|
import {
|
|
26
22
|
AnthropicCacheControl,
|
|
27
23
|
AnthropicMessage,
|
|
28
24
|
AnthropicOutputConfig,
|
|
29
25
|
AnthropicRequest,
|
|
30
|
-
AnthropicRequestWithTools,
|
|
31
26
|
AnthropicResponse,
|
|
32
|
-
AnthropicResponseWithTools,
|
|
33
27
|
AnthropicStreamChunk,
|
|
34
28
|
AnthropicTextBlock,
|
|
35
|
-
AnthropicTool,
|
|
36
|
-
AnthropicToolInputSchema,
|
|
37
29
|
AnthropicUsage
|
|
38
30
|
} from "./AnthropicModels.ts"
|
|
39
31
|
|
|
@@ -54,16 +46,6 @@ const decodeResponse = (raw: string): Effect.Effect<AnthropicResponse, ParseErro
|
|
|
54
46
|
)
|
|
55
47
|
)
|
|
56
48
|
|
|
57
|
-
const decodeToolResponse = (raw: string): Effect.Effect<AnthropicResponseWithTools, ParseError> =>
|
|
58
|
-
Schema.decodeUnknownEffect(Schema.fromJsonString(AnthropicResponseWithTools))(raw).pipe(
|
|
59
|
-
Effect.mapError((error) =>
|
|
60
|
-
ParseError.make({
|
|
61
|
-
message: `Failed to decode Anthropic tool response: ${String(error)}`,
|
|
62
|
-
raw
|
|
63
|
-
})
|
|
64
|
-
)
|
|
65
|
-
)
|
|
66
|
-
|
|
67
49
|
const decodeStreamChunk = (raw: string): Effect.Effect<AnthropicStreamChunk, ParseError> =>
|
|
68
50
|
Schema.decodeUnknownEffect(Schema.fromJsonString(AnthropicStreamChunk))(raw).pipe(
|
|
69
51
|
Effect.mapError((error) =>
|
|
@@ -162,36 +144,6 @@ export const anthropicTokenUsage = (usage: AnthropicUsage): TokenUsage => {
|
|
|
162
144
|
})
|
|
163
145
|
}
|
|
164
146
|
|
|
165
|
-
export const buildAnthropicToolRequest = (
|
|
166
|
-
config: LlmConfig,
|
|
167
|
-
prompt: string,
|
|
168
|
-
tools: ReadonlyArray<ToolDefinition>
|
|
169
|
-
): AnthropicRequestWithTools =>
|
|
170
|
-
AnthropicRequestWithTools.make({
|
|
171
|
-
model: config.model,
|
|
172
|
-
max_tokens: config.maxTokens ?? 4096,
|
|
173
|
-
messages: [
|
|
174
|
-
AnthropicMessage.make({
|
|
175
|
-
role: "user",
|
|
176
|
-
content: prompt
|
|
177
|
-
})
|
|
178
|
-
],
|
|
179
|
-
tools: tools.map((tool) =>
|
|
180
|
-
AnthropicTool.make({
|
|
181
|
-
name: tool.name,
|
|
182
|
-
description: tool.description,
|
|
183
|
-
input_schema: AnthropicToolInputSchema.make({
|
|
184
|
-
type: "object",
|
|
185
|
-
properties: tool.parameters
|
|
186
|
-
})
|
|
187
|
-
})
|
|
188
|
-
),
|
|
189
|
-
...(config.temperature === undefined ? {} : { temperature: config.temperature }),
|
|
190
|
-
...(config.effort === undefined
|
|
191
|
-
? {}
|
|
192
|
-
: { output_config: AnthropicOutputConfig.make({ effort: config.effort }) })
|
|
193
|
-
})
|
|
194
|
-
|
|
195
147
|
const contentFromResponse = (
|
|
196
148
|
response: AnthropicResponse,
|
|
197
149
|
raw: string
|
|
@@ -207,8 +159,6 @@ const contentFromResponse = (
|
|
|
207
159
|
: Effect.succeed(content)
|
|
208
160
|
}
|
|
209
161
|
|
|
210
|
-
const jsonString = (value: typeof Schema.Json.Type): string => JSON.stringify(value) ?? "{}"
|
|
211
|
-
|
|
212
162
|
export const makeAnthropicProvider = (
|
|
213
163
|
config: LlmConfig,
|
|
214
164
|
httpClient: HttpClientShape
|
|
@@ -352,41 +302,6 @@ export const makeAnthropicProvider = (
|
|
|
352
302
|
return result
|
|
353
303
|
})
|
|
354
304
|
|
|
355
|
-
const executeWithTools = (
|
|
356
|
-
prompt: string,
|
|
357
|
-
tools: ReadonlyArray<ToolDefinition>
|
|
358
|
-
): Effect.Effect<ToolCallResponse, LlmError> =>
|
|
359
|
-
Effect.gen(function* () {
|
|
360
|
-
const { apiKey, baseUrl } = yield* requiredConfig
|
|
361
|
-
const request = buildAnthropicToolRequest(config, prompt, tools)
|
|
362
|
-
const raw = yield* httpClient.postJson(
|
|
363
|
-
`${baseUrl}/messages`,
|
|
364
|
-
JSON.stringify(request),
|
|
365
|
-
authHeaders(apiKey),
|
|
366
|
-
config.timeout
|
|
367
|
-
)
|
|
368
|
-
const response = yield* decodeToolResponse(raw)
|
|
369
|
-
const toolCalls = response.content
|
|
370
|
-
.filter((block) => block.type === "tool_use")
|
|
371
|
-
.map((block) =>
|
|
372
|
-
ToolCall.make({
|
|
373
|
-
id: block.id ?? "",
|
|
374
|
-
name: block.name ?? "",
|
|
375
|
-
arguments: block.input === undefined ? "{}" : jsonString(block.input)
|
|
376
|
-
})
|
|
377
|
-
)
|
|
378
|
-
const content = response.content.find(
|
|
379
|
-
(block): block is AnthropicContentBlockFull =>
|
|
380
|
-
block.type === "text" && block.text !== undefined && block.text !== null
|
|
381
|
-
)?.text
|
|
382
|
-
|
|
383
|
-
return ToolCallResponse.make({
|
|
384
|
-
toolCalls,
|
|
385
|
-
finishReason: response.stop_reason ?? "stop",
|
|
386
|
-
...(content === undefined || content === null ? {} : { content })
|
|
387
|
-
})
|
|
388
|
-
})
|
|
389
|
-
|
|
390
305
|
const executeStream = (prompt: string): Stream.Stream<LlmChunk, LlmError> =>
|
|
391
306
|
executeStreamRequest([
|
|
392
307
|
AnthropicMessage.make({
|
|
@@ -409,7 +324,6 @@ export const makeAnthropicProvider = (
|
|
|
409
324
|
const history = anthropicHistory(messages)
|
|
410
325
|
return executeStreamRequest(history.messages, history.system)
|
|
411
326
|
},
|
|
412
|
-
executeWithTools,
|
|
413
327
|
executeStructuredWithUsage,
|
|
414
328
|
isAvailable,
|
|
415
329
|
capabilities: ConnectorCapabilities.make({ readOnlyEnforcement: "enforced", effort: "mapped" })
|