@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.
Files changed (142) hide show
  1. package/README.md +1 -1
  2. package/dist/Capability.d.ts +0 -9
  3. package/dist/Capability.d.ts.map +1 -1
  4. package/dist/Capability.js +0 -38
  5. package/dist/Capability.js.map +1 -1
  6. package/dist/Connector.d.ts +2 -3
  7. package/dist/Connector.d.ts.map +1 -1
  8. package/dist/Connector.js +0 -5
  9. package/dist/Connector.js.map +1 -1
  10. package/dist/ConnectorRegistry.d.ts +0 -3
  11. package/dist/ConnectorRegistry.d.ts.map +1 -1
  12. package/dist/ConnectorRegistry.js +0 -3
  13. package/dist/ConnectorRegistry.js.map +1 -1
  14. package/dist/HttpClient.d.ts +0 -2
  15. package/dist/HttpClient.d.ts.map +1 -1
  16. package/dist/HttpClient.js +0 -2
  17. package/dist/HttpClient.js.map +1 -1
  18. package/dist/LlmService.d.ts +1 -2
  19. package/dist/LlmService.d.ts.map +1 -1
  20. package/dist/LlmService.js.map +1 -1
  21. package/dist/Models.d.ts +0 -21
  22. package/dist/Models.d.ts.map +1 -1
  23. package/dist/Models.js +0 -19
  24. package/dist/Models.js.map +1 -1
  25. package/dist/Streaming.d.ts +4 -11
  26. package/dist/Streaming.d.ts.map +1 -1
  27. package/dist/Streaming.js +2 -29
  28. package/dist/Streaming.js.map +1 -1
  29. package/dist/providers/AnthropicModels.d.ts +0 -43
  30. package/dist/providers/AnthropicModels.d.ts.map +1 -1
  31. package/dist/providers/AnthropicModels.js +0 -39
  32. package/dist/providers/AnthropicModels.js.map +1 -1
  33. package/dist/providers/AnthropicProvider.d.ts +2 -3
  34. package/dist/providers/AnthropicProvider.d.ts.map +1 -1
  35. package/dist/providers/AnthropicProvider.js +2 -49
  36. package/dist/providers/AnthropicProvider.js.map +1 -1
  37. package/dist/providers/GeminiApiProvider.d.ts +2 -3
  38. package/dist/providers/GeminiApiProvider.d.ts.map +1 -1
  39. package/dist/providers/GeminiApiProvider.js +2 -44
  40. package/dist/providers/GeminiApiProvider.js.map +1 -1
  41. package/dist/providers/GeminiModels.d.ts +0 -48
  42. package/dist/providers/GeminiModels.d.ts.map +1 -1
  43. package/dist/providers/GeminiModels.js +0 -40
  44. package/dist/providers/GeminiModels.js.map +1 -1
  45. package/dist/providers/LmStudioProvider.d.ts.map +1 -1
  46. package/dist/providers/LmStudioProvider.js +1 -4
  47. package/dist/providers/LmStudioProvider.js.map +1 -1
  48. package/dist/providers/MlxLmProvider.d.ts.map +1 -1
  49. package/dist/providers/MlxLmProvider.js +1 -2
  50. package/dist/providers/MlxLmProvider.js.map +1 -1
  51. package/dist/providers/MockProvider.d.ts.map +1 -1
  52. package/dist/providers/MockProvider.js +1 -6
  53. package/dist/providers/MockProvider.js.map +1 -1
  54. package/dist/providers/OllamaProvider.d.ts.map +1 -1
  55. package/dist/providers/OllamaProvider.js +1 -4
  56. package/dist/providers/OllamaProvider.js.map +1 -1
  57. package/dist/providers/OpenAIModels.d.ts +0 -58
  58. package/dist/providers/OpenAIModels.d.ts.map +1 -1
  59. package/dist/providers/OpenAIModels.js +0 -51
  60. package/dist/providers/OpenAIModels.js.map +1 -1
  61. package/dist/providers/OpenAIProvider.d.ts +2 -3
  62. package/dist/providers/OpenAIProvider.d.ts.map +1 -1
  63. package/dist/providers/OpenAIProvider.js +2 -46
  64. package/dist/providers/OpenAIProvider.js.map +1 -1
  65. package/package.json +2 -14
  66. package/src/Capability.ts +0 -50
  67. package/src/Connector.ts +2 -20
  68. package/src/ConnectorRegistry.ts +0 -15
  69. package/src/HttpClient.ts +0 -15
  70. package/src/LlmService.ts +1 -13
  71. package/src/Models.ts +0 -22
  72. package/src/Streaming.ts +3 -99
  73. package/src/providers/AnthropicModels.ts +0 -47
  74. package/src/providers/AnthropicProvider.ts +1 -87
  75. package/src/providers/GeminiApiProvider.ts +2 -83
  76. package/src/providers/GeminiModels.ts +0 -46
  77. package/src/providers/LmStudioProvider.ts +1 -7
  78. package/src/providers/MlxLmProvider.ts +1 -3
  79. package/src/providers/MockProvider.ts +0 -9
  80. package/src/providers/OllamaProvider.ts +1 -7
  81. package/src/providers/OpenAIModels.ts +0 -64
  82. package/src/providers/OpenAIProvider.ts +2 -83
  83. package/dist/ContextManagement.d.ts +0 -78
  84. package/dist/ContextManagement.d.ts.map +0 -1
  85. package/dist/ContextManagement.js +0 -222
  86. package/dist/ContextManagement.js.map +0 -1
  87. package/dist/Conversation.d.ts +0 -18
  88. package/dist/Conversation.d.ts.map +0 -1
  89. package/dist/Conversation.js +0 -17
  90. package/dist/Conversation.js.map +0 -1
  91. package/dist/RateLimiter.d.ts +0 -44
  92. package/dist/RateLimiter.d.ts.map +0 -1
  93. package/dist/RateLimiter.js +0 -155
  94. package/dist/RateLimiter.js.map +0 -1
  95. package/dist/observability/MeteredLlmService.d.ts +0 -16
  96. package/dist/observability/MeteredLlmService.d.ts.map +0 -1
  97. package/dist/observability/MeteredLlmService.js +0 -72
  98. package/dist/observability/MeteredLlmService.js.map +0 -1
  99. package/dist/observability/Metrics.d.ts +0 -76
  100. package/dist/observability/Metrics.d.ts.map +0 -1
  101. package/dist/observability/Metrics.js +0 -152
  102. package/dist/observability/Metrics.js.map +0 -1
  103. package/dist/observability/StructuredLogger.d.ts +0 -31
  104. package/dist/observability/StructuredLogger.d.ts.map +0 -1
  105. package/dist/observability/StructuredLogger.js +0 -39
  106. package/dist/observability/StructuredLogger.js.map +0 -1
  107. package/dist/observability/Tracing.d.ts +0 -38
  108. package/dist/observability/Tracing.d.ts.map +0 -1
  109. package/dist/observability/Tracing.js +0 -80
  110. package/dist/observability/Tracing.js.map +0 -1
  111. package/dist/providers/OpenCodeModels.d.ts +0 -61
  112. package/dist/providers/OpenCodeModels.d.ts.map +0 -1
  113. package/dist/providers/OpenCodeModels.js +0 -53
  114. package/dist/providers/OpenCodeModels.js.map +0 -1
  115. package/dist/providers/OpenCodeProvider.d.ts +0 -10
  116. package/dist/providers/OpenCodeProvider.d.ts.map +0 -1
  117. package/dist/providers/OpenCodeProvider.js +0 -154
  118. package/dist/providers/OpenCodeProvider.js.map +0 -1
  119. package/dist/tools/Tool.d.ts +0 -83
  120. package/dist/tools/Tool.d.ts.map +0 -1
  121. package/dist/tools/Tool.js +0 -278
  122. package/dist/tools/Tool.js.map +0 -1
  123. package/dist/tools/ToolCallingExecutor.d.ts +0 -18
  124. package/dist/tools/ToolCallingExecutor.d.ts.map +0 -1
  125. package/dist/tools/ToolCallingExecutor.js +0 -64
  126. package/dist/tools/ToolCallingExecutor.js.map +0 -1
  127. package/dist/tools/ToolRegistry.d.ts +0 -45
  128. package/dist/tools/ToolRegistry.d.ts.map +0 -1
  129. package/dist/tools/ToolRegistry.js +0 -133
  130. package/dist/tools/ToolRegistry.js.map +0 -1
  131. package/src/ContextManagement.ts +0 -367
  132. package/src/Conversation.ts +0 -21
  133. package/src/RateLimiter.ts +0 -238
  134. package/src/observability/MeteredLlmService.ts +0 -168
  135. package/src/observability/Metrics.ts +0 -200
  136. package/src/observability/StructuredLogger.ts +0 -67
  137. package/src/observability/Tracing.ts +0 -146
  138. package/src/providers/OpenCodeModels.ts +0 -60
  139. package/src/providers/OpenCodeProvider.ts +0 -278
  140. package/src/tools/Tool.ts +0 -376
  141. package/src/tools/ToolCallingExecutor.ts +0 -106
  142. package/src/tools/ToolRegistry.ts +0 -224
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@llm4ts/core",
3
- "version": "2.54.1",
4
- "description": "Effect-native LLM contracts, providers, tools, evaluation, and observability",
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 { InvalidRequestError, type LlmError } from "./Errors.ts"
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)
@@ -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 { ParseError, TimeoutError, type LlmError } from "./Errors.ts"
8
- import { LlmChunk, LlmResponse, StreamProgress } from "./Models.ts"
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" })