@prismshadow/mmsp 0.5.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 (116) hide show
  1. package/README.md +121 -0
  2. package/dist/ant_messages/client.d.ts +59 -0
  3. package/dist/ant_messages/client.d.ts.map +1 -0
  4. package/dist/ant_messages/client.js +419 -0
  5. package/dist/ant_messages/index.d.ts +2 -0
  6. package/dist/ant_messages/index.d.ts.map +1 -0
  7. package/dist/ant_messages/index.js +18 -0
  8. package/dist/anthropic_official/client.d.ts +63 -0
  9. package/dist/anthropic_official/client.d.ts.map +1 -0
  10. package/dist/anthropic_official/client.js +540 -0
  11. package/dist/anthropic_official/index.d.ts +2 -0
  12. package/dist/anthropic_official/index.d.ts.map +1 -0
  13. package/dist/anthropic_official/index.js +18 -0
  14. package/dist/autoClient.d.ts +96 -0
  15. package/dist/autoClient.d.ts.map +1 -0
  16. package/dist/autoClient.js +258 -0
  17. package/dist/baseClient.d.ts +111 -0
  18. package/dist/baseClient.d.ts.map +1 -0
  19. package/dist/baseClient.js +284 -0
  20. package/dist/deepseek_official/client.d.ts +60 -0
  21. package/dist/deepseek_official/client.d.ts.map +1 -0
  22. package/dist/deepseek_official/client.js +407 -0
  23. package/dist/deepseek_official/index.d.ts +2 -0
  24. package/dist/deepseek_official/index.d.ts.map +1 -0
  25. package/dist/deepseek_official/index.js +18 -0
  26. package/dist/errors.d.ts +84 -0
  27. package/dist/errors.d.ts.map +1 -0
  28. package/dist/errors.js +140 -0
  29. package/dist/gemini_generate_content/client.d.ts +86 -0
  30. package/dist/gemini_generate_content/client.d.ts.map +1 -0
  31. package/dist/gemini_generate_content/client.js +809 -0
  32. package/dist/gemini_generate_content/index.d.ts +2 -0
  33. package/dist/gemini_generate_content/index.d.ts.map +1 -0
  34. package/dist/gemini_generate_content/index.js +18 -0
  35. package/dist/gemini_official/client.d.ts +87 -0
  36. package/dist/gemini_official/client.d.ts.map +1 -0
  37. package/dist/gemini_official/client.js +780 -0
  38. package/dist/gemini_official/index.d.ts +2 -0
  39. package/dist/gemini_official/index.d.ts.map +1 -0
  40. package/dist/gemini_official/index.js +18 -0
  41. package/dist/index.d.ts +6 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +44 -0
  44. package/dist/integration/index.d.ts +1 -0
  45. package/dist/integration/index.d.ts.map +1 -0
  46. package/dist/integration/index.js +14 -0
  47. package/dist/integration/playground.d.ts +17 -0
  48. package/dist/integration/playground.d.ts.map +1 -0
  49. package/dist/integration/playground.js +3246 -0
  50. package/dist/integration/tracer.d.ts +188 -0
  51. package/dist/integration/tracer.d.ts.map +1 -0
  52. package/dist/integration/tracer.js +1928 -0
  53. package/dist/legacy.d.ts +13 -0
  54. package/dist/legacy.d.ts.map +1 -0
  55. package/dist/legacy.js +59 -0
  56. package/dist/minimax_official/client.d.ts +43 -0
  57. package/dist/minimax_official/client.d.ts.map +1 -0
  58. package/dist/minimax_official/client.js +346 -0
  59. package/dist/minimax_official/index.d.ts +2 -0
  60. package/dist/minimax_official/index.d.ts.map +1 -0
  61. package/dist/minimax_official/index.js +18 -0
  62. package/dist/moonshot_official/client.d.ts +73 -0
  63. package/dist/moonshot_official/client.d.ts.map +1 -0
  64. package/dist/moonshot_official/client.js +477 -0
  65. package/dist/moonshot_official/index.d.ts +2 -0
  66. package/dist/moonshot_official/index.d.ts.map +1 -0
  67. package/dist/moonshot_official/index.js +18 -0
  68. package/dist/openai_chat/client.d.ts +67 -0
  69. package/dist/openai_chat/client.d.ts.map +1 -0
  70. package/dist/openai_chat/client.js +419 -0
  71. package/dist/openai_chat/index.d.ts +2 -0
  72. package/dist/openai_chat/index.d.ts.map +1 -0
  73. package/dist/openai_chat/index.js +18 -0
  74. package/dist/openai_chat_vllm_adapter/client.d.ts +15 -0
  75. package/dist/openai_chat_vllm_adapter/client.d.ts.map +1 -0
  76. package/dist/openai_chat_vllm_adapter/client.js +118 -0
  77. package/dist/openai_chat_vllm_adapter/index.d.ts +2 -0
  78. package/dist/openai_chat_vllm_adapter/index.d.ts.map +1 -0
  79. package/dist/openai_chat_vllm_adapter/index.js +5 -0
  80. package/dist/openai_embedding/client.d.ts +46 -0
  81. package/dist/openai_embedding/client.d.ts.map +1 -0
  82. package/dist/openai_embedding/client.js +124 -0
  83. package/dist/openai_embedding/index.d.ts +2 -0
  84. package/dist/openai_embedding/index.d.ts.map +1 -0
  85. package/dist/openai_embedding/index.js +18 -0
  86. package/dist/openai_official/client.d.ts +61 -0
  87. package/dist/openai_official/client.d.ts.map +1 -0
  88. package/dist/openai_official/client.js +464 -0
  89. package/dist/openai_official/index.d.ts +2 -0
  90. package/dist/openai_official/index.d.ts.map +1 -0
  91. package/dist/openai_official/index.js +18 -0
  92. package/dist/openai_responses/client.d.ts +61 -0
  93. package/dist/openai_responses/client.d.ts.map +1 -0
  94. package/dist/openai_responses/client.js +449 -0
  95. package/dist/openai_responses/index.d.ts +2 -0
  96. package/dist/openai_responses/index.d.ts.map +1 -0
  97. package/dist/openai_responses/index.js +18 -0
  98. package/dist/registry.d.ts +49 -0
  99. package/dist/registry.d.ts.map +1 -0
  100. package/dist/registry.js +798 -0
  101. package/dist/streamItems.d.ts +36 -0
  102. package/dist/streamItems.d.ts.map +1 -0
  103. package/dist/streamItems.js +183 -0
  104. package/dist/types.d.ts +190 -0
  105. package/dist/types.d.ts.map +1 -0
  106. package/dist/types.js +37 -0
  107. package/dist/utils.d.ts +99 -0
  108. package/dist/utils.d.ts.map +1 -0
  109. package/dist/utils.js +312 -0
  110. package/dist/zai_official/client.d.ts +78 -0
  111. package/dist/zai_official/client.d.ts.map +1 -0
  112. package/dist/zai_official/client.js +420 -0
  113. package/dist/zai_official/index.d.ts +2 -0
  114. package/dist/zai_official/index.d.ts.map +1 -0
  115. package/dist/zai_official/index.js +18 -0
  116. package/package.json +68 -0
