@llm4ts/core 0.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/LICENSE +21 -0
- package/README.md +47 -0
- package/dist/AgentSession.d.ts +66 -0
- package/dist/AgentSession.d.ts.map +1 -0
- package/dist/AgentSession.js +53 -0
- package/dist/AgentSession.js.map +1 -0
- package/dist/Capability.d.ts +101 -0
- package/dist/Capability.d.ts.map +1 -0
- package/dist/Capability.js +210 -0
- package/dist/Capability.js.map +1 -0
- package/dist/Connector.d.ts +69 -0
- package/dist/Connector.d.ts.map +1 -0
- package/dist/Connector.js +86 -0
- package/dist/Connector.js.map +1 -0
- package/dist/ConnectorConfig.d.ts +70 -0
- package/dist/ConnectorConfig.d.ts.map +1 -0
- package/dist/ConnectorConfig.js +110 -0
- package/dist/ConnectorConfig.js.map +1 -0
- package/dist/ConnectorRegistry.d.ts +28 -0
- package/dist/ConnectorRegistry.d.ts.map +1 -0
- package/dist/ConnectorRegistry.js +87 -0
- package/dist/ConnectorRegistry.js.map +1 -0
- package/dist/ContextManagement.d.ts +78 -0
- package/dist/ContextManagement.d.ts.map +1 -0
- package/dist/ContextManagement.js +221 -0
- package/dist/ContextManagement.js.map +1 -0
- package/dist/Conversation.d.ts +18 -0
- package/dist/Conversation.d.ts.map +1 -0
- package/dist/Conversation.js +17 -0
- package/dist/Conversation.js.map +1 -0
- package/dist/Errors.d.ts +64 -0
- package/dist/Errors.d.ts.map +1 -0
- package/dist/Errors.js +76 -0
- package/dist/Errors.js.map +1 -0
- package/dist/HttpClient.d.ts +43 -0
- package/dist/HttpClient.d.ts.map +1 -0
- package/dist/HttpClient.js +99 -0
- package/dist/HttpClient.js.map +1 -0
- package/dist/LlmService.d.ts +24 -0
- package/dist/LlmService.d.ts.map +1 -0
- package/dist/LlmService.js +4 -0
- package/dist/LlmService.js.map +1 -0
- package/dist/Models.d.ts +138 -0
- package/dist/Models.d.ts.map +1 -0
- package/dist/Models.js +209 -0
- package/dist/Models.js.map +1 -0
- package/dist/ProcessExecutor.d.ts +57 -0
- package/dist/ProcessExecutor.d.ts.map +1 -0
- package/dist/ProcessExecutor.js +71 -0
- package/dist/ProcessExecutor.js.map +1 -0
- package/dist/RateLimiter.d.ts +44 -0
- package/dist/RateLimiter.d.ts.map +1 -0
- package/dist/RateLimiter.js +155 -0
- package/dist/RateLimiter.js.map +1 -0
- package/dist/Streaming.d.ts +17 -0
- package/dist/Streaming.d.ts.map +1 -0
- package/dist/Streaming.js +65 -0
- package/dist/Streaming.js.map +1 -0
- package/dist/StructuredOutput.d.ts +10 -0
- package/dist/StructuredOutput.d.ts.map +1 -0
- package/dist/StructuredOutput.js +97 -0
- package/dist/StructuredOutput.js.map +1 -0
- package/dist/TemporaryFiles.d.ts +20 -0
- package/dist/TemporaryFiles.d.ts.map +1 -0
- package/dist/TemporaryFiles.js +18 -0
- package/dist/TemporaryFiles.js.map +1 -0
- package/dist/UsageLimits.d.ts +5 -0
- package/dist/UsageLimits.d.ts.map +1 -0
- package/dist/UsageLimits.js +187 -0
- package/dist/UsageLimits.js.map +1 -0
- package/dist/eval/Checks.d.ts +6 -0
- package/dist/eval/Checks.d.ts.map +1 -0
- package/dist/eval/Checks.js +39 -0
- package/dist/eval/Checks.js.map +1 -0
- package/dist/eval/Eval.d.ts +57 -0
- package/dist/eval/Eval.d.ts.map +1 -0
- package/dist/eval/Eval.js +91 -0
- package/dist/eval/Eval.js.map +1 -0
- package/dist/eval/EvalSuite.d.ts +21 -0
- package/dist/eval/EvalSuite.d.ts.map +1 -0
- package/dist/eval/EvalSuite.js +30 -0
- package/dist/eval/EvalSuite.js.map +1 -0
- package/dist/eval/Evaluator.d.ts +10 -0
- package/dist/eval/Evaluator.d.ts.map +1 -0
- package/dist/eval/Evaluator.js +14 -0
- package/dist/eval/Evaluator.js.map +1 -0
- package/dist/eval/Judge.d.ts +15 -0
- package/dist/eval/Judge.d.ts.map +1 -0
- package/dist/eval/Judge.js +73 -0
- package/dist/eval/Judge.js.map +1 -0
- package/dist/observability/MeteredLlmService.d.ts +16 -0
- package/dist/observability/MeteredLlmService.d.ts.map +1 -0
- package/dist/observability/MeteredLlmService.js +66 -0
- package/dist/observability/MeteredLlmService.js.map +1 -0
- package/dist/observability/Metrics.d.ts +71 -0
- package/dist/observability/Metrics.d.ts.map +1 -0
- package/dist/observability/Metrics.js +147 -0
- package/dist/observability/Metrics.js.map +1 -0
- package/dist/observability/Redaction.d.ts +8 -0
- package/dist/observability/Redaction.d.ts.map +1 -0
- package/dist/observability/Redaction.js +38 -0
- package/dist/observability/Redaction.js.map +1 -0
- package/dist/observability/StreamRecorder.d.ts +9 -0
- package/dist/observability/StreamRecorder.d.ts.map +1 -0
- package/dist/observability/StreamRecorder.js +10 -0
- package/dist/observability/StreamRecorder.js.map +1 -0
- package/dist/observability/StructuredLogger.d.ts +31 -0
- package/dist/observability/StructuredLogger.d.ts.map +1 -0
- package/dist/observability/StructuredLogger.js +34 -0
- package/dist/observability/StructuredLogger.js.map +1 -0
- package/dist/observability/Tracing.d.ts +38 -0
- package/dist/observability/Tracing.d.ts.map +1 -0
- package/dist/observability/Tracing.js +75 -0
- package/dist/observability/Tracing.js.map +1 -0
- package/dist/providers/AnthropicModels.d.ts +95 -0
- package/dist/providers/AnthropicModels.d.ts.map +1 -0
- package/dist/providers/AnthropicModels.js +83 -0
- package/dist/providers/AnthropicModels.js.map +1 -0
- package/dist/providers/AnthropicProvider.d.ts +13 -0
- package/dist/providers/AnthropicProvider.d.ts.map +1 -0
- package/dist/providers/AnthropicProvider.js +177 -0
- package/dist/providers/AnthropicProvider.js.map +1 -0
- package/dist/providers/AntigravityConnector.d.ts +7 -0
- package/dist/providers/AntigravityConnector.d.ts.map +1 -0
- package/dist/providers/AntigravityConnector.js +52 -0
- package/dist/providers/AntigravityConnector.js.map +1 -0
- package/dist/providers/ClaudeAgentSession.d.ts +11 -0
- package/dist/providers/ClaudeAgentSession.d.ts.map +1 -0
- package/dist/providers/ClaudeAgentSession.js +158 -0
- package/dist/providers/ClaudeAgentSession.js.map +1 -0
- package/dist/providers/ClaudeCliConnector.d.ts +9 -0
- package/dist/providers/ClaudeCliConnector.d.ts.map +1 -0
- package/dist/providers/ClaudeCliConnector.js +123 -0
- package/dist/providers/ClaudeCliConnector.js.map +1 -0
- package/dist/providers/CliSupport.d.ts +21 -0
- package/dist/providers/CliSupport.d.ts.map +1 -0
- package/dist/providers/CliSupport.js +62 -0
- package/dist/providers/CliSupport.js.map +1 -0
- package/dist/providers/CodexConnector.d.ts +12 -0
- package/dist/providers/CodexConnector.d.ts.map +1 -0
- package/dist/providers/CodexConnector.js +175 -0
- package/dist/providers/CodexConnector.js.map +1 -0
- package/dist/providers/ConnectorFactories.d.ts +15 -0
- package/dist/providers/ConnectorFactories.d.ts.map +1 -0
- package/dist/providers/ConnectorFactories.js +74 -0
- package/dist/providers/ConnectorFactories.js.map +1 -0
- package/dist/providers/CopilotConnector.d.ts +6 -0
- package/dist/providers/CopilotConnector.d.ts.map +1 -0
- package/dist/providers/CopilotConnector.js +35 -0
- package/dist/providers/CopilotConnector.js.map +1 -0
- package/dist/providers/CursorConnector.d.ts +8 -0
- package/dist/providers/CursorConnector.d.ts.map +1 -0
- package/dist/providers/CursorConnector.js +82 -0
- package/dist/providers/CursorConnector.js.map +1 -0
- package/dist/providers/GeminiApiProvider.d.ts +9 -0
- package/dist/providers/GeminiApiProvider.d.ts.map +1 -0
- package/dist/providers/GeminiApiProvider.js +181 -0
- package/dist/providers/GeminiApiProvider.js.map +1 -0
- package/dist/providers/GeminiCliProvider.d.ts +106 -0
- package/dist/providers/GeminiCliProvider.d.ts.map +1 -0
- package/dist/providers/GeminiCliProvider.js +596 -0
- package/dist/providers/GeminiCliProvider.js.map +1 -0
- package/dist/providers/GeminiModels.d.ts +92 -0
- package/dist/providers/GeminiModels.d.ts.map +1 -0
- package/dist/providers/GeminiModels.js +80 -0
- package/dist/providers/GeminiModels.js.map +1 -0
- package/dist/providers/GrokCliConnector.d.ts +8 -0
- package/dist/providers/GrokCliConnector.d.ts.map +1 -0
- package/dist/providers/GrokCliConnector.js +82 -0
- package/dist/providers/GrokCliConnector.js.map +1 -0
- package/dist/providers/LmStudioModels.d.ts +114 -0
- package/dist/providers/LmStudioModels.d.ts.map +1 -0
- package/dist/providers/LmStudioModels.js +102 -0
- package/dist/providers/LmStudioModels.js.map +1 -0
- package/dist/providers/LmStudioProvider.d.ts +13 -0
- package/dist/providers/LmStudioProvider.d.ts.map +1 -0
- package/dist/providers/LmStudioProvider.js +158 -0
- package/dist/providers/LmStudioProvider.js.map +1 -0
- package/dist/providers/MockProvider.d.ts +6 -0
- package/dist/providers/MockProvider.d.ts.map +1 -0
- package/dist/providers/MockProvider.js +271 -0
- package/dist/providers/MockProvider.js.map +1 -0
- package/dist/providers/OllamaModels.d.ts +68 -0
- package/dist/providers/OllamaModels.d.ts.map +1 -0
- package/dist/providers/OllamaModels.js +59 -0
- package/dist/providers/OllamaModels.js.map +1 -0
- package/dist/providers/OllamaProvider.d.ts +7 -0
- package/dist/providers/OllamaProvider.d.ts.map +1 -0
- package/dist/providers/OllamaProvider.js +134 -0
- package/dist/providers/OllamaProvider.js.map +1 -0
- package/dist/providers/OpenAIModels.d.ts +139 -0
- package/dist/providers/OpenAIModels.d.ts.map +1 -0
- package/dist/providers/OpenAIModels.js +123 -0
- package/dist/providers/OpenAIModels.js.map +1 -0
- package/dist/providers/OpenAIProvider.d.ts +9 -0
- package/dist/providers/OpenAIProvider.d.ts.map +1 -0
- package/dist/providers/OpenAIProvider.js +185 -0
- package/dist/providers/OpenAIProvider.js.map +1 -0
- package/dist/providers/OpenCodeCliConnector.d.ts +8 -0
- package/dist/providers/OpenCodeCliConnector.d.ts.map +1 -0
- package/dist/providers/OpenCodeCliConnector.js +93 -0
- package/dist/providers/OpenCodeCliConnector.js.map +1 -0
- package/dist/providers/OpenCodeModels.d.ts +61 -0
- package/dist/providers/OpenCodeModels.d.ts.map +1 -0
- package/dist/providers/OpenCodeModels.js +53 -0
- package/dist/providers/OpenCodeModels.js.map +1 -0
- package/dist/providers/OpenCodeProvider.d.ts +10 -0
- package/dist/providers/OpenCodeProvider.d.ts.map +1 -0
- package/dist/providers/OpenCodeProvider.js +154 -0
- package/dist/providers/OpenCodeProvider.js.map +1 -0
- package/dist/providers/PiConnector.d.ts +8 -0
- package/dist/providers/PiConnector.d.ts.map +1 -0
- package/dist/providers/PiConnector.js +99 -0
- package/dist/providers/PiConnector.js.map +1 -0
- package/dist/tools/Tool.d.ts +83 -0
- package/dist/tools/Tool.d.ts.map +1 -0
- package/dist/tools/Tool.js +278 -0
- package/dist/tools/Tool.js.map +1 -0
- package/dist/tools/ToolCallingExecutor.d.ts +18 -0
- package/dist/tools/ToolCallingExecutor.d.ts.map +1 -0
- package/dist/tools/ToolCallingExecutor.js +64 -0
- package/dist/tools/ToolCallingExecutor.js.map +1 -0
- package/dist/tools/ToolRegistry.d.ts +45 -0
- package/dist/tools/ToolRegistry.d.ts.map +1 -0
- package/dist/tools/ToolRegistry.js +133 -0
- package/dist/tools/ToolRegistry.js.map +1 -0
- package/package.json +105 -0
- package/src/.gitkeep +1 -0
- package/src/AgentSession.ts +69 -0
- package/src/Capability.ts +240 -0
- package/src/Connector.ts +220 -0
- package/src/ConnectorConfig.ts +146 -0
- package/src/ConnectorRegistry.ts +184 -0
- package/src/ContextManagement.ts +372 -0
- package/src/Conversation.ts +21 -0
- package/src/Errors.ts +87 -0
- package/src/HttpClient.ts +202 -0
- package/src/LlmService.ts +45 -0
- package/src/Models.ts +250 -0
- package/src/ProcessExecutor.ts +157 -0
- package/src/RateLimiter.ts +238 -0
- package/src/Streaming.ts +164 -0
- package/src/StructuredOutput.ts +138 -0
- package/src/TemporaryFiles.ts +51 -0
- package/src/UsageLimits.ts +242 -0
- package/src/eval/Checks.ts +68 -0
- package/src/eval/Eval.ts +112 -0
- package/src/eval/EvalSuite.ts +63 -0
- package/src/eval/Evaluator.ts +31 -0
- package/src/eval/Judge.ts +92 -0
- package/src/observability/MeteredLlmService.ts +156 -0
- package/src/observability/Metrics.ts +195 -0
- package/src/observability/Redaction.ts +55 -0
- package/src/observability/StreamRecorder.ts +32 -0
- package/src/observability/StructuredLogger.ts +62 -0
- package/src/observability/Tracing.ts +141 -0
- package/src/providers/AnthropicModels.ts +96 -0
- package/src/providers/AnthropicProvider.ts +320 -0
- package/src/providers/AntigravityConnector.ts +77 -0
- package/src/providers/ClaudeAgentSession.ts +226 -0
- package/src/providers/ClaudeCliConnector.ts +201 -0
- package/src/providers/CliSupport.ts +100 -0
- package/src/providers/CodexConnector.ts +251 -0
- package/src/providers/ConnectorFactories.ts +142 -0
- package/src/providers/CopilotConnector.ts +47 -0
- package/src/providers/CursorConnector.ts +120 -0
- package/src/providers/GeminiApiProvider.ts +337 -0
- package/src/providers/GeminiCliProvider.ts +793 -0
- package/src/providers/GeminiModels.ts +97 -0
- package/src/providers/GrokCliConnector.ts +117 -0
- package/src/providers/LmStudioModels.ts +117 -0
- package/src/providers/LmStudioProvider.ts +260 -0
- package/src/providers/MockProvider.ts +322 -0
- package/src/providers/OllamaModels.ts +64 -0
- package/src/providers/OllamaProvider.ts +236 -0
- package/src/providers/OpenAIModels.ts +152 -0
- package/src/providers/OpenAIProvider.ts +331 -0
- package/src/providers/OpenCodeCliConnector.ts +135 -0
- package/src/providers/OpenCodeModels.ts +60 -0
- package/src/providers/OpenCodeProvider.ts +278 -0
- package/src/providers/PiConnector.ts +142 -0
- package/src/tools/Tool.ts +379 -0
- package/src/tools/ToolCallingExecutor.ts +106 -0
- package/src/tools/ToolRegistry.ts +224 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect"
|
|
2
|
+
import * as Schema from "effect/Schema"
|
|
3
|
+
|
|
4
|
+
export const PromptRole = Schema.Literals(["System", "User", "Assistant", "Tool"])
|
|
5
|
+
export type PromptRole = typeof PromptRole.Type
|
|
6
|
+
|
|
7
|
+
const emptyMetadata: Readonly<Record<string, string>> = Object.freeze({})
|
|
8
|
+
|
|
9
|
+
export class ConversationMessage extends Schema.Class<ConversationMessage>("ConversationMessage")({
|
|
10
|
+
id: Schema.String,
|
|
11
|
+
role: PromptRole,
|
|
12
|
+
content: Schema.String,
|
|
13
|
+
timestamp: Schema.DateTimeUtc,
|
|
14
|
+
tokens: Schema.Int.pipe(Schema.withConstructorDefault(Effect.succeed(0))),
|
|
15
|
+
model: Schema.optionalKey(Schema.String),
|
|
16
|
+
costUsd: Schema.optionalKey(Schema.Number),
|
|
17
|
+
metadata: Schema.Record(Schema.String, Schema.String).pipe(
|
|
18
|
+
Schema.withConstructorDefault(Effect.succeed(emptyMetadata))
|
|
19
|
+
),
|
|
20
|
+
important: Schema.Boolean.pipe(Schema.withConstructorDefault(Effect.succeed(false)))
|
|
21
|
+
}) {}
|
package/src/Errors.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import * as Duration from "effect/Duration"
|
|
2
|
+
import * as Schema from "effect/Schema"
|
|
3
|
+
|
|
4
|
+
export class ProviderError extends Schema.TaggedErrorClass<ProviderError>()("ProviderError", {
|
|
5
|
+
message: Schema.String,
|
|
6
|
+
cause: Schema.optionalKey(Schema.Defect())
|
|
7
|
+
}) {}
|
|
8
|
+
|
|
9
|
+
export class UsageLimitError extends Schema.TaggedErrorClass<UsageLimitError>()("UsageLimitError", {
|
|
10
|
+
resetAt: Schema.optionalKey(Schema.DateTimeUtc),
|
|
11
|
+
provider: Schema.String,
|
|
12
|
+
message: Schema.String
|
|
13
|
+
}) {}
|
|
14
|
+
|
|
15
|
+
export class AuthenticationError extends Schema.TaggedErrorClass<AuthenticationError>()(
|
|
16
|
+
"AuthenticationError",
|
|
17
|
+
{
|
|
18
|
+
message: Schema.String
|
|
19
|
+
}
|
|
20
|
+
) {}
|
|
21
|
+
|
|
22
|
+
export class InvalidRequestError extends Schema.TaggedErrorClass<InvalidRequestError>()(
|
|
23
|
+
"InvalidRequestError",
|
|
24
|
+
{
|
|
25
|
+
message: Schema.String
|
|
26
|
+
}
|
|
27
|
+
) {}
|
|
28
|
+
|
|
29
|
+
export class ParseError extends Schema.TaggedErrorClass<ParseError>()("ParseError", {
|
|
30
|
+
message: Schema.String,
|
|
31
|
+
raw: Schema.String
|
|
32
|
+
}) {}
|
|
33
|
+
|
|
34
|
+
export class ToolError extends Schema.TaggedErrorClass<ToolError>()("ToolError", {
|
|
35
|
+
toolName: Schema.String,
|
|
36
|
+
detail: Schema.String
|
|
37
|
+
}) {
|
|
38
|
+
get message(): string {
|
|
39
|
+
return `tool '${this.toolName}' failed: ${this.detail}`
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export class ConfigError extends Schema.TaggedErrorClass<ConfigError>()("ConfigError", {
|
|
44
|
+
message: Schema.String
|
|
45
|
+
}) {}
|
|
46
|
+
|
|
47
|
+
export class RateLimitError extends Schema.TaggedErrorClass<RateLimitError>()("RateLimitError", {
|
|
48
|
+
retryAfter: Schema.optionalKey(Schema.Duration)
|
|
49
|
+
}) {
|
|
50
|
+
get message(): string {
|
|
51
|
+
return this.retryAfter === undefined
|
|
52
|
+
? "rate limited"
|
|
53
|
+
: `rate limited; retry after ${Duration.format(this.retryAfter)}`
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export class TimeoutError extends Schema.TaggedErrorClass<TimeoutError>()("TimeoutError", {
|
|
58
|
+
duration: Schema.Duration
|
|
59
|
+
}) {
|
|
60
|
+
get message(): string {
|
|
61
|
+
return `timed out after ${Duration.format(this.duration)}`
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export class TurnLimitError extends Schema.TaggedErrorClass<TurnLimitError>()("TurnLimitError", {
|
|
66
|
+
limit: Schema.optionalKey(Schema.Int)
|
|
67
|
+
}) {
|
|
68
|
+
get message(): string {
|
|
69
|
+
return this.limit === undefined
|
|
70
|
+
? "turn limit reached"
|
|
71
|
+
: `turn limit reached after ${this.limit} turn(s)`
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export const LlmError = Schema.Union([
|
|
76
|
+
ProviderError,
|
|
77
|
+
UsageLimitError,
|
|
78
|
+
AuthenticationError,
|
|
79
|
+
InvalidRequestError,
|
|
80
|
+
ParseError,
|
|
81
|
+
ToolError,
|
|
82
|
+
ConfigError,
|
|
83
|
+
RateLimitError,
|
|
84
|
+
TimeoutError,
|
|
85
|
+
TurnLimitError
|
|
86
|
+
])
|
|
87
|
+
export type LlmError = typeof LlmError.Type
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import * as Context from "effect/Context"
|
|
2
|
+
import type * as Duration from "effect/Duration"
|
|
3
|
+
import * as Effect from "effect/Effect"
|
|
4
|
+
import * as Ref from "effect/Ref"
|
|
5
|
+
import * as Schema from "effect/Schema"
|
|
6
|
+
import * as Stream from "effect/Stream"
|
|
7
|
+
import { InvalidRequestError, type LlmError } from "./Errors.ts"
|
|
8
|
+
|
|
9
|
+
const emptyHeaders: Readonly<Record<string, string>> = Object.freeze({})
|
|
10
|
+
|
|
11
|
+
export class HttpRequest extends Schema.Class<HttpRequest>("HttpRequest")({
|
|
12
|
+
method: Schema.String,
|
|
13
|
+
url: Schema.String,
|
|
14
|
+
body: Schema.optionalKey(Schema.String),
|
|
15
|
+
headers: Schema.Record(Schema.String, Schema.String).pipe(
|
|
16
|
+
Schema.withConstructorDefault(Effect.succeed(emptyHeaders))
|
|
17
|
+
),
|
|
18
|
+
contentType: Schema.String.pipe(
|
|
19
|
+
Schema.withConstructorDefault(Effect.succeed("application/json"))
|
|
20
|
+
),
|
|
21
|
+
timeout: Schema.Duration
|
|
22
|
+
}) {}
|
|
23
|
+
|
|
24
|
+
export interface HttpClientShape {
|
|
25
|
+
readonly get: (
|
|
26
|
+
url: string,
|
|
27
|
+
headers: Readonly<Record<string, string>>,
|
|
28
|
+
timeout: Duration.Duration
|
|
29
|
+
) => Effect.Effect<string, LlmError>
|
|
30
|
+
readonly postJson: (
|
|
31
|
+
url: string,
|
|
32
|
+
body: string,
|
|
33
|
+
headers: Readonly<Record<string, string>>,
|
|
34
|
+
timeout: Duration.Duration
|
|
35
|
+
) => Effect.Effect<string, LlmError>
|
|
36
|
+
readonly send: (
|
|
37
|
+
method: string,
|
|
38
|
+
url: string,
|
|
39
|
+
body: string | undefined,
|
|
40
|
+
headers: Readonly<Record<string, string>>,
|
|
41
|
+
contentType: string,
|
|
42
|
+
timeout: Duration.Duration
|
|
43
|
+
) => Effect.Effect<string, LlmError>
|
|
44
|
+
readonly postJsonStream: (
|
|
45
|
+
url: string,
|
|
46
|
+
body: string,
|
|
47
|
+
headers: Readonly<Record<string, string>>,
|
|
48
|
+
timeout: Duration.Duration
|
|
49
|
+
) => Stream.Stream<string, LlmError>
|
|
50
|
+
readonly postJsonStreamSSE: (
|
|
51
|
+
url: string,
|
|
52
|
+
body: string,
|
|
53
|
+
headers: Readonly<Record<string, string>>,
|
|
54
|
+
timeout: Duration.Duration
|
|
55
|
+
) => Stream.Stream<string, LlmError>
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export class HttpClient extends Context.Service<HttpClient, HttpClientShape>()(
|
|
59
|
+
"@llm4ts/core/HttpClient"
|
|
60
|
+
) {}
|
|
61
|
+
|
|
62
|
+
export interface HttpClientPrimitives {
|
|
63
|
+
readonly postJson: HttpClientShape["postJson"]
|
|
64
|
+
readonly get?: HttpClientShape["get"]
|
|
65
|
+
readonly send?: HttpClientShape["send"]
|
|
66
|
+
readonly postJsonStream?: HttpClientShape["postJsonStream"]
|
|
67
|
+
readonly postJsonStreamSSE?: HttpClientShape["postJsonStreamSSE"]
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export const makeHttpClient = (primitives: HttpClientPrimitives): HttpClientShape => {
|
|
71
|
+
const get: HttpClientShape["get"] =
|
|
72
|
+
primitives.get ??
|
|
73
|
+
((_url, _headers, _timeout) =>
|
|
74
|
+
Effect.fail(
|
|
75
|
+
InvalidRequestError.make({
|
|
76
|
+
message: "GET is not supported by this HttpClient implementation"
|
|
77
|
+
})
|
|
78
|
+
))
|
|
79
|
+
|
|
80
|
+
const send: HttpClientShape["send"] =
|
|
81
|
+
primitives.send ??
|
|
82
|
+
((_method, _url, _body, _headers, _contentType, _timeout) =>
|
|
83
|
+
Effect.fail(
|
|
84
|
+
InvalidRequestError.make({
|
|
85
|
+
message: "send is not supported by this HttpClient implementation"
|
|
86
|
+
})
|
|
87
|
+
))
|
|
88
|
+
|
|
89
|
+
const postJsonStream: HttpClientShape["postJsonStream"] =
|
|
90
|
+
primitives.postJsonStream ??
|
|
91
|
+
((url, body, headers, timeout) =>
|
|
92
|
+
Stream.flatMap(Stream.fromEffect(primitives.postJson(url, body, headers, timeout)), (raw) =>
|
|
93
|
+
Stream.fromIterable(raw.split(/\r?\n/))
|
|
94
|
+
))
|
|
95
|
+
|
|
96
|
+
const postJsonStreamSSE: HttpClientShape["postJsonStreamSSE"] =
|
|
97
|
+
primitives.postJsonStreamSSE ??
|
|
98
|
+
((url, body, headers, timeout) =>
|
|
99
|
+
postJsonStream(url, body, headers, timeout).pipe(
|
|
100
|
+
Stream.filter((line) => line.startsWith("data: ")),
|
|
101
|
+
Stream.map((line) => line.slice("data: ".length).trim()),
|
|
102
|
+
Stream.filter((payload) => payload.length > 0 && payload !== "[DONE]")
|
|
103
|
+
))
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
get,
|
|
107
|
+
postJson: primitives.postJson,
|
|
108
|
+
send,
|
|
109
|
+
postJsonStream,
|
|
110
|
+
postJsonStreamSSE
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export interface RecordingHttpClient {
|
|
115
|
+
readonly client: HttpClientShape
|
|
116
|
+
readonly recorded: Effect.Effect<ReadonlyArray<HttpRequest>>
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export const makeRecordingHttpClient = Effect.fn("@llm4ts/core/HttpClient.makeRecording")(
|
|
120
|
+
function* (
|
|
121
|
+
handler: (request: HttpRequest) => Effect.Effect<string, LlmError>,
|
|
122
|
+
streamHandler?: (request: HttpRequest) => Stream.Stream<string, LlmError>
|
|
123
|
+
): Effect.fn.Return<RecordingHttpClient> {
|
|
124
|
+
const requests = yield* Ref.make<ReadonlyArray<HttpRequest>>([])
|
|
125
|
+
const record = (request: HttpRequest): Effect.Effect<void> =>
|
|
126
|
+
Ref.update(requests, (current) => [...current, request])
|
|
127
|
+
|
|
128
|
+
const postJson: HttpClientShape["postJson"] = (url, body, headers, timeout) => {
|
|
129
|
+
const request = HttpRequest.make({
|
|
130
|
+
method: "POST",
|
|
131
|
+
url,
|
|
132
|
+
body,
|
|
133
|
+
headers,
|
|
134
|
+
contentType: "application/json",
|
|
135
|
+
timeout
|
|
136
|
+
})
|
|
137
|
+
return record(request).pipe(Effect.andThen(handler(request)))
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const client = makeHttpClient({
|
|
141
|
+
postJson,
|
|
142
|
+
get: (url, headers, timeout) => {
|
|
143
|
+
const request = HttpRequest.make({
|
|
144
|
+
method: "GET",
|
|
145
|
+
url,
|
|
146
|
+
headers,
|
|
147
|
+
timeout
|
|
148
|
+
})
|
|
149
|
+
return record(request).pipe(Effect.andThen(handler(request)))
|
|
150
|
+
},
|
|
151
|
+
send: (method, url, body, headers, contentType, timeout) => {
|
|
152
|
+
const request = HttpRequest.make({
|
|
153
|
+
method,
|
|
154
|
+
url,
|
|
155
|
+
...(body === undefined ? {} : { body }),
|
|
156
|
+
headers,
|
|
157
|
+
contentType,
|
|
158
|
+
timeout
|
|
159
|
+
})
|
|
160
|
+
return record(request).pipe(Effect.andThen(handler(request)))
|
|
161
|
+
},
|
|
162
|
+
...(streamHandler === undefined
|
|
163
|
+
? {}
|
|
164
|
+
: {
|
|
165
|
+
postJsonStream: (url, body, headers, timeout) => {
|
|
166
|
+
const request = HttpRequest.make({
|
|
167
|
+
method: "POST",
|
|
168
|
+
url,
|
|
169
|
+
body,
|
|
170
|
+
headers,
|
|
171
|
+
contentType: "application/json",
|
|
172
|
+
timeout
|
|
173
|
+
})
|
|
174
|
+
return Stream.concat(
|
|
175
|
+
Stream.drain(Stream.fromEffect(record(request))),
|
|
176
|
+
Stream.suspend(() => streamHandler(request))
|
|
177
|
+
)
|
|
178
|
+
}
|
|
179
|
+
})
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
return {
|
|
183
|
+
client,
|
|
184
|
+
recorded: Ref.get(requests)
|
|
185
|
+
}
|
|
186
|
+
}
|
|
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))
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as Context from "effect/Context"
|
|
2
|
+
import type * as Effect from "effect/Effect"
|
|
3
|
+
import type * as Stream from "effect/Stream"
|
|
4
|
+
import type * as Schema from "effect/Schema"
|
|
5
|
+
import type { LlmError } from "./Errors.ts"
|
|
6
|
+
import type {
|
|
7
|
+
JsonSchema,
|
|
8
|
+
LlmChunk,
|
|
9
|
+
Message,
|
|
10
|
+
TokenUsage,
|
|
11
|
+
ToolCallResponse,
|
|
12
|
+
ToolDefinition
|
|
13
|
+
} from "./Models.ts"
|
|
14
|
+
|
|
15
|
+
export type StructuredResult<A> = readonly [
|
|
16
|
+
value: A,
|
|
17
|
+
usage: TokenUsage | undefined,
|
|
18
|
+
model: string | undefined
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
export interface LlmServiceShape {
|
|
22
|
+
readonly executeStream: (prompt: string) => Stream.Stream<LlmChunk, LlmError>
|
|
23
|
+
readonly executeStreamWithHistory: (
|
|
24
|
+
messages: ReadonlyArray<Message>
|
|
25
|
+
) => Stream.Stream<LlmChunk, LlmError>
|
|
26
|
+
readonly executeWithTools: (
|
|
27
|
+
prompt: string,
|
|
28
|
+
tools: ReadonlyArray<ToolDefinition>
|
|
29
|
+
) => Effect.Effect<ToolCallResponse, LlmError>
|
|
30
|
+
readonly executeStructured: <A, E, RD, RE>(
|
|
31
|
+
prompt: string,
|
|
32
|
+
schema: Schema.ConstraintCodec<A, E, RD, RE>,
|
|
33
|
+
jsonSchema: JsonSchema
|
|
34
|
+
) => Effect.Effect<A, LlmError, RD>
|
|
35
|
+
readonly executeStructuredWithUsage: <A, E, RD, RE>(
|
|
36
|
+
prompt: string,
|
|
37
|
+
schema: Schema.ConstraintCodec<A, E, RD, RE>,
|
|
38
|
+
jsonSchema: JsonSchema
|
|
39
|
+
) => Effect.Effect<StructuredResult<A>, LlmError, RD>
|
|
40
|
+
readonly isAvailable: Effect.Effect<boolean>
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export class LlmService extends Context.Service<LlmService, LlmServiceShape>()(
|
|
44
|
+
"@llm4ts/core/LlmService"
|
|
45
|
+
) {}
|
package/src/Models.ts
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import * as Duration from "effect/Duration"
|
|
2
|
+
import * as Effect from "effect/Effect"
|
|
3
|
+
import * as Schema from "effect/Schema"
|
|
4
|
+
|
|
5
|
+
export const LlmProvider = Schema.Literals([
|
|
6
|
+
"GeminiCli",
|
|
7
|
+
"GeminiApi",
|
|
8
|
+
"OpenAI",
|
|
9
|
+
"Anthropic",
|
|
10
|
+
"LmStudio",
|
|
11
|
+
"Ollama",
|
|
12
|
+
"OpenCode",
|
|
13
|
+
"Mock"
|
|
14
|
+
])
|
|
15
|
+
export type LlmProvider = typeof LlmProvider.Type
|
|
16
|
+
|
|
17
|
+
export class ConnectorId extends Schema.Class<ConnectorId>("ConnectorId")({
|
|
18
|
+
value: Schema.String
|
|
19
|
+
}) {}
|
|
20
|
+
|
|
21
|
+
export const ConnectorIds = Object.freeze({
|
|
22
|
+
OpenAI: new ConnectorId({ value: "openai" }),
|
|
23
|
+
Anthropic: new ConnectorId({ value: "anthropic" }),
|
|
24
|
+
GeminiApi: new ConnectorId({ value: "gemini-api" }),
|
|
25
|
+
LmStudio: new ConnectorId({ value: "lm-studio" }),
|
|
26
|
+
Ollama: new ConnectorId({ value: "ollama" }),
|
|
27
|
+
ClaudeCli: new ConnectorId({ value: "claude-cli" }),
|
|
28
|
+
GeminiCli: new ConnectorId({ value: "gemini-cli" }),
|
|
29
|
+
OpenCode: new ConnectorId({ value: "opencode" }),
|
|
30
|
+
Codex: new ConnectorId({ value: "codex" }),
|
|
31
|
+
Copilot: new ConnectorId({ value: "copilot" }),
|
|
32
|
+
Pi: new ConnectorId({ value: "pi" }),
|
|
33
|
+
AntigravityCli: new ConnectorId({ value: "antigravity-cli" }),
|
|
34
|
+
Grok: new ConnectorId({ value: "grok" }),
|
|
35
|
+
Cursor: new ConnectorId({ value: "cursor" }),
|
|
36
|
+
Mock: new ConnectorId({ value: "mock" })
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
export const apiConnectorIds: ReadonlyArray<ConnectorId> = Object.freeze([
|
|
40
|
+
ConnectorIds.OpenAI,
|
|
41
|
+
ConnectorIds.Anthropic,
|
|
42
|
+
ConnectorIds.GeminiApi,
|
|
43
|
+
ConnectorIds.LmStudio,
|
|
44
|
+
ConnectorIds.Ollama
|
|
45
|
+
])
|
|
46
|
+
|
|
47
|
+
export const cliConnectorIds: ReadonlyArray<ConnectorId> = Object.freeze([
|
|
48
|
+
ConnectorIds.ClaudeCli,
|
|
49
|
+
ConnectorIds.GeminiCli,
|
|
50
|
+
ConnectorIds.OpenCode,
|
|
51
|
+
ConnectorIds.Codex,
|
|
52
|
+
ConnectorIds.Copilot,
|
|
53
|
+
ConnectorIds.Pi,
|
|
54
|
+
ConnectorIds.AntigravityCli,
|
|
55
|
+
ConnectorIds.Grok,
|
|
56
|
+
ConnectorIds.Cursor
|
|
57
|
+
])
|
|
58
|
+
|
|
59
|
+
export const connectorIds: ReadonlyArray<ConnectorId> = Object.freeze([
|
|
60
|
+
...apiConnectorIds,
|
|
61
|
+
...cliConnectorIds,
|
|
62
|
+
ConnectorIds.Mock
|
|
63
|
+
])
|
|
64
|
+
|
|
65
|
+
export const defaultBaseUrl = (provider: LlmProvider): string | undefined => {
|
|
66
|
+
switch (provider) {
|
|
67
|
+
case "GeminiCli":
|
|
68
|
+
case "Mock":
|
|
69
|
+
return undefined
|
|
70
|
+
case "GeminiApi":
|
|
71
|
+
return "https://generativelanguage.googleapis.com"
|
|
72
|
+
case "OpenAI":
|
|
73
|
+
return "https://api.openai.com/v1"
|
|
74
|
+
case "Anthropic":
|
|
75
|
+
return "https://api.anthropic.com"
|
|
76
|
+
case "LmStudio":
|
|
77
|
+
return "http://localhost:1234/v1"
|
|
78
|
+
case "Ollama":
|
|
79
|
+
return "http://localhost:11434"
|
|
80
|
+
case "OpenCode":
|
|
81
|
+
return "http://localhost:4096"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const connectorProviderTable: Readonly<Record<string, LlmProvider>> = {
|
|
86
|
+
openai: "OpenAI",
|
|
87
|
+
anthropic: "Anthropic",
|
|
88
|
+
"gemini-api": "GeminiApi",
|
|
89
|
+
"lm-studio": "LmStudio",
|
|
90
|
+
ollama: "Ollama",
|
|
91
|
+
opencode: "OpenCode",
|
|
92
|
+
"gemini-cli": "GeminiCli",
|
|
93
|
+
mock: "Mock"
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export const connectorProvider = (id: ConnectorId): LlmProvider | undefined =>
|
|
97
|
+
connectorProviderTable[id.value]
|
|
98
|
+
|
|
99
|
+
export const connectorDefaultBaseUrl = (id: ConnectorId): string | undefined => {
|
|
100
|
+
const provider = connectorProvider(id)
|
|
101
|
+
return provider === undefined ? undefined : defaultBaseUrl(provider)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export const providerConnectorId = (provider: LlmProvider): ConnectorId => {
|
|
105
|
+
switch (provider) {
|
|
106
|
+
case "GeminiCli":
|
|
107
|
+
return ConnectorIds.GeminiCli
|
|
108
|
+
case "GeminiApi":
|
|
109
|
+
return ConnectorIds.GeminiApi
|
|
110
|
+
case "OpenAI":
|
|
111
|
+
return ConnectorIds.OpenAI
|
|
112
|
+
case "Anthropic":
|
|
113
|
+
return ConnectorIds.Anthropic
|
|
114
|
+
case "LmStudio":
|
|
115
|
+
return ConnectorIds.LmStudio
|
|
116
|
+
case "Ollama":
|
|
117
|
+
return ConnectorIds.Ollama
|
|
118
|
+
case "OpenCode":
|
|
119
|
+
return ConnectorIds.OpenCode
|
|
120
|
+
case "Mock":
|
|
121
|
+
return ConnectorIds.Mock
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export const ConnectorKind = Schema.Literals(["Api", "Cli"])
|
|
126
|
+
export type ConnectorKind = typeof ConnectorKind.Type
|
|
127
|
+
|
|
128
|
+
export const MessageRole = Schema.Literals(["System", "User", "Assistant", "Tool"])
|
|
129
|
+
export type MessageRole = typeof MessageRole.Type
|
|
130
|
+
|
|
131
|
+
export class Message extends Schema.Class<Message>("Message")({
|
|
132
|
+
role: MessageRole,
|
|
133
|
+
content: Schema.String
|
|
134
|
+
}) {}
|
|
135
|
+
|
|
136
|
+
export class TokenUsage extends Schema.Class<TokenUsage>("TokenUsage")({
|
|
137
|
+
prompt: Schema.Int,
|
|
138
|
+
completion: Schema.Int,
|
|
139
|
+
total: Schema.Int,
|
|
140
|
+
cached: Schema.optionalKey(Schema.Int)
|
|
141
|
+
}) {}
|
|
142
|
+
|
|
143
|
+
const emptyMetadata: Readonly<Record<string, string>> = Object.freeze({})
|
|
144
|
+
|
|
145
|
+
export class LlmResponse extends Schema.Class<LlmResponse>("LlmResponse")({
|
|
146
|
+
content: Schema.String,
|
|
147
|
+
usage: Schema.optionalKey(TokenUsage),
|
|
148
|
+
metadata: Schema.Record(Schema.String, Schema.String).pipe(
|
|
149
|
+
Schema.withConstructorDefault(Effect.succeed(emptyMetadata))
|
|
150
|
+
)
|
|
151
|
+
}) {}
|
|
152
|
+
|
|
153
|
+
export class LlmChunk extends Schema.Class<LlmChunk>("LlmChunk")({
|
|
154
|
+
delta: Schema.String,
|
|
155
|
+
finishReason: Schema.optionalKey(Schema.String),
|
|
156
|
+
usage: Schema.optionalKey(TokenUsage),
|
|
157
|
+
metadata: Schema.Record(Schema.String, Schema.String).pipe(
|
|
158
|
+
Schema.withConstructorDefault(Effect.succeed(emptyMetadata))
|
|
159
|
+
)
|
|
160
|
+
}) {}
|
|
161
|
+
|
|
162
|
+
export class StreamProgress extends Schema.Class<StreamProgress>("StreamProgress")({
|
|
163
|
+
tokensProcessed: Schema.Int,
|
|
164
|
+
tokensPerSecond: Schema.Number,
|
|
165
|
+
elapsedMs: Schema.Int,
|
|
166
|
+
estimatedRemainingMs: Schema.optionalKey(Schema.Int)
|
|
167
|
+
}) {}
|
|
168
|
+
|
|
169
|
+
export class LlmConfig extends Schema.Class<LlmConfig>("LlmConfig")({
|
|
170
|
+
provider: LlmProvider,
|
|
171
|
+
model: Schema.String,
|
|
172
|
+
baseUrl: Schema.optionalKey(Schema.String),
|
|
173
|
+
apiKey: Schema.optionalKey(
|
|
174
|
+
Schema.Redacted(Schema.String, {
|
|
175
|
+
disallowJsonEncode: true
|
|
176
|
+
})
|
|
177
|
+
),
|
|
178
|
+
timeout: Schema.Duration.pipe(
|
|
179
|
+
Schema.withConstructorDefault(Effect.succeed(Duration.seconds(300)))
|
|
180
|
+
),
|
|
181
|
+
maxRetries: Schema.Int.pipe(Schema.withConstructorDefault(Effect.succeed(3))),
|
|
182
|
+
requestsPerMinute: Schema.Int.pipe(Schema.withConstructorDefault(Effect.succeed(60))),
|
|
183
|
+
burstSize: Schema.Int.pipe(Schema.withConstructorDefault(Effect.succeed(10))),
|
|
184
|
+
acquireTimeout: Schema.Duration.pipe(
|
|
185
|
+
Schema.withConstructorDefault(Effect.succeed(Duration.seconds(30)))
|
|
186
|
+
),
|
|
187
|
+
temperature: Schema.optionalKey(Schema.Number),
|
|
188
|
+
maxTokens: Schema.optionalKey(Schema.Int)
|
|
189
|
+
}) {}
|
|
190
|
+
|
|
191
|
+
export const withConfigDefaults = (config: LlmConfig): LlmConfig => {
|
|
192
|
+
if (config.baseUrl !== undefined) {
|
|
193
|
+
return config
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const baseUrl = defaultBaseUrl(config.provider)
|
|
197
|
+
return baseUrl === undefined ? config : new LlmConfig({ ...config, baseUrl })
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export class ToolCall extends Schema.Class<ToolCall>("ToolCall")({
|
|
201
|
+
id: Schema.String,
|
|
202
|
+
name: Schema.String,
|
|
203
|
+
arguments: Schema.String
|
|
204
|
+
}) {}
|
|
205
|
+
|
|
206
|
+
const emptyToolCalls: ReadonlyArray<ToolCall> = Object.freeze([])
|
|
207
|
+
|
|
208
|
+
export class ToolCallResponse extends Schema.Class<ToolCallResponse>("ToolCallResponse")({
|
|
209
|
+
content: Schema.optionalKey(Schema.String),
|
|
210
|
+
toolCalls: Schema.Array(ToolCall).pipe(
|
|
211
|
+
Schema.withConstructorDefault(Effect.succeed(emptyToolCalls))
|
|
212
|
+
),
|
|
213
|
+
finishReason: Schema.String
|
|
214
|
+
}) {}
|
|
215
|
+
|
|
216
|
+
export const JsonSchema = Schema.Record(Schema.String, Schema.Json)
|
|
217
|
+
export type JsonSchema = typeof JsonSchema.Type
|
|
218
|
+
|
|
219
|
+
export class ToolDefinition extends Schema.Class<ToolDefinition>("ToolDefinition")({
|
|
220
|
+
name: Schema.String,
|
|
221
|
+
description: Schema.String,
|
|
222
|
+
parameters: JsonSchema
|
|
223
|
+
}) {}
|
|
224
|
+
|
|
225
|
+
export const Availability = Schema.Literals(["Healthy", "Degraded", "Unhealthy", "Unknown"])
|
|
226
|
+
export type Availability = typeof Availability.Type
|
|
227
|
+
|
|
228
|
+
export const AuthStatus = Schema.Literals(["Valid", "Missing", "Invalid", "Unknown"])
|
|
229
|
+
export type AuthStatus = typeof AuthStatus.Type
|
|
230
|
+
|
|
231
|
+
export class HealthStatus extends Schema.Class<HealthStatus>("HealthStatus")({
|
|
232
|
+
availability: Availability,
|
|
233
|
+
authStatus: AuthStatus,
|
|
234
|
+
latency: Schema.optionalKey(Schema.Duration)
|
|
235
|
+
}) {}
|
|
236
|
+
|
|
237
|
+
export const InteractionSupport = Schema.Literals(["InteractiveStdin", "ContinuationOnly"])
|
|
238
|
+
export type InteractionSupport = typeof InteractionSupport.Type
|
|
239
|
+
|
|
240
|
+
export class ConnectorCapabilities extends Schema.Class<ConnectorCapabilities>(
|
|
241
|
+
"ConnectorCapabilities"
|
|
242
|
+
)({
|
|
243
|
+
streaming: Schema.Boolean.pipe(Schema.withConstructorDefault(Effect.succeed(true))),
|
|
244
|
+
resumableSessions: Schema.Boolean.pipe(Schema.withConstructorDefault(Effect.succeed(false))),
|
|
245
|
+
interactiveSessions: Schema.Boolean.pipe(Schema.withConstructorDefault(Effect.succeed(false))),
|
|
246
|
+
askUser: Schema.Boolean.pipe(Schema.withConstructorDefault(Effect.succeed(false))),
|
|
247
|
+
approval: Schema.Boolean.pipe(Schema.withConstructorDefault(Effect.succeed(false))),
|
|
248
|
+
structuredOutput: Schema.Boolean.pipe(Schema.withConstructorDefault(Effect.succeed(true))),
|
|
249
|
+
usageReporting: Schema.Boolean.pipe(Schema.withConstructorDefault(Effect.succeed(true)))
|
|
250
|
+
}) {}
|