@effect-uai/anthropic 0.1.0 → 0.3.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/dist/Anthropic.d.mts +94 -0
- package/dist/Anthropic.d.mts.map +1 -0
- package/dist/Anthropic.mjs +226 -0
- package/dist/Anthropic.mjs.map +1 -0
- package/dist/codec.d.mts +142 -0
- package/dist/codec.d.mts.map +1 -0
- package/dist/codec.mjs +354 -0
- package/dist/codec.mjs.map +1 -0
- package/dist/index.d.mts +5 -438
- package/dist/index.mjs +5 -649
- package/dist/models.d.mts +25 -0
- package/dist/models.d.mts.map +1 -0
- package/dist/models.mjs +1 -0
- package/dist/streamEvents.d.mts +196 -0
- package/dist/streamEvents.d.mts.map +1 -0
- package/dist/streamEvents.mjs +152 -0
- package/dist/streamEvents.mjs.map +1 -0
- package/package.json +16 -12
- package/src/Anthropic.ts +49 -54
- package/src/codec.ts +104 -109
- package/src/index.ts +2 -2
- package/src/streamEvents.ts +27 -25
- package/dist/index.d.mts.map +0 -1
- package/dist/index.mjs.map +0 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { ThinkingConfig } from "./codec.mjs";
|
|
2
|
+
import { AnthropicModel } from "./models.mjs";
|
|
3
|
+
import { ProviderEvent } from "./streamEvents.mjs";
|
|
4
|
+
import { Context, Effect, Layer, Redacted, Stream } from "effect";
|
|
5
|
+
import { HttpClient } from "effect/unstable/http";
|
|
6
|
+
import * as AiError from "@effect-uai/core/AiError";
|
|
7
|
+
import { CommonRequest, LanguageModel } from "@effect-uai/core/LanguageModel";
|
|
8
|
+
import { TurnEvent } from "@effect-uai/core/Turn";
|
|
9
|
+
|
|
10
|
+
//#region src/Anthropic.d.ts
|
|
11
|
+
declare namespace Anthropic_d_exports {
|
|
12
|
+
export { Anthropic, AnthropicRequest, AnthropicService, Config, layer, make, toCanonical };
|
|
13
|
+
}
|
|
14
|
+
type AnthropicRequest = Omit<CommonRequest, "model"> & {
|
|
15
|
+
/**
|
|
16
|
+
* Narrows `CommonRequest.model` (`string`) to the typed `AnthropicModel`
|
|
17
|
+
* literal union for autocomplete.
|
|
18
|
+
*/
|
|
19
|
+
readonly model: AnthropicModel;
|
|
20
|
+
/**
|
|
21
|
+
* Top-K nucleus sampling parameter. Anthropic-specific; not exposed on the
|
|
22
|
+
* common surface.
|
|
23
|
+
*/
|
|
24
|
+
readonly topK?: number; /** Stop sequences that abort generation when matched. */
|
|
25
|
+
readonly stopSequences?: ReadonlyArray<string>;
|
|
26
|
+
/**
|
|
27
|
+
* Extended thinking configuration. `0` budget is equivalent to disabled.
|
|
28
|
+
* Only the `claude-sonnet-4-x`, `claude-haiku-4-x`, and pre-Opus-4.7
|
|
29
|
+
* model lines support extended thinking.
|
|
30
|
+
*/
|
|
31
|
+
readonly thinking?: ThinkingConfig;
|
|
32
|
+
/**
|
|
33
|
+
* `metadata.user_id` on the wire. End-user tracking identifier.
|
|
34
|
+
*/
|
|
35
|
+
readonly user?: string;
|
|
36
|
+
};
|
|
37
|
+
type AnthropicService = {
|
|
38
|
+
/**
|
|
39
|
+
* Stream the provider's native event vocabulary (post-SSE-decode).
|
|
40
|
+
* Use this when you need full vendor fidelity (e.g. `signature_delta` for
|
|
41
|
+
* encrypted reasoning state). For provider-portable code, use `streamTurn`.
|
|
42
|
+
*/
|
|
43
|
+
readonly streamNative: (request: AnthropicRequest) => Stream.Stream<ProviderEvent, AiError.AiError>;
|
|
44
|
+
/**
|
|
45
|
+
* Stream canonical `TurnEvent`s. Implemented as
|
|
46
|
+
* `streamNative |> toCanonical`.
|
|
47
|
+
*/
|
|
48
|
+
readonly streamTurn: (request: AnthropicRequest) => Stream.Stream<TurnEvent, AiError.AiError>;
|
|
49
|
+
/**
|
|
50
|
+
* Project a stream of native `ProviderEvent`s into canonical `TurnEvent`s.
|
|
51
|
+
* Stateful (threads an `Accumulator` for tool-call lookup and
|
|
52
|
+
* accumulator-to-Turn assembly).
|
|
53
|
+
*/
|
|
54
|
+
readonly toCanonical: <E, R>(s: Stream.Stream<ProviderEvent, E, R>) => Stream.Stream<TurnEvent, E, R>;
|
|
55
|
+
};
|
|
56
|
+
declare const Anthropic_base: Context.ServiceClass<Anthropic, "@betalyra/effect-uai/providers/anthropic/Anthropic", AnthropicService>;
|
|
57
|
+
/**
|
|
58
|
+
* Provider-typed service tag. Yield this when you want Anthropic-specific
|
|
59
|
+
* options (`topK`, `stopSequences`, `thinking`); yield the generic
|
|
60
|
+
* `LanguageModel` tag for provider-portable code. Both are registered by
|
|
61
|
+
* `layer`.
|
|
62
|
+
*/
|
|
63
|
+
declare class Anthropic extends Anthropic_base {}
|
|
64
|
+
type Config = {
|
|
65
|
+
readonly apiKey: Redacted.Redacted;
|
|
66
|
+
readonly baseUrl?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Default `max_tokens` for requests that don't override via
|
|
69
|
+
* `request.maxOutputTokens`. Anthropic requires this field; we default to
|
|
70
|
+
* 4096 if neither is set.
|
|
71
|
+
*/
|
|
72
|
+
readonly defaultMaxTokens?: number;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Project a stream of native `ProviderEvent`s into canonical `TurnEvent`s.
|
|
76
|
+
* Threads a fresh `Accumulator` per stream so tool-call lookup and
|
|
77
|
+
* `accumulatorToTurn` assembly work correctly across the run.
|
|
78
|
+
*/
|
|
79
|
+
declare const toCanonical: <E, R>(s: Stream.Stream<ProviderEvent, E, R>) => Stream.Stream<TurnEvent, E, R>;
|
|
80
|
+
/**
|
|
81
|
+
* Build an `AnthropicService` value. For Layer-based setup, prefer `layer`.
|
|
82
|
+
*/
|
|
83
|
+
declare const make: (cfg: Config) => Effect.Effect<AnthropicService, never, HttpClient.HttpClient>;
|
|
84
|
+
/**
|
|
85
|
+
* Layer that registers both the provider-specific `Anthropic` tag and the
|
|
86
|
+
* generic `LanguageModel` tag, sharing one underlying implementation.
|
|
87
|
+
*
|
|
88
|
+
* The generic tag accepts `CommonRequest`; the typed tag accepts the full
|
|
89
|
+
* `AnthropicRequest` surface.
|
|
90
|
+
*/
|
|
91
|
+
declare const layer: (cfg: Config) => Layer.Layer<Anthropic | LanguageModel, never, HttpClient.HttpClient>;
|
|
92
|
+
//#endregion
|
|
93
|
+
export { Anthropic, AnthropicRequest, AnthropicService, Config, layer, make, Anthropic_d_exports as t, toCanonical };
|
|
94
|
+
//# sourceMappingURL=Anthropic.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Anthropic.d.mts","names":[],"sources":["../src/Anthropic.ts"],"mappings":";;;;;;;;;;;;;KAmCY,gBAAA,GAAmB,IAAA,CAAK,aAAA;;;;;WAKzB,KAAA,EAAO,cAAA;;;;;WAKP,IAAA;WAEA,aAAA,GAAgB,aAAA;EAZC;;;;;EAAA,SAkBjB,QAAA,GAAW,cAAA;EAAA;;;EAAA,SAIX,IAAA;AAAA;AAAA,KAGC,gBAAA;EApBM;;;;;EAAA,SA0BP,YAAA,GACP,OAAA,EAAS,gBAAA,KACN,MAAA,CAAO,MAAA,CAAO,aAAA,EAAe,OAAA,CAAQ,OAAA;EAXjC;;;AAGX;EAHW,SAgBA,UAAA,GAAa,OAAA,EAAS,gBAAA,KAAqB,MAAA,CAAO,MAAA,CAAO,SAAA,EAAW,OAAA,CAAQ,OAAA;EAb3D;;;;;EAAA,SAmBjB,WAAA,SACP,CAAA,EAAG,MAAA,CAAO,MAAA,CAAO,aAAA,EAAe,CAAA,EAAG,CAAA,MAChC,MAAA,CAAO,MAAA,CAAO,SAAA,EAAW,CAAA,EAAG,CAAA;AAAA;AAAA,cAClC,cAAA;;;;;;;cAQY,SAAA,SAAkB,cAAA;AAAA,KAInB,MAAA;EAAA,SACD,MAAA,EAAQ,QAAA,CAAS,QAAA;EAAA,SACjB,OAAA;EA9BA;;;;;EAAA,SAoCA,gBAAA;AAAA;;;;;;cAqOE,WAAA,SACX,CAAA,EAAG,MAAA,CAAO,MAAA,CAAO,aAAA,EAAe,CAAA,EAAG,CAAA,MAClC,MAAA,CAAO,MAAA,CAAO,SAAA,EAAW,CAAA,EAAG,CAAA;;;;cAmBlB,IAAA,GAAQ,GAAA,EAAK,MAAA,KAAS,MAAA,CAAO,MAAA,CAAO,gBAAA,SAAyB,UAAA,CAAW,UAAA;;;;;;;;cAkBxE,KAAA,GACX,GAAA,EAAK,MAAA,KACJ,KAAA,CAAM,KAAA,CAAM,SAAA,GAAY,aAAA,SAAsB,UAAA,CAAW,UAAA"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { t as __exportAll } from "./chunk-CfYAbeIz.mjs";
|
|
2
|
+
import { accumulatorToTurn, buildRequestBody, emptyAccumulator } from "./codec.mjs";
|
|
3
|
+
import { KnownProviderEvent, applyEvent } from "./streamEvents.mjs";
|
|
4
|
+
import { Context, Effect, Layer, Match, Option, Redacted, Result, Schema, Stream, pipe } from "effect";
|
|
5
|
+
import { HttpClient, HttpClientRequest } from "effect/unstable/http";
|
|
6
|
+
import * as AiError from "@effect-uai/core/AiError";
|
|
7
|
+
import { LanguageModel } from "@effect-uai/core/LanguageModel";
|
|
8
|
+
import * as SSE from "@effect-uai/core/SSE";
|
|
9
|
+
//#region src/Anthropic.ts
|
|
10
|
+
var Anthropic_exports = /* @__PURE__ */ __exportAll({
|
|
11
|
+
Anthropic: () => Anthropic,
|
|
12
|
+
layer: () => layer,
|
|
13
|
+
make: () => make,
|
|
14
|
+
toCanonical: () => toCanonical
|
|
15
|
+
});
|
|
16
|
+
/**
|
|
17
|
+
* Provider-typed service tag. Yield this when you want Anthropic-specific
|
|
18
|
+
* options (`topK`, `stopSequences`, `thinking`); yield the generic
|
|
19
|
+
* `LanguageModel` tag for provider-portable code. Both are registered by
|
|
20
|
+
* `layer`.
|
|
21
|
+
*/
|
|
22
|
+
var Anthropic = class extends Context.Service()("@betalyra/effect-uai/providers/anthropic/Anthropic") {};
|
|
23
|
+
const ANTHROPIC_VERSION = "2023-06-01";
|
|
24
|
+
const STRUCTURED_OUTPUTS_BETA = "structured-outputs-2025-11-13";
|
|
25
|
+
const FALLBACK_MAX_TOKENS = 4096;
|
|
26
|
+
const outputConfig = (request) => pipe(Option.fromUndefinedOr(request.structured), Option.map((format) => ({ format: {
|
|
27
|
+
type: "json_schema",
|
|
28
|
+
schema: format.schema["~standard"].jsonSchema.input({ target: "draft-2020-12" })
|
|
29
|
+
} })));
|
|
30
|
+
const resolvedMaxTokens = (cfg, request) => request.maxOutputTokens ?? cfg.defaultMaxTokens ?? FALLBACK_MAX_TOKENS;
|
|
31
|
+
const toolDescriptors = (request) => request.tools !== void 0 && request.tools.length > 0 ? Option.some(request.tools.map((t) => ({
|
|
32
|
+
name: t.name,
|
|
33
|
+
description: t.description,
|
|
34
|
+
input_schema: t.inputSchema
|
|
35
|
+
}))) : Option.none();
|
|
36
|
+
const toolChoiceWire = (request) => pipe(Option.fromUndefinedOr(request.toolChoice), Option.map((choice) => choice === "auto" ? { type: "auto" } : choice === "required" ? { type: "any" } : choice === "none" ? { type: "none" } : {
|
|
37
|
+
type: "tool",
|
|
38
|
+
name: choice.name
|
|
39
|
+
}));
|
|
40
|
+
const decodeKnown = Schema.decodeUnknownEffect(KnownProviderEvent);
|
|
41
|
+
const makeUnknown = (raw) => ({
|
|
42
|
+
type: "_unknown",
|
|
43
|
+
raw
|
|
44
|
+
});
|
|
45
|
+
/**
|
|
46
|
+
* Parse one SSE event's `data` payload into a typed `ProviderEvent`. Never
|
|
47
|
+
* fails: JSON-parse and schema-decode failures both produce a synthesized
|
|
48
|
+
* `_unknown` event so consumers of `streamNative` never silently miss a
|
|
49
|
+
* wire event we didn't model.
|
|
50
|
+
*/
|
|
51
|
+
const sseEventToProviderEvent = (ev) => Effect.try({
|
|
52
|
+
try: () => JSON.parse(ev.data),
|
|
53
|
+
catch: () => ev.data
|
|
54
|
+
}).pipe(Effect.flatMap((parsed) => decodeKnown(parsed).pipe(Effect.orElseSucceed(() => makeUnknown(parsed)))), Effect.orElseSucceed(() => makeUnknown(ev.data)));
|
|
55
|
+
const deltasFromEvent = (next, event) => Match.value(event).pipe(Match.discriminatorsExhaustive("type")({
|
|
56
|
+
content_block_start: (e) => e.content_block.type === "tool_use" ? [{
|
|
57
|
+
type: "tool_call_start",
|
|
58
|
+
call_id: e.content_block.id,
|
|
59
|
+
name: e.content_block.name
|
|
60
|
+
}] : [],
|
|
61
|
+
content_block_delta: (e) => Match.value(e.delta).pipe(Match.discriminatorsExhaustive("type")({
|
|
62
|
+
text_delta: (d) => [{
|
|
63
|
+
type: "text_delta",
|
|
64
|
+
text: d.text
|
|
65
|
+
}],
|
|
66
|
+
thinking_delta: (d) => [{
|
|
67
|
+
type: "reasoning_delta",
|
|
68
|
+
text: d.thinking,
|
|
69
|
+
kind: "trace"
|
|
70
|
+
}],
|
|
71
|
+
input_json_delta: (d) => {
|
|
72
|
+
const block = next.blocks[e.index];
|
|
73
|
+
if (block === void 0) return [];
|
|
74
|
+
const callId = Option.getOrElse(block.id, () => "");
|
|
75
|
+
return callId.length === 0 ? [] : [{
|
|
76
|
+
type: "tool_call_args_delta",
|
|
77
|
+
call_id: callId,
|
|
78
|
+
delta: d.partial_json
|
|
79
|
+
}];
|
|
80
|
+
},
|
|
81
|
+
signature_delta: () => []
|
|
82
|
+
})),
|
|
83
|
+
message_start: (e) => e.message.usage === void 0 ? [] : [{
|
|
84
|
+
type: "usage_update",
|
|
85
|
+
usage: next.usage
|
|
86
|
+
}],
|
|
87
|
+
message_delta: (e) => e.usage === void 0 ? [] : [{
|
|
88
|
+
type: "usage_update",
|
|
89
|
+
usage: next.usage
|
|
90
|
+
}],
|
|
91
|
+
message_stop: () => [{
|
|
92
|
+
type: "turn_complete",
|
|
93
|
+
turn: accumulatorToTurn(next)
|
|
94
|
+
}],
|
|
95
|
+
content_block_stop: () => [],
|
|
96
|
+
ping: () => [],
|
|
97
|
+
error: () => [],
|
|
98
|
+
_unknown: () => []
|
|
99
|
+
}));
|
|
100
|
+
const httpStatusError = (status, body) => {
|
|
101
|
+
const provider = "anthropic";
|
|
102
|
+
const raw = body;
|
|
103
|
+
if (status === 429) return new AiError.RateLimited({
|
|
104
|
+
provider,
|
|
105
|
+
raw
|
|
106
|
+
});
|
|
107
|
+
if (status === 408 || status === 504) return new AiError.Timeout({
|
|
108
|
+
provider,
|
|
109
|
+
raw
|
|
110
|
+
});
|
|
111
|
+
if (status === 401) return new AiError.AuthFailed({
|
|
112
|
+
provider,
|
|
113
|
+
subtype: "auth",
|
|
114
|
+
raw
|
|
115
|
+
});
|
|
116
|
+
if (status === 403) return new AiError.AuthFailed({
|
|
117
|
+
provider,
|
|
118
|
+
subtype: "permission",
|
|
119
|
+
raw
|
|
120
|
+
});
|
|
121
|
+
if (status === 402) return new AiError.AuthFailed({
|
|
122
|
+
provider,
|
|
123
|
+
subtype: "billing",
|
|
124
|
+
raw
|
|
125
|
+
});
|
|
126
|
+
if (status === 413) return new AiError.ContextLengthExceeded({
|
|
127
|
+
provider,
|
|
128
|
+
raw
|
|
129
|
+
});
|
|
130
|
+
if (status === 529) return new AiError.Unavailable({
|
|
131
|
+
provider,
|
|
132
|
+
status,
|
|
133
|
+
raw
|
|
134
|
+
});
|
|
135
|
+
if (status >= 500) return new AiError.Unavailable({
|
|
136
|
+
provider,
|
|
137
|
+
status,
|
|
138
|
+
raw
|
|
139
|
+
});
|
|
140
|
+
return new AiError.InvalidRequest({
|
|
141
|
+
provider,
|
|
142
|
+
raw
|
|
143
|
+
});
|
|
144
|
+
};
|
|
145
|
+
const buildNativeStream = (cfg) => {
|
|
146
|
+
const url = `${cfg.baseUrl ?? "https://api.anthropic.com"}/v1/messages`;
|
|
147
|
+
return (request) => Stream.unwrap(Effect.gen(function* () {
|
|
148
|
+
const structured = outputConfig(request);
|
|
149
|
+
const bodyResult = buildRequestBody({
|
|
150
|
+
model: request.model,
|
|
151
|
+
history: request.history,
|
|
152
|
+
maxTokens: resolvedMaxTokens(cfg, request),
|
|
153
|
+
temperature: Option.fromUndefinedOr(request.temperature),
|
|
154
|
+
topP: Option.fromUndefinedOr(request.topP),
|
|
155
|
+
topK: Option.fromUndefinedOr(request.topK),
|
|
156
|
+
stopSequences: Option.fromUndefinedOr(request.stopSequences),
|
|
157
|
+
thinking: Option.fromUndefinedOr(request.thinking),
|
|
158
|
+
tools: toolDescriptors(request),
|
|
159
|
+
toolChoice: toolChoiceWire(request),
|
|
160
|
+
userId: Option.fromUndefinedOr(request.user),
|
|
161
|
+
outputConfig: structured
|
|
162
|
+
});
|
|
163
|
+
const body = yield* Result.match(bodyResult, {
|
|
164
|
+
onFailure: (cause) => Effect.fail(new AiError.InvalidRequest({
|
|
165
|
+
provider: "anthropic",
|
|
166
|
+
param: "input.function_call.arguments",
|
|
167
|
+
raw: cause
|
|
168
|
+
})),
|
|
169
|
+
onSuccess: (b) => Effect.succeed(b)
|
|
170
|
+
});
|
|
171
|
+
const client = yield* HttpClient.HttpClient;
|
|
172
|
+
const baseRequest = HttpClientRequest.post(url).pipe(HttpClientRequest.setHeader("x-api-key", Redacted.value(cfg.apiKey)), HttpClientRequest.setHeader("anthropic-version", ANTHROPIC_VERSION), HttpClientRequest.bodyJsonUnsafe(body), HttpClientRequest.accept("text/event-stream"));
|
|
173
|
+
const httpRequest = Option.isSome(structured) ? baseRequest.pipe(HttpClientRequest.setHeader("anthropic-beta", STRUCTURED_OUTPUTS_BETA)) : baseRequest;
|
|
174
|
+
const response = yield* client.execute(httpRequest).pipe(Effect.mapError((cause) => new AiError.Unavailable({
|
|
175
|
+
provider: "anthropic",
|
|
176
|
+
raw: cause
|
|
177
|
+
})));
|
|
178
|
+
if (response.status >= 400) {
|
|
179
|
+
const text = yield* response.text.pipe(Effect.orElseSucceed(() => ""));
|
|
180
|
+
return Stream.fail(httpStatusError(response.status, text));
|
|
181
|
+
}
|
|
182
|
+
return response.stream.pipe(Stream.mapError((cause) => new AiError.Unavailable({
|
|
183
|
+
provider: "anthropic",
|
|
184
|
+
raw: cause
|
|
185
|
+
})), SSE.fromBytes, Stream.mapEffect(sseEventToProviderEvent), Stream.flatMap((event) => event.type === "error" ? Stream.fail(new AiError.Unavailable({
|
|
186
|
+
provider: "anthropic",
|
|
187
|
+
raw: event
|
|
188
|
+
})) : Stream.succeed(event)));
|
|
189
|
+
}));
|
|
190
|
+
};
|
|
191
|
+
/**
|
|
192
|
+
* Project a stream of native `ProviderEvent`s into canonical `TurnEvent`s.
|
|
193
|
+
* Threads a fresh `Accumulator` per stream so tool-call lookup and
|
|
194
|
+
* `accumulatorToTurn` assembly work correctly across the run.
|
|
195
|
+
*/
|
|
196
|
+
const toCanonical = (s) => s.pipe(Stream.mapAccum(() => emptyAccumulator, (acc, event) => {
|
|
197
|
+
const next = applyEvent(acc, event);
|
|
198
|
+
return [next, deltasFromEvent(next, event)];
|
|
199
|
+
}));
|
|
200
|
+
/**
|
|
201
|
+
* Build an `AnthropicService` value. For Layer-based setup, prefer `layer`.
|
|
202
|
+
*/
|
|
203
|
+
const make = (cfg) => Effect.map(HttpClient.HttpClient.asEffect(), (client) => {
|
|
204
|
+
const streamNative = (request) => buildNativeStream(cfg)(request).pipe(Stream.provideService(HttpClient.HttpClient, client));
|
|
205
|
+
return {
|
|
206
|
+
streamNative,
|
|
207
|
+
streamTurn: (request) => toCanonical(streamNative(request)),
|
|
208
|
+
toCanonical
|
|
209
|
+
};
|
|
210
|
+
});
|
|
211
|
+
/**
|
|
212
|
+
* Layer that registers both the provider-specific `Anthropic` tag and the
|
|
213
|
+
* generic `LanguageModel` tag, sharing one underlying implementation.
|
|
214
|
+
*
|
|
215
|
+
* The generic tag accepts `CommonRequest`; the typed tag accepts the full
|
|
216
|
+
* `AnthropicRequest` surface.
|
|
217
|
+
*/
|
|
218
|
+
const layer = (cfg) => {
|
|
219
|
+
const typed = Layer.effect(Anthropic, make(cfg));
|
|
220
|
+
const generic = Layer.effect(LanguageModel, Effect.map(make(cfg), (s) => ({ streamTurn: (request) => s.streamTurn(request) })));
|
|
221
|
+
return Layer.merge(typed, generic);
|
|
222
|
+
};
|
|
223
|
+
//#endregion
|
|
224
|
+
export { Anthropic, layer, make, Anthropic_exports as t, toCanonical };
|
|
225
|
+
|
|
226
|
+
//# sourceMappingURL=Anthropic.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Anthropic.mjs","names":[],"sources":["../src/Anthropic.ts"],"sourcesContent":["import {\n Context,\n Effect,\n Layer,\n Match,\n Option,\n Redacted,\n Result,\n Schema,\n Stream,\n pipe,\n} from \"effect\"\nimport { HttpClient, HttpClientRequest } from \"effect/unstable/http\"\nimport * as AiError from \"@effect-uai/core/AiError\"\nimport {\n type CommonRequest,\n LanguageModel,\n type LanguageModelService,\n} from \"@effect-uai/core/LanguageModel\"\nimport * as SSE from \"@effect-uai/core/SSE\"\nimport type { TurnEvent } from \"@effect-uai/core/Turn\"\nimport {\n type Accumulator,\n type ThinkingConfig,\n accumulatorToTurn,\n buildRequestBody,\n emptyAccumulator,\n} from \"./codec.js\"\nimport type { AnthropicModel } from \"./models.js\"\nimport { KnownProviderEvent, ProviderEvent, applyEvent } from \"./streamEvents.js\"\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type AnthropicRequest = Omit<CommonRequest, \"model\"> & {\n /**\n * Narrows `CommonRequest.model` (`string`) to the typed `AnthropicModel`\n * literal union for autocomplete.\n */\n readonly model: AnthropicModel\n /**\n * Top-K nucleus sampling parameter. Anthropic-specific; not exposed on the\n * common surface.\n */\n readonly topK?: number\n /** Stop sequences that abort generation when matched. */\n readonly stopSequences?: ReadonlyArray<string>\n /**\n * Extended thinking configuration. `0` budget is equivalent to disabled.\n * Only the `claude-sonnet-4-x`, `claude-haiku-4-x`, and pre-Opus-4.7\n * model lines support extended thinking.\n */\n readonly thinking?: ThinkingConfig\n /**\n * `metadata.user_id` on the wire. End-user tracking identifier.\n */\n readonly user?: string\n}\n\nexport type AnthropicService = {\n /**\n * Stream the provider's native event vocabulary (post-SSE-decode).\n * Use this when you need full vendor fidelity (e.g. `signature_delta` for\n * encrypted reasoning state). For provider-portable code, use `streamTurn`.\n */\n readonly streamNative: (\n request: AnthropicRequest,\n ) => Stream.Stream<ProviderEvent, AiError.AiError>\n /**\n * Stream canonical `TurnEvent`s. Implemented as\n * `streamNative |> toCanonical`.\n */\n readonly streamTurn: (request: AnthropicRequest) => Stream.Stream<TurnEvent, AiError.AiError>\n /**\n * Project a stream of native `ProviderEvent`s into canonical `TurnEvent`s.\n * Stateful (threads an `Accumulator` for tool-call lookup and\n * accumulator-to-Turn assembly).\n */\n readonly toCanonical: <E, R>(\n s: Stream.Stream<ProviderEvent, E, R>,\n ) => Stream.Stream<TurnEvent, E, R>\n}\n\n/**\n * Provider-typed service tag. Yield this when you want Anthropic-specific\n * options (`topK`, `stopSequences`, `thinking`); yield the generic\n * `LanguageModel` tag for provider-portable code. Both are registered by\n * `layer`.\n */\nexport class Anthropic extends Context.Service<Anthropic, AnthropicService>()(\n \"@betalyra/effect-uai/providers/anthropic/Anthropic\",\n) {}\n\nexport type Config = {\n readonly apiKey: Redacted.Redacted\n readonly baseUrl?: string\n /**\n * Default `max_tokens` for requests that don't override via\n * `request.maxOutputTokens`. Anthropic requires this field; we default to\n * 4096 if neither is set.\n */\n readonly defaultMaxTokens?: number\n}\n\nconst ANTHROPIC_VERSION = \"2023-06-01\"\nconst STRUCTURED_OUTPUTS_BETA = \"structured-outputs-2025-11-13\"\nconst FALLBACK_MAX_TOKENS = 4096\n\nconst outputConfig = (request: AnthropicRequest): Option.Option<Record<string, unknown>> =>\n pipe(\n Option.fromUndefinedOr(request.structured),\n Option.map((format) => ({\n format: {\n type: \"json_schema\",\n schema: format.schema[\"~standard\"].jsonSchema.input({ target: \"draft-2020-12\" }),\n },\n })),\n )\n\nconst resolvedMaxTokens = (cfg: Config, request: AnthropicRequest): number =>\n request.maxOutputTokens ?? cfg.defaultMaxTokens ?? FALLBACK_MAX_TOKENS\n\nconst toolDescriptors = (\n request: AnthropicRequest,\n): Option.Option<ReadonlyArray<Record<string, unknown>>> =>\n request.tools !== undefined && request.tools.length > 0\n ? Option.some(\n request.tools.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema: t.inputSchema,\n })),\n )\n : Option.none()\n\nconst toolChoiceWire = (request: AnthropicRequest): Option.Option<Record<string, unknown>> =>\n pipe(\n Option.fromUndefinedOr(request.toolChoice),\n Option.map((choice) =>\n choice === \"auto\"\n ? { type: \"auto\" }\n : choice === \"required\"\n ? { type: \"any\" }\n : choice === \"none\"\n ? { type: \"none\" }\n : { type: \"tool\", name: choice.name },\n ),\n )\n\n// ---------------------------------------------------------------------------\n// SSE event → ProviderEvent\n// ---------------------------------------------------------------------------\n\nconst decodeKnown = Schema.decodeUnknownEffect(KnownProviderEvent)\n\nconst makeUnknown = (raw: unknown): ProviderEvent => ({ type: \"_unknown\", raw })\n\n/**\n * Parse one SSE event's `data` payload into a typed `ProviderEvent`. Never\n * fails: JSON-parse and schema-decode failures both produce a synthesized\n * `_unknown` event so consumers of `streamNative` never silently miss a\n * wire event we didn't model.\n */\nconst sseEventToProviderEvent = (ev: SSE.Event): Effect.Effect<ProviderEvent> =>\n Effect.try({\n try: () => JSON.parse(ev.data) as unknown,\n catch: () => ev.data,\n }).pipe(\n Effect.flatMap((parsed) =>\n decodeKnown(parsed).pipe(Effect.orElseSucceed(() => makeUnknown(parsed))),\n ),\n Effect.orElseSucceed(() => makeUnknown(ev.data)),\n )\n\n// ---------------------------------------------------------------------------\n// Per-event derivation of TurnEvents. Drives off the new accumulator and the\n// raw event, since some deltas (`tool_call_args_delta`) need the call_id\n// which lives on the accumulator's per-index block.\n// ---------------------------------------------------------------------------\n\nconst deltasFromEvent = (next: Accumulator, event: ProviderEvent): ReadonlyArray<TurnEvent> =>\n Match.value(event).pipe(\n Match.discriminatorsExhaustive(\"type\")({\n content_block_start: (e) =>\n e.content_block.type === \"tool_use\"\n ? [\n {\n type: \"tool_call_start\" as const,\n call_id: e.content_block.id,\n name: e.content_block.name,\n },\n ]\n : [],\n content_block_delta: (e) =>\n Match.value(e.delta).pipe(\n Match.discriminatorsExhaustive(\"type\")({\n text_delta: (d) => [{ type: \"text_delta\" as const, text: d.text }],\n thinking_delta: (d) => [\n { type: \"reasoning_delta\" as const, text: d.thinking, kind: \"trace\" as const },\n ],\n input_json_delta: (d) => {\n const block = next.blocks[e.index]\n if (block === undefined) return []\n const callId = Option.getOrElse(block.id, () => \"\")\n return callId.length === 0\n ? []\n : [\n {\n type: \"tool_call_args_delta\" as const,\n call_id: callId,\n delta: d.partial_json,\n },\n ]\n },\n // Encrypted reasoning state - flows through `streamNative` but has\n // no canonical representation.\n signature_delta: () => [],\n }),\n ),\n message_start: (e) =>\n e.message.usage === undefined ? [] : [{ type: \"usage_update\" as const, usage: next.usage }],\n message_delta: (e) =>\n e.usage === undefined ? [] : [{ type: \"usage_update\" as const, usage: next.usage }],\n message_stop: () => [{ type: \"turn_complete\" as const, turn: accumulatorToTurn(next) }],\n content_block_stop: () => [],\n ping: () => [],\n error: () => [],\n _unknown: () => [],\n }),\n )\n\n// ---------------------------------------------------------------------------\n// Service implementation\n// ---------------------------------------------------------------------------\n\nconst httpStatusError = (status: number, body: string): AiError.AiError => {\n const provider = \"anthropic\"\n const raw = body\n if (status === 429) return new AiError.RateLimited({ provider, raw })\n if (status === 408 || status === 504) return new AiError.Timeout({ provider, raw })\n if (status === 401) return new AiError.AuthFailed({ provider, subtype: \"auth\", raw })\n if (status === 403) return new AiError.AuthFailed({ provider, subtype: \"permission\", raw })\n if (status === 402) return new AiError.AuthFailed({ provider, subtype: \"billing\", raw })\n if (status === 413) return new AiError.ContextLengthExceeded({ provider, raw })\n if (status === 529) return new AiError.Unavailable({ provider, status, raw })\n if (status >= 500) return new AiError.Unavailable({ provider, status, raw })\n return new AiError.InvalidRequest({ provider, raw })\n}\n\nconst buildNativeStream = (cfg: Config) => {\n const baseUrl = cfg.baseUrl ?? \"https://api.anthropic.com\"\n const url = `${baseUrl}/v1/messages`\n return (\n request: AnthropicRequest,\n ): Stream.Stream<ProviderEvent, AiError.AiError, HttpClient.HttpClient> =>\n Stream.unwrap(\n Effect.gen(function* () {\n const structured = outputConfig(request)\n const bodyResult = buildRequestBody({\n model: request.model,\n history: request.history,\n maxTokens: resolvedMaxTokens(cfg, request),\n temperature: Option.fromUndefinedOr(request.temperature),\n topP: Option.fromUndefinedOr(request.topP),\n topK: Option.fromUndefinedOr(request.topK),\n stopSequences: Option.fromUndefinedOr(request.stopSequences),\n thinking: Option.fromUndefinedOr(request.thinking),\n tools: toolDescriptors(request),\n toolChoice: toolChoiceWire(request),\n userId: Option.fromUndefinedOr(request.user),\n outputConfig: structured,\n })\n\n const body = yield* Result.match(bodyResult, {\n onFailure: (cause) =>\n Effect.fail(\n new AiError.InvalidRequest({\n provider: \"anthropic\",\n param: \"input.function_call.arguments\",\n raw: cause,\n }),\n ),\n onSuccess: (b) => Effect.succeed(b),\n })\n\n const client = yield* HttpClient.HttpClient\n const baseRequest = HttpClientRequest.post(url).pipe(\n HttpClientRequest.setHeader(\"x-api-key\", Redacted.value(cfg.apiKey)),\n HttpClientRequest.setHeader(\"anthropic-version\", ANTHROPIC_VERSION),\n HttpClientRequest.bodyJsonUnsafe(body),\n HttpClientRequest.accept(\"text/event-stream\"),\n )\n const httpRequest = Option.isSome(structured)\n ? baseRequest.pipe(HttpClientRequest.setHeader(\"anthropic-beta\", STRUCTURED_OUTPUTS_BETA))\n : baseRequest\n const response = yield* client\n .execute(httpRequest)\n .pipe(\n Effect.mapError(\n (cause): AiError.AiError =>\n new AiError.Unavailable({ provider: \"anthropic\", raw: cause }),\n ),\n )\n if (response.status >= 400) {\n const text = yield* response.text.pipe(Effect.orElseSucceed(() => \"\"))\n return Stream.fail(httpStatusError(response.status, text))\n }\n\n return response.stream.pipe(\n Stream.mapError(\n (cause): AiError.AiError =>\n new AiError.Unavailable({ provider: \"anthropic\", raw: cause }),\n ),\n SSE.fromBytes,\n Stream.mapEffect(sseEventToProviderEvent),\n Stream.flatMap((event) =>\n event.type === \"error\"\n ? Stream.fail(new AiError.Unavailable({ provider: \"anthropic\", raw: event }))\n : Stream.succeed(event),\n ),\n )\n }),\n )\n}\n\n/**\n * Project a stream of native `ProviderEvent`s into canonical `TurnEvent`s.\n * Threads a fresh `Accumulator` per stream so tool-call lookup and\n * `accumulatorToTurn` assembly work correctly across the run.\n */\nexport const toCanonical = <E, R>(\n s: Stream.Stream<ProviderEvent, E, R>,\n): Stream.Stream<TurnEvent, E, R> =>\n s.pipe(\n Stream.mapAccum(\n () => emptyAccumulator,\n (acc, event) => {\n const next = applyEvent(acc, event)\n const deltas = deltasFromEvent(next, event)\n return [next, deltas] as const\n },\n ),\n )\n\n// ---------------------------------------------------------------------------\n// Constructors\n// ---------------------------------------------------------------------------\n\n/**\n * Build an `AnthropicService` value. For Layer-based setup, prefer `layer`.\n */\nexport const make = (cfg: Config): Effect.Effect<AnthropicService, never, HttpClient.HttpClient> =>\n Effect.map(HttpClient.HttpClient.asEffect(), (client) => {\n const streamNative: AnthropicService[\"streamNative\"] = (request) =>\n buildNativeStream(cfg)(request).pipe(Stream.provideService(HttpClient.HttpClient, client))\n return {\n streamNative,\n streamTurn: (request) => toCanonical(streamNative(request)),\n toCanonical,\n }\n })\n\n/**\n * Layer that registers both the provider-specific `Anthropic` tag and the\n * generic `LanguageModel` tag, sharing one underlying implementation.\n *\n * The generic tag accepts `CommonRequest`; the typed tag accepts the full\n * `AnthropicRequest` surface.\n */\nexport const layer = (\n cfg: Config,\n): Layer.Layer<Anthropic | LanguageModel, never, HttpClient.HttpClient> => {\n const typed = Layer.effect(Anthropic, make(cfg))\n const generic = Layer.effect(\n LanguageModel,\n Effect.map(\n make(cfg),\n (s): LanguageModelService => ({\n streamTurn: (request) => s.streamTurn(request as AnthropicRequest),\n }),\n ),\n )\n return Layer.merge(typed, generic)\n}\n"],"mappings":"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"}
|
package/dist/codec.d.mts
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { Option, Result, Schema } from "effect";
|
|
2
|
+
import { JsonParseError } from "@effect-uai/core/JSONL";
|
|
3
|
+
import { Turn } from "@effect-uai/core/Turn";
|
|
4
|
+
import * as Items from "@effect-uai/core/Items";
|
|
5
|
+
|
|
6
|
+
//#region src/codec.d.ts
|
|
7
|
+
declare namespace codec_d_exports {
|
|
8
|
+
export { Accumulator, RequestBody, ThinkingConfig, WireContentBlock, WireUsage, accumulatorToTurn, appendInputJsonDelta, appendSignatureDelta, appendTextDelta, appendThinkingDelta, buildRequestBody, emptyAccumulator, mergeUsage, setStopReason, startBlock };
|
|
9
|
+
}
|
|
10
|
+
declare const WireContentBlock: Schema.Union<readonly [Schema.Struct<{
|
|
11
|
+
readonly type: Schema.Literal<"text">;
|
|
12
|
+
readonly text: Schema.String;
|
|
13
|
+
}>, Schema.Struct<{
|
|
14
|
+
readonly type: Schema.Literal<"tool_use">;
|
|
15
|
+
readonly id: Schema.String;
|
|
16
|
+
readonly name: Schema.String;
|
|
17
|
+
readonly input: Schema.Unknown;
|
|
18
|
+
}>, Schema.Struct<{
|
|
19
|
+
readonly type: Schema.Literal<"thinking">;
|
|
20
|
+
readonly thinking: Schema.String;
|
|
21
|
+
readonly signature: Schema.optional<Schema.String>;
|
|
22
|
+
}>, Schema.Struct<{
|
|
23
|
+
readonly type: Schema.Literal<"redacted_thinking">;
|
|
24
|
+
readonly data: Schema.String;
|
|
25
|
+
}>]>;
|
|
26
|
+
type WireContentBlock = typeof WireContentBlock.Type;
|
|
27
|
+
declare const WireUsage: Schema.Struct<{
|
|
28
|
+
readonly input_tokens: Schema.optional<Schema.Number>;
|
|
29
|
+
readonly output_tokens: Schema.optional<Schema.Number>;
|
|
30
|
+
readonly cache_creation_input_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
|
|
31
|
+
readonly cache_read_input_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
|
|
32
|
+
}>;
|
|
33
|
+
type WireUsage = typeof WireUsage.Type;
|
|
34
|
+
type RequestTextContent = {
|
|
35
|
+
readonly type: "text";
|
|
36
|
+
readonly text: string;
|
|
37
|
+
};
|
|
38
|
+
type RequestToolResultContent = {
|
|
39
|
+
readonly type: "tool_result";
|
|
40
|
+
readonly tool_use_id: string;
|
|
41
|
+
readonly content: string;
|
|
42
|
+
};
|
|
43
|
+
type RequestToolUseContent = {
|
|
44
|
+
readonly type: "tool_use";
|
|
45
|
+
readonly id: string;
|
|
46
|
+
readonly name: string;
|
|
47
|
+
readonly input: unknown;
|
|
48
|
+
};
|
|
49
|
+
type RequestThinkingContent = {
|
|
50
|
+
readonly type: "thinking";
|
|
51
|
+
readonly thinking: string;
|
|
52
|
+
readonly signature?: string;
|
|
53
|
+
};
|
|
54
|
+
type RequestRedactedThinkingContent = {
|
|
55
|
+
readonly type: "redacted_thinking";
|
|
56
|
+
readonly data: string;
|
|
57
|
+
};
|
|
58
|
+
type RequestImageContent = {
|
|
59
|
+
readonly type: "image";
|
|
60
|
+
readonly source: {
|
|
61
|
+
readonly type: "url";
|
|
62
|
+
readonly url: string;
|
|
63
|
+
} | {
|
|
64
|
+
readonly type: "base64";
|
|
65
|
+
readonly media_type: string;
|
|
66
|
+
readonly data: string;
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
type RequestUserContentBlock = RequestTextContent | RequestToolResultContent | RequestImageContent;
|
|
70
|
+
type RequestAssistantContentBlock = RequestTextContent | RequestToolUseContent | RequestThinkingContent | RequestRedactedThinkingContent;
|
|
71
|
+
type RequestUserMessage = {
|
|
72
|
+
readonly role: "user";
|
|
73
|
+
readonly content: ReadonlyArray<RequestUserContentBlock>;
|
|
74
|
+
};
|
|
75
|
+
type RequestAssistantMessage = {
|
|
76
|
+
readonly role: "assistant";
|
|
77
|
+
readonly content: ReadonlyArray<RequestAssistantContentBlock>;
|
|
78
|
+
};
|
|
79
|
+
type RequestMessage = RequestUserMessage | RequestAssistantMessage;
|
|
80
|
+
type ThinkingConfig = {
|
|
81
|
+
readonly type: "enabled";
|
|
82
|
+
readonly budget_tokens: number;
|
|
83
|
+
};
|
|
84
|
+
type RequestBody = {
|
|
85
|
+
readonly model: string;
|
|
86
|
+
readonly messages: ReadonlyArray<RequestMessage>;
|
|
87
|
+
readonly max_tokens: number;
|
|
88
|
+
readonly system?: string;
|
|
89
|
+
readonly temperature?: number;
|
|
90
|
+
readonly top_p?: number;
|
|
91
|
+
readonly top_k?: number;
|
|
92
|
+
readonly stop_sequences?: ReadonlyArray<string>;
|
|
93
|
+
readonly thinking?: ThinkingConfig;
|
|
94
|
+
readonly tools?: ReadonlyArray<Record<string, unknown>>;
|
|
95
|
+
readonly tool_choice?: Record<string, unknown>;
|
|
96
|
+
readonly metadata?: {
|
|
97
|
+
readonly user_id: string;
|
|
98
|
+
};
|
|
99
|
+
readonly output_config?: Record<string, unknown>;
|
|
100
|
+
readonly stream: true;
|
|
101
|
+
};
|
|
102
|
+
declare const buildRequestBody: (params: {
|
|
103
|
+
readonly model: string;
|
|
104
|
+
readonly history: ReadonlyArray<Items.Item>;
|
|
105
|
+
readonly maxTokens: number;
|
|
106
|
+
readonly temperature: Option.Option<number>;
|
|
107
|
+
readonly topP: Option.Option<number>;
|
|
108
|
+
readonly topK: Option.Option<number>;
|
|
109
|
+
readonly stopSequences: Option.Option<ReadonlyArray<string>>;
|
|
110
|
+
readonly thinking: Option.Option<ThinkingConfig>;
|
|
111
|
+
readonly tools: Option.Option<ReadonlyArray<Record<string, unknown>>>;
|
|
112
|
+
readonly toolChoice: Option.Option<Record<string, unknown>>;
|
|
113
|
+
readonly userId: Option.Option<string>;
|
|
114
|
+
readonly outputConfig: Option.Option<Record<string, unknown>>;
|
|
115
|
+
}) => Result.Result<RequestBody, JsonParseError>;
|
|
116
|
+
type BlockBuffer = {
|
|
117
|
+
readonly type: WireContentBlock["type"];
|
|
118
|
+
readonly text: string;
|
|
119
|
+
readonly inputJson: string;
|
|
120
|
+
readonly thinking: string;
|
|
121
|
+
readonly signature: string;
|
|
122
|
+
readonly id: Option.Option<string>;
|
|
123
|
+
readonly name: Option.Option<string>;
|
|
124
|
+
readonly redactedData: Option.Option<string>;
|
|
125
|
+
};
|
|
126
|
+
type Accumulator = {
|
|
127
|
+
readonly blocks: Readonly<Record<number, BlockBuffer>>;
|
|
128
|
+
readonly stopReason: Option.Option<string>;
|
|
129
|
+
readonly usage: Items.Usage;
|
|
130
|
+
};
|
|
131
|
+
declare const emptyAccumulator: Accumulator;
|
|
132
|
+
declare const startBlock: (acc: Accumulator, index: number, block: WireContentBlock) => Accumulator;
|
|
133
|
+
declare const appendTextDelta: (acc: Accumulator, index: number, text: string) => Accumulator;
|
|
134
|
+
declare const appendInputJsonDelta: (acc: Accumulator, index: number, partial: string) => Accumulator;
|
|
135
|
+
declare const appendThinkingDelta: (acc: Accumulator, index: number, thinking: string) => Accumulator;
|
|
136
|
+
declare const appendSignatureDelta: (acc: Accumulator, index: number, signature: string) => Accumulator;
|
|
137
|
+
declare const setStopReason: (acc: Accumulator, reason: string) => Accumulator;
|
|
138
|
+
declare const mergeUsage: (acc: Accumulator, wire: WireUsage) => Accumulator;
|
|
139
|
+
declare const accumulatorToTurn: (acc: Accumulator) => Turn;
|
|
140
|
+
//#endregion
|
|
141
|
+
export { Accumulator, RequestBody, ThinkingConfig, WireContentBlock, WireUsage, accumulatorToTurn, appendInputJsonDelta, appendSignatureDelta, appendTextDelta, appendThinkingDelta, buildRequestBody, emptyAccumulator, mergeUsage, setStopReason, startBlock, codec_d_exports as t };
|
|
142
|
+
//# sourceMappingURL=codec.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codec.d.mts","names":[],"sources":["../src/codec.ts"],"mappings":";;;;;;;;;cAiCa,gBAAA,EAAgB,MAAA,CAAA,KAAA,WAAA,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;;;;;KAMjB,gBAAA,UAA0B,gBAAA,CAAiB,IAAA;AAAA,cAEjD,SAAA,EAAS,MAAA,CAAA,MAAA;EAAA;;;;;KAMH,SAAA,UAAmB,SAAA,CAAU,IAAA;AAAA,KAMpC,kBAAA;EAAA,SACM,IAAA;EAAA,SACA,IAAA;AAAA;AAAA,KAGN,wBAAA;EAAA,SACM,IAAA;EAAA,SACA,WAAA;EAAA,SACA,OAAA;AAAA;AAAA,KAGN,qBAAA;EAAA,SACM,IAAA;EAAA,SACA,EAAA;EAAA,SACA,IAAA;EAAA,SACA,KAAA;AAAA;AAAA,KAGN,sBAAA;EAAA,SACM,IAAA;EAAA,SACA,QAAA;EAAA,SACA,SAAA;AAAA;AAAA,KAGN,8BAAA;EAAA,SACM,IAAA;EAAA,SACA,IAAA;AAAA;AAAA,KAGN,mBAAA;EAAA,SACM,IAAA;EAAA,SACA,MAAA;IAAA,SACM,IAAA;IAAA,SAAsB,GAAA;EAAA;IAAA,SACtB,IAAA;IAAA,SAAyB,UAAA;IAAA,SAA6B,IAAA;EAAA;AAAA;AAAA,KAGlE,uBAAA,GAA0B,kBAAA,GAAqB,wBAAA,GAA2B,mBAAA;AAAA,KAE1E,4BAAA,GACD,kBAAA,GACA,qBAAA,GACA,sBAAA,GACA,8BAAA;AAAA,KAEC,kBAAA;EAAA,SACM,IAAA;EAAA,SACA,OAAA,EAAS,aAAA,CAAc,uBAAA;AAAA;AAAA,KAG7B,uBAAA;EAAA,SACM,IAAA;EAAA,SACA,OAAA,EAAS,aAAA,CAAc,4BAAA;AAAA;AAAA,KAG7B,cAAA,GAAiB,kBAAA,GAAqB,uBAAA;AAAA,KAmN/B,cAAA;EAAA,SACD,IAAA;EAAA,SACA,aAAA;AAAA;AAAA,KAGC,WAAA;EAAA,SACD,KAAA;EAAA,SACA,QAAA,EAAU,aAAA,CAAc,cAAA;EAAA,SACxB,UAAA;EAAA,SACA,MAAA;EAAA,SACA,WAAA;EAAA,SACA,KAAA;EAAA,SACA,KAAA;EAAA,SACA,cAAA,GAAiB,aAAA;EAAA,SACjB,QAAA,GAAW,cAAA;EAAA,SACX,KAAA,GAAQ,aAAA,CAAc,MAAA;EAAA,SACtB,WAAA,GAAc,MAAA;EAAA,SACd,QAAA;IAAA,SAAsB,OAAA;EAAA;EAAA,SACtB,aAAA,GAAgB,MAAA;EAAA,SAChB,MAAA;AAAA;AAAA,cAGE,gBAAA,GAAoB,MAAA;EAAA,SACtB,KAAA;EAAA,SACA,OAAA,EAAS,aAAA,CAAc,KAAA,CAAM,IAAA;EAAA,SAC7B,SAAA;EAAA,SACA,WAAA,EAAa,MAAA,CAAO,MAAA;EAAA,SACpB,IAAA,EAAM,MAAA,CAAO,MAAA;EAAA,SACb,IAAA,EAAM,MAAA,CAAO,MAAA;EAAA,SACb,aAAA,EAAe,MAAA,CAAO,MAAA,CAAO,aAAA;EAAA,SAC7B,QAAA,EAAU,MAAA,CAAO,MAAA,CAAO,cAAA;EAAA,SACxB,KAAA,EAAO,MAAA,CAAO,MAAA,CAAO,aAAA,CAAc,MAAA;EAAA,SACnC,UAAA,EAAY,MAAA,CAAO,MAAA,CAAO,MAAA;EAAA,SAC1B,MAAA,EAAQ,MAAA,CAAO,MAAA;EAAA,SACf,YAAA,EAAc,MAAA,CAAO,MAAA,CAAO,MAAA;AAAA,MACnC,MAAA,CAAO,MAAA,CAAO,WAAA,EAAa,cAAA;AAAA,KA0D1B,WAAA;EAAA,SACM,IAAA,EAAM,gBAAA;EAAA,SACN,IAAA;EAAA,SACA,SAAA;EAAA,SACA,QAAA;EAAA,SACA,SAAA;EAAA,SACA,EAAA,EAAI,MAAA,CAAO,MAAA;EAAA,SACX,IAAA,EAAM,MAAA,CAAO,MAAA;EAAA,SACb,YAAA,EAAc,MAAA,CAAO,MAAA;AAAA;AAAA,KAcpB,WAAA;EAAA,SACD,MAAA,EAAQ,QAAA,CAAS,MAAA,SAAe,WAAA;EAAA,SAChC,UAAA,EAAY,MAAA,CAAO,MAAA;EAAA,SACnB,KAAA,EAAO,KAAA,CAAM,KAAA;AAAA;AAAA,cAGX,gBAAA,EAAkB,WAAA;AAAA,cAiBlB,UAAA,GAAc,GAAA,EAAK,WAAA,EAAa,KAAA,UAAe,KAAA,EAAO,gBAAA,KAAmB,WAAA;AAAA,cAoBzE,eAAA,GAAmB,GAAA,EAAK,WAAA,EAAa,KAAA,UAAe,IAAA,aAAe,WAAA;AAAA,cAGnE,oBAAA,GACX,GAAA,EAAK,WAAA,EACL,KAAA,UACA,OAAA,aACC,WAAA;AAAA,cAEU,mBAAA,GACX,GAAA,EAAK,WAAA,EACL,KAAA,UACA,QAAA,aACC,WAAA;AAAA,cAEU,oBAAA,GACX,GAAA,EAAK,WAAA,EACL,KAAA,UACA,SAAA,aACC,WAAA;AAAA,cAEU,aAAA,GAAiB,GAAA,EAAK,WAAA,EAAa,MAAA,aAAiB,WAAA;AAAA,cAQpD,UAAA,GAAc,GAAA,EAAK,WAAA,EAAa,IAAA,EAAM,SAAA,KAAY,WAAA;AAAA,cAiHlD,iBAAA,GAAqB,GAAA,EAAK,WAAA,KAAc,IAAA"}
|