@@ -0,0 +1,63 @@
1
+ import { BetaMessageParam, BetaRawMessageStreamEvent } from "@anthropic-ai/sdk/resources/beta/messages";
2
+ import { LLMClient } from "../baseClient";
3
+ import { UniConfig, UniEvent, UniMessage } from "../types";
4
+ /**
5
+ * Claude 5-specific LLM client implementation (also serves Claude 4.6 through 4.8).
6
+ */
7
+ export declare class AnthropicOfficialClient extends LLMClient {
8
+ protected _model: string;
9
+ private _client;
10
+ private _use_bedrock;
11
+ /**
12
+ * Initialize Claude 5 client with model and API key.
13
+ */
14
+ constructor(options: {
15
+ model: string;
16
+ apiKey?: string;
17
+ baseUrl?: string | null;
18
+ defaultHeaders?: Record<string, string>;
19
+ });
20
+ /**
21
+ * Convert image URL to image source.
22
+ *
23
+ * Bedrock does not support image url sources, so we need to fetch the image bytes and encode them.
24
+ */
25
+ private _convertImageUrlToSource;
26
+ /**
27
+ * Convert ThinkingLevel enum to Claude's adaptive thinking config.
28
+ */
29
+ private _generation;
30
+ private _convertThinkingLevelToThinkingConfig;
31
+ /**
32
+ * Convert ToolChoice to Claude's tool_choice format.
33
+ */
34
+ private _convertToolChoice;
35
+ /**
36
+ * Transform universal configuration to Claude-specific configuration.
37
+ */
38
+ transformUniConfigToModelConfig(config: UniConfig): any;
39
+ /**
40
+ * Transform universal message format to Claude's MessageParam format.
41
+ */
42
+ transformUniMessageToModelInput(messages: UniMessage[], signal?: AbortSignal): Promise<BetaMessageParam[]>;
43
+ /**
44
+ * Transform one Claude stream event into a universal event, identifying items by content
45
+ * block index.
46
+ */
47
+ transformModelOutputToUniEvent(modelOutput: BetaRawMessageStreamEvent): UniEvent;
48
+ /**
49
+ * Stream generate using Claude SDK with unified conversion methods.
50
+ */
51
+ _streamingResponseInternal(options: {
52
+ messages: UniMessage[];
53
+ config: UniConfig;
54
+ signal?: AbortSignal;
55
+ }): AsyncGenerator<UniEvent>;
56
+ /**
57
+ * List the model ids the configured endpoint serves.
58
+ *
59
+ * @returns The model ids, in the order the endpoint returned them.
60
+ */
61
+ listModels(): Promise<string[]>;
62
+ }
63
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/anthropic_official/client.ts"],"names":[],"mappings":"AAgBA,OAAO,EACL,gBAAgB,EAChB,yBAAyB,EAC1B,MAAM,2CAA2C,CAAC;AAEnD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAK1C,OAAO,EAOL,SAAS,EACT,QAAQ,EACR,UAAU,EAEX,MAAM,UAAU,CAAC;AAelB;;GAEG;AACH,qBAAa,uBAAwB,SAAQ,SAAS;IACpD,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,YAAY,CAAU;IAE9B;;OAEG;gBACS,OAAO,EAAE;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACzC;IAuCD;;;;OAIG;YACW,wBAAwB;IA8CtC;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,qCAAqC;IA6C7C;;OAEG;IAEH,OAAO,CAAC,kBAAkB;IA6B1B;;OAEG;IAEH,+BAA+B,CAAC,MAAM,EAAE,SAAS,GAAG,GAAG;IAoGvD;;OAEG;IACG,+BAA+B,CACnC,QAAQ,EAAE,UAAU,EAAE,EACtB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAqE9B;;;OAGG;IACH,8BAA8B,CAC5B,WAAW,EAAE,yBAAyB,GACrC,QAAQ;IAwHX;;OAEG;IACI,0BAA0B,CAAC,OAAO,EAAE;QACzC,QAAQ,EAAE,UAAU,EAAE,CAAC;QACvB,MAAM,EAAE,SAAS,CAAC;QAClB,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GAAG,cAAc,CAAC,QAAQ,CAAC;IAmD5B;;;;OAIG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAgBtC"}
@@ -0,0 +1,540 @@
1
+ "use strict";
2
+ // Copyright 2025 Prism Shadow. and/or its affiliates
3
+ //
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // you may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ //
8
+ // http://www.apache.org/licenses/LICENSE-2.0
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software
11
+ // distributed under the License is distributed on an "AS IS" BASIS,
12
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ // See the License for the specific language governing permissions and
14
+ // limitations under the License.
15
+ var __importDefault = (this && this.__importDefault) || function (mod) {
16
+ return (mod && mod.__esModule) ? mod : { "default": mod };
17
+ };
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.AnthropicOfficialClient = void 0;
20
+ const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
21
+ const bedrock_sdk_1 = __importDefault(require("@anthropic-ai/bedrock-sdk"));
22
+ const baseClient_1 = require("../baseClient");
23
+ const errors_1 = require("../errors");
24
+ const types_1 = require("../types");
25
+ const utils_1 = require("../utils");
26
+ const REDACTED_THINKING = "_REDACTED_THINKING";
27
+ // Generations told apart by explicit version, matched anywhere in the id so Bedrock's
28
+ // anthropic.claude-opus-5-5 counts too. Opus 5.5 and Fable 5.1 always think: "disabled" and
29
+ // "between_tools" return 400. Sonnet 5.5 drops only up-front thinking, with "between_tools".
30
+ const ALWAYS_THINKING = ["opus-5-5", "fable-5-1"];
31
+ const BETWEEN_TOOLS = ["sonnet-5-5"];
32
+ // The 2026-09 generation returns 400 for tool_choice "any" and "tool".
33
+ const NO_FORCED_TOOL_CHOICE = ["opus-5-5", "sonnet-5-5", "fable-5-1"];
34
+ // These reject the speed parameter ("does not support the `speed` parameter").
35
+ const NO_FAST_MODE = ["4-6", "sonnet-5-5", "fable-5-1"];
36
+ /**
37
+ * Claude 5-specific LLM client implementation (also serves Claude 4.6 through 4.8).
38
+ */
39
+ class AnthropicOfficialClient extends baseClient_1.LLMClient {
40
+ /**
41
+ * Initialize Claude 5 client with model and API key.
42
+ */
43
+ constructor(options) {
44
+ super();
45
+ this._model = options.model;
46
+ const { apiKey: key, baseUrl: url } = (0, utils_1.resolveCredentials)(this.constructor.name, options, { key: "ANTHROPIC_API_KEY", baseUrl: "ANTHROPIC_BASE_URL" });
47
+ if (url && url.startsWith("bedrock://")) {
48
+ // example: bedrock://us-east-1
49
+ const region = url.replace("bedrock://", "");
50
+ const [accessKey, secretKey] = (key || "").split(",");
51
+ const bedrock = new bedrock_sdk_1.default({
52
+ awsSecretKey: secretKey,
53
+ awsAccessKey: accessKey,
54
+ awsRegion: region,
55
+ defaultHeaders: options.defaultHeaders,
56
+ });
57
+ // AnthropicBedrock's options type leaves out apiKey and authToken, yet the Anthropic client
58
+ // it extends still fills both from ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN and sends them
59
+ // to AWS beside the SigV4 signature, so clear them: the AWS credentials sign alone.
60
+ bedrock.apiKey = null;
61
+ bedrock.authToken = null;
62
+ this._client = bedrock;
63
+ this._use_bedrock = true;
64
+ }
65
+ else {
66
+ this._client = new sdk_1.default({
67
+ apiKey: key,
68
+ // null, not undefined: the SDK fills an undefined authToken from ANTHROPIC_AUTH_TOKEN and
69
+ // sends it as Authorization: Bearer beside the key, to whatever base URL this client uses
70
+ authToken: null,
71
+ baseURL: url,
72
+ defaultHeaders: options.defaultHeaders,
73
+ });
74
+ this._use_bedrock = false;
75
+ }
76
+ }
77
+ /**
78
+ * Convert image URL to image source.
79
+ *
80
+ * Bedrock does not support image url sources, so we need to fetch the image bytes and encode them.
81
+ */
82
+ async _convertImageUrlToSource(url, signal) {
83
+ if (url.startsWith("data:")) {
84
+ const match = url.match(/data:([^;]+);base64,(.+)/);
85
+ if (match) {
86
+ const mediaType = match[1];
87
+ const base64Data = match[2];
88
+ return {
89
+ type: "image",
90
+ source: {
91
+ type: "base64",
92
+ media_type: mediaType,
93
+ data: base64Data,
94
+ },
95
+ };
96
+ }
97
+ else {
98
+ throw new Error(`Invalid base64 image: ${url}`);
99
+ }
100
+ }
101
+ else if (this._use_bedrock) {
102
+ const response = await fetch(url, { signal });
103
+ if (!response.ok) {
104
+ throw new Error(`Failed to fetch image: ${response.status} ${response.statusText}`);
105
+ }
106
+ const arrayBuffer = await response.arrayBuffer();
107
+ const buffer = Buffer.from(arrayBuffer);
108
+ const mime_type = response.headers.get("content-type") || "image/jpeg";
109
+ return {
110
+ type: "image",
111
+ source: {
112
+ type: "base64",
113
+ media_type: mime_type,
114
+ data: buffer.toString("base64"),
115
+ },
116
+ };
117
+ }
118
+ else {
119
+ return { type: "image", source: { type: "url", url } };
120
+ }
121
+ }
122
+ /**
123
+ * Convert ThinkingLevel enum to Claude's adaptive thinking config.
124
+ */
125
+ _generation(versions) {
126
+ return versions.some((version) => this._model.includes(version));
127
+ }
128
+ _convertThinkingLevelToThinkingConfig(thinkingLevel) {
129
+ // nothing turns thinking off on ALWAYS_THINKING, so NONE takes the least of it
130
+ const none = this._generation(ALWAYS_THINKING)
131
+ ? { thinking: { type: "adaptive" }, output_config: { effort: "low" } }
132
+ : this._generation(BETWEEN_TOOLS)
133
+ ? { thinking: { type: "between_tools" } }
134
+ : {}; // omit thinking config
135
+ const mapping = {
136
+ [types_1.ThinkingLevel.NONE]: none,
137
+ [types_1.ThinkingLevel.LOW]: {
138
+ thinking: { type: "adaptive" },
139
+ output_config: { effort: "low" },
140
+ },
141
+ [types_1.ThinkingLevel.MEDIUM]: {
142
+ thinking: { type: "adaptive" },
143
+ output_config: { effort: "medium" },
144
+ },
145
+ [types_1.ThinkingLevel.HIGH]: {
146
+ thinking: { type: "adaptive" },
147
+ output_config: { effort: "high" },
148
+ },
149
+ // Claude 4.6 has no xhigh effort, so XHIGH degrades to the closest supported level
150
+ [types_1.ThinkingLevel.XHIGH]: {
151
+ thinking: { type: "adaptive" },
152
+ output_config: {
153
+ effort: this._model.includes("4-6") ? "high" : "xhigh",
154
+ },
155
+ },
156
+ // every model this client serves is 4.6 or later, and max spans that whole range
157
+ [types_1.ThinkingLevel.MAX]: {
158
+ thinking: { type: "adaptive" },
159
+ output_config: { effort: "max" },
160
+ },
161
+ };
162
+ return mapping[thinkingLevel];
163
+ }
164
+ /**
165
+ * Convert ToolChoice to Claude's tool_choice format.
166
+ */
167
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
168
+ _convertToolChoice(toolChoice) {
169
+ if ((toolChoice === "required" || Array.isArray(toolChoice)) &&
170
+ this._generation(NO_FORCED_TOOL_CHOICE)) {
171
+ throw new errors_1.UnsupportedParameterError({
172
+ client: this.constructor.name,
173
+ parameter: "tool_choice",
174
+ message: `${this._model} does not support forcing a tool call; use auto and name the tool in the prompt.`,
175
+ });
176
+ }
177
+ if (Array.isArray(toolChoice)) {
178
+ if (toolChoice.length > 1) {
179
+ throw new errors_1.UnsupportedParameterError({
180
+ client: this.constructor.name,
181
+ parameter: "tool_choice",
182
+ message: "Claude supports only one tool choice.",
183
+ });
184
+ }
185
+ return { type: "any", name: toolChoice[0] };
186
+ }
187
+ else if (toolChoice === "none") {
188
+ return { type: "none" };
189
+ }
190
+ else if (toolChoice === "auto") {
191
+ return { type: "auto" };
192
+ }
193
+ else if (toolChoice === "required") {
194
+ return { type: "any" };
195
+ }
196
+ }
197
+ /**
198
+ * Transform universal configuration to Claude-specific configuration.
199
+ */
200
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
201
+ transformUniConfigToModelConfig(config) {
202
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
203
+ const claudeConfig = {
204
+ model: this._model,
205
+ stream: true,
206
+ };
207
+ if (config.system_prompt !== undefined) {
208
+ claudeConfig.system = config.system_prompt;
209
+ }
210
+ if (config.max_tokens !== undefined) {
211
+ claudeConfig.max_tokens = config.max_tokens;
212
+ }
213
+ else {
214
+ claudeConfig.max_tokens = 64000;
215
+ }
216
+ if (config.temperature !== undefined && config.temperature !== 1.0) {
217
+ throw new errors_1.UnsupportedParameterError({
218
+ client: this.constructor.name,
219
+ parameter: "temperature",
220
+ message: "Claude models do not support setting temperature; the API dropped it " +
221
+ "starting with the 4.7 generation and the unified client rejects it for the whole family.",
222
+ });
223
+ }
224
+ if (config.thinking_level !== undefined) {
225
+ Object.assign(claudeConfig, this._convertThinkingLevelToThinkingConfig(config.thinking_level));
226
+ }
227
+ if (config.thinking_summary !== undefined) {
228
+ // display lives on the thinking block, so a summary asked for on its own selects
229
+ // adaptive thinking, which is what this family runs by default anyway; a block
230
+ // carrying display but no output_config is accepted on 4.6 through 5 (verified
231
+ // live 2026-09-03). NONE omits the block, so the request lands on that default.
232
+ claudeConfig.thinking = claudeConfig.thinking ?? { type: "adaptive" };
233
+ // between_tools takes no display: its updates between tool calls always carry their text
234
+ if (claudeConfig.thinking.type !== "between_tools") {
235
+ claudeConfig.thinking.display = config.thinking_summary
236
+ ? "summarized"
237
+ : "omitted";
238
+ }
239
+ }
240
+ if (config.tools !== undefined) {
241
+ const claudeTools = [];
242
+ for (const tool of config.tools) {
243
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
244
+ const claudeTool = {};
245
+ for (const [key, value] of Object.entries(tool)) {
246
+ claudeTool[key.replace("parameters", "input_schema")] = value;
247
+ }
248
+ claudeTools.push(claudeTool);
249
+ }
250
+ claudeConfig.tools = claudeTools;
251
+ }
252
+ if (config.tool_choice !== undefined) {
253
+ claudeConfig.tool_choice = this._convertToolChoice(config.tool_choice);
254
+ }
255
+ if (config.fast_mode) {
256
+ if (this._use_bedrock) {
257
+ throw new errors_1.UnsupportedParameterError({
258
+ client: this.constructor.name,
259
+ parameter: "fast_mode",
260
+ message: "Bedrock does not support fast mode.",
261
+ });
262
+ }
263
+ if (this._generation(NO_FAST_MODE)) {
264
+ throw new errors_1.UnsupportedParameterError({
265
+ client: this.constructor.name,
266
+ parameter: "fast_mode",
267
+ message: `${this._model} does not support fast mode.`,
268
+ });
269
+ }
270
+ claudeConfig.speed = "fast";
271
+ claudeConfig.betas = ["fast-mode-2026-02-01"];
272
+ }
273
+ // Add cache_control if prompt caching is enabled
274
+ // TODO: wait for bedrock to support cache_control in config
275
+ if (!this._use_bedrock) {
276
+ const promptCaching = config.prompt_caching || types_1.PromptCaching.ENABLE;
277
+ if (promptCaching === types_1.PromptCaching.ENABLE) {
278
+ claudeConfig.cache_control = { type: "ephemeral" };
279
+ }
280
+ else if (promptCaching === types_1.PromptCaching.ENHANCE) {
281
+ claudeConfig.cache_control = { type: "ephemeral", ttl: "1h" };
282
+ }
283
+ }
284
+ return claudeConfig;
285
+ }
286
+ /**
287
+ * Transform universal message format to Claude's MessageParam format.
288
+ */
289
+ async transformUniMessageToModelInput(messages, signal) {
290
+ const claudeMessages = [];
291
+ for (const msg of messages) {
292
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
293
+ const contentBlocks = [];
294
+ for (const item of msg.content_items) {
295
+ if (item.type === "text.done") {
296
+ contentBlocks.push({ type: "text", text: item.text });
297
+ }
298
+ else if (item.type === "image_url.done") {
299
+ const imageUrl = item.image_url;
300
+ contentBlocks.push(await this._convertImageUrlToSource(imageUrl, signal));
301
+ }
302
+ else if (item.type === "thinking.done") {
303
+ if (item.thinking === REDACTED_THINKING) {
304
+ contentBlocks.push({
305
+ type: "redacted_thinking",
306
+ data: item.fidelity?.signature,
307
+ });
308
+ }
309
+ else {
310
+ contentBlocks.push({
311
+ type: "thinking",
312
+ thinking: item.thinking,
313
+ signature: item.fidelity?.signature,
314
+ });
315
+ }
316
+ }
317
+ else if (item.type === "tool_call.done") {
318
+ contentBlocks.push({
319
+ type: "tool_use",
320
+ id: item.tool_call_id,
321
+ name: item.name,
322
+ input: item.arguments,
323
+ });
324
+ }
325
+ else if (item.type === "tool_result.done") {
326
+ if (!item.tool_call_id) {
327
+ throw new Error("tool_call_id is required for tool result.");
328
+ }
329
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
330
+ const toolResult = [{ type: "text", text: item.text }];
331
+ if (item.images) {
332
+ for (const imageUrl of item.images) {
333
+ toolResult.push(await this._convertImageUrlToSource(imageUrl, signal));
334
+ }
335
+ }
336
+ contentBlocks.push({
337
+ type: "tool_result",
338
+ content: toolResult,
339
+ tool_use_id: item.tool_call_id,
340
+ });
341
+ }
342
+ else {
343
+ throw new Error(`Unknown item: ${JSON.stringify(item)}`);
344
+ }
345
+ }
346
+ claudeMessages.push({
347
+ role: msg.role,
348
+ content: contentBlocks,
349
+ });
350
+ }
351
+ return claudeMessages;
352
+ }
353
+ /**
354
+ * Transform one Claude stream event into a universal event, identifying items by content
355
+ * block index.
356
+ */
357
+ transformModelOutputToUniEvent(modelOutput) {
358
+ let eventType = "delta";
359
+ const contentItems = [];
360
+ let usageMetadata = null;
361
+ let finishReason = null;
362
+ const claudeEventType = modelOutput.type;
363
+ if (claudeEventType === "content_block_start") {
364
+ const itemId = String(modelOutput.index);
365
+ const block = modelOutput.content_block;
366
+ if (block.type === "tool_use") {
367
+ contentItems.push({
368
+ type: "tool_call.delta",
369
+ name: block.name,
370
+ arguments: "",
371
+ tool_call_id: block.id,
372
+ fidelity: { item_id: itemId },
373
+ });
374
+ }
375
+ else if (block.type === "redacted_thinking") {
376
+ contentItems.push({
377
+ type: "thinking.delta",
378
+ thinking: REDACTED_THINKING,
379
+ fidelity: { item_id: itemId, signature: block.data },
380
+ });
381
+ }
382
+ }
383
+ else if (claudeEventType === "content_block_delta") {
384
+ const itemId = String(modelOutput.index);
385
+ const delta = modelOutput.delta;
386
+ if (delta.type === "thinking_delta") {
387
+ contentItems.push({
388
+ type: "thinking.delta",
389
+ thinking: delta.thinking,
390
+ fidelity: { item_id: itemId },
391
+ });
392
+ }
393
+ else if (delta.type === "text_delta") {
394
+ contentItems.push({
395
+ type: "text.delta",
396
+ text: delta.text,
397
+ fidelity: { item_id: itemId },
398
+ });
399
+ }
400
+ else if (delta.type === "input_json_delta") {
401
+ contentItems.push({
402
+ type: "tool_call.delta",
403
+ name: "",
404
+ arguments: delta.partial_json,
405
+ tool_call_id: "",
406
+ fidelity: { item_id: itemId },
407
+ });
408
+ }
409
+ else if (delta.type === "signature_delta") {
410
+ // the last delta of a thinking block: its signature
411
+ contentItems.push({
412
+ type: "thinking.delta",
413
+ thinking: "",
414
+ fidelity: { item_id: itemId, signature: delta.signature },
415
+ });
416
+ }
417
+ }
418
+ else if (claudeEventType === "message_start") {
419
+ eventType = "stop";
420
+ const usage = modelOutput.message.usage;
421
+ if (usage) {
422
+ const cacheCreationTokens = usage.cache_creation_input_tokens || 0;
423
+ usageMetadata = {
424
+ cached_tokens: usage.cache_read_input_tokens || null,
425
+ prompt_tokens: usage.input_tokens + cacheCreationTokens,
426
+ thoughts_tokens: null,
427
+ response_tokens: null,
428
+ };
429
+ }
430
+ }
431
+ else if (claudeEventType === "message_delta") {
432
+ eventType = "stop";
433
+ const stopReasonMapping = {
434
+ end_turn: "stop",
435
+ max_tokens: "length",
436
+ stop_sequence: "stop",
437
+ tool_use: "tool_call",
438
+ };
439
+ const stopReason = modelOutput.delta.stop_reason;
440
+ if (stopReason) {
441
+ finishReason = stopReasonMapping[stopReason] || "unknown";
442
+ }
443
+ if (modelOutput.usage) {
444
+ // message_delta reports the output tokens; the input side came with message_start
445
+ usageMetadata = {
446
+ cached_tokens: null,
447
+ prompt_tokens: null,
448
+ thoughts_tokens: null,
449
+ response_tokens: modelOutput.usage.output_tokens,
450
+ };
451
+ }
452
+ }
453
+ else if ([
454
+ "content_block_stop",
455
+ "message_stop",
456
+ "text",
457
+ "thinking",
458
+ "signature",
459
+ "input_json",
460
+ "ping",
461
+ ].includes(claudeEventType)) {
462
+ // a block needs no stop: it is done when the next one begins or the stream ends. The SDK
463
+ // drops the "ping" heartbeat at the SSE layer; it reaches here only from gateways that
464
+ // relabel it onto another event
465
+ }
466
+ else if ((0, utils_1.isDebugEnabled)()) {
467
+ throw new Error(`Unknown output: ${JSON.stringify(modelOutput)}`);
468
+ }
469
+ else {
470
+ // a gateway injects its own events (heartbeats, cost tickers) into the stream, and
471
+ // killing a long generation over one costs more than dropping it
472
+ }
473
+ return {
474
+ role: "assistant",
475
+ event_type: eventType,
476
+ content_items: contentItems,
477
+ usage_metadata: usageMetadata,
478
+ finish_reason: finishReason,
479
+ };
480
+ }
481
+ /**
482
+ * Stream generate using Claude SDK with unified conversion methods.
483
+ */
484
+ async *_streamingResponseInternal(options) {
485
+ const claudeConfig = this.transformUniConfigToModelConfig(options.config);
486
+ const claudeMessages = await this.transformUniMessageToModelInput(options.messages, options.signal);
487
+ // Add cache_control to last user message's last item if enabled
488
+ // TODO: remove after bedrock supports cache_control in config
489
+ if (this._use_bedrock) {
490
+ const promptCaching = options.config.prompt_caching || types_1.PromptCaching.ENABLE;
491
+ if (promptCaching !== types_1.PromptCaching.DISABLE &&
492
+ claudeMessages.length > 0) {
493
+ try {
494
+ const reversedMessages = [...claudeMessages].reverse();
495
+ const lastUserMessage = reversedMessages.find((x) => x.role === "user");
496
+ if (lastUserMessage && Array.isArray(lastUserMessage.content)) {
497
+ const lastContentItem = lastUserMessage.content[lastUserMessage.content.length - 1];
498
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
499
+ lastContentItem.cache_control = {
500
+ type: "ephemeral",
501
+ ttl: promptCaching === types_1.PromptCaching.ENHANCE ? "1h" : "5m",
502
+ };
503
+ }
504
+ }
505
+ catch {
506
+ // Ignore errors in cache_control setup
507
+ }
508
+ }
509
+ }
510
+ const stream = (await this._client.beta.messages.create({
511
+ ...claudeConfig,
512
+ messages: claudeMessages,
513
+ }, {
514
+ signal: options.signal,
515
+ }));
516
+ for await (const event of stream) {
517
+ yield this.transformModelOutputToUniEvent(event);
518
+ }
519
+ }
520
+ /**
521
+ * List the model ids the configured endpoint serves.
522
+ *
523
+ * @returns The model ids, in the order the endpoint returned them.
524
+ */
525
+ async listModels() {
526
+ if (this._use_bedrock) {
527
+ throw new errors_1.UnsupportedOperationError({
528
+ client: this.constructor.name,
529
+ operation: "list_models",
530
+ message: "Bedrock does not support listing models.",
531
+ });
532
+ }
533
+ const models = [];
534
+ for await (const model of this._client.models.list()) {
535
+ models.push(model.id);
536
+ }
537
+ return models;
538
+ }
539
+ }
540
+ exports.AnthropicOfficialClient = AnthropicOfficialClient;
@@ -0,0 +1,2 @@
1
+ export { AnthropicOfficialClient } from "./client";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/anthropic_official/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ // Copyright 2025 Prism Shadow. and/or its affiliates
3
+ //
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // you may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ //
8
+ // http://www.apache.org/licenses/LICENSE-2.0
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software
11
+ // distributed under the License is distributed on an "AS IS" BASIS,
12
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ // See the License for the specific language governing permissions and
14
+ // limitations under the License.
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.AnthropicOfficialClient = void 0;
17
+ var client_1 = require("./client");
18
+ Object.defineProperty(exports, "AnthropicOfficialClient", { enumerable: true, get: function () { return client_1.AnthropicOfficialClient; } });