@acentric/llm 0.0.0-stage → 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.
Files changed (232) hide show
  1. package/README.md +128 -2
  2. package/dist/catalog/anthropic.d.ts +77 -0
  3. package/dist/catalog/anthropic.d.ts.map +1 -0
  4. package/dist/catalog/anthropic.js +73 -0
  5. package/dist/catalog/anthropic.js.map +1 -0
  6. package/dist/catalog/fireworks.d.ts +93 -0
  7. package/dist/catalog/fireworks.d.ts.map +1 -0
  8. package/dist/catalog/fireworks.js +117 -0
  9. package/dist/catalog/fireworks.js.map +1 -0
  10. package/dist/catalog/openai.d.ts +103 -0
  11. package/dist/catalog/openai.d.ts.map +1 -0
  12. package/dist/catalog/openai.js +102 -0
  13. package/dist/catalog/openai.js.map +1 -0
  14. package/dist/client/anthropic/errors.d.ts +4 -0
  15. package/dist/client/anthropic/errors.d.ts.map +1 -0
  16. package/dist/client/anthropic/errors.js +80 -0
  17. package/dist/client/anthropic/errors.js.map +1 -0
  18. package/dist/client/anthropic/request.d.ts +9 -0
  19. package/dist/client/anthropic/request.d.ts.map +1 -0
  20. package/dist/client/anthropic/request.js +232 -0
  21. package/dist/client/anthropic/request.js.map +1 -0
  22. package/dist/client/anthropic/response.d.ts +13 -0
  23. package/dist/client/anthropic/response.d.ts.map +1 -0
  24. package/dist/client/anthropic/response.js +207 -0
  25. package/dist/client/anthropic/response.js.map +1 -0
  26. package/dist/client/direct.d.ts +18 -0
  27. package/dist/client/direct.d.ts.map +1 -0
  28. package/dist/client/direct.js +104 -0
  29. package/dist/client/direct.js.map +1 -0
  30. package/dist/client/gateway.d.ts +43 -0
  31. package/dist/client/gateway.d.ts.map +1 -0
  32. package/dist/client/gateway.js +72 -0
  33. package/dist/client/gateway.js.map +1 -0
  34. package/dist/client/http.d.ts +41 -0
  35. package/dist/client/http.d.ts.map +1 -0
  36. package/dist/client/http.js +190 -0
  37. package/dist/client/http.js.map +1 -0
  38. package/dist/client/llm.d.ts +41 -0
  39. package/dist/client/llm.d.ts.map +1 -0
  40. package/dist/client/llm.js +100 -0
  41. package/dist/client/llm.js.map +1 -0
  42. package/dist/client/responses/errors.d.ts +13 -0
  43. package/dist/client/responses/errors.d.ts.map +1 -0
  44. package/dist/client/responses/errors.js +144 -0
  45. package/dist/client/responses/errors.js.map +1 -0
  46. package/dist/client/responses/profile.d.ts +50 -0
  47. package/dist/client/responses/profile.d.ts.map +1 -0
  48. package/dist/client/responses/profile.js +4 -0
  49. package/dist/client/responses/profile.js.map +1 -0
  50. package/dist/client/responses/providers.d.ts +4 -0
  51. package/dist/client/responses/providers.d.ts.map +1 -0
  52. package/dist/client/responses/providers.js +75 -0
  53. package/dist/client/responses/providers.js.map +1 -0
  54. package/dist/client/responses/request.d.ts +5 -0
  55. package/dist/client/responses/request.d.ts.map +1 -0
  56. package/dist/client/responses/request.js +248 -0
  57. package/dist/client/responses/request.js.map +1 -0
  58. package/dist/client/responses/response.d.ts +10 -0
  59. package/dist/client/responses/response.d.ts.map +1 -0
  60. package/dist/client/responses/response.js +176 -0
  61. package/dist/client/responses/response.js.map +1 -0
  62. package/dist/client/util.d.ts +21 -0
  63. package/dist/client/util.d.ts.map +1 -0
  64. package/dist/client/util.js +63 -0
  65. package/dist/client/util.js.map +1 -0
  66. package/dist/client.d.ts +9 -0
  67. package/dist/client.d.ts.map +1 -0
  68. package/dist/client.js +10 -0
  69. package/dist/client.js.map +1 -0
  70. package/dist/content.d.ts +38 -0
  71. package/dist/content.d.ts.map +1 -0
  72. package/dist/content.js +5 -0
  73. package/dist/content.js.map +1 -0
  74. package/dist/convert/anthropic.d.ts +3 -0
  75. package/dist/convert/anthropic.d.ts.map +1 -0
  76. package/dist/convert/anthropic.js +114 -0
  77. package/dist/convert/anthropic.js.map +1 -0
  78. package/dist/convert/index.d.ts +12 -0
  79. package/dist/convert/index.d.ts.map +1 -0
  80. package/dist/convert/index.js +221 -0
  81. package/dist/convert/index.js.map +1 -0
  82. package/dist/convert/responses.d.ts +3 -0
  83. package/dist/convert/responses.d.ts.map +1 -0
  84. package/dist/convert/responses.js +197 -0
  85. package/dist/convert/responses.js.map +1 -0
  86. package/dist/convert/types.d.ts +88 -0
  87. package/dist/convert/types.d.ts.map +1 -0
  88. package/dist/convert/types.js +3 -0
  89. package/dist/convert/types.js.map +1 -0
  90. package/dist/cost.d.ts +18 -0
  91. package/dist/cost.d.ts.map +1 -0
  92. package/dist/cost.js +49 -0
  93. package/dist/cost.js.map +1 -0
  94. package/dist/failure.d.ts +90 -0
  95. package/dist/failure.d.ts.map +1 -0
  96. package/dist/failure.js +111 -0
  97. package/dist/failure.js.map +1 -0
  98. package/dist/fields.d.ts +14 -0
  99. package/dist/fields.d.ts.map +1 -0
  100. package/dist/fields.js +3 -0
  101. package/dist/fields.js.map +1 -0
  102. package/dist/formats/anthropic.d.ts +152 -0
  103. package/dist/formats/anthropic.d.ts.map +1 -0
  104. package/dist/formats/anthropic.js +7 -0
  105. package/dist/formats/anthropic.js.map +1 -0
  106. package/dist/formats/responses.d.ts +179 -0
  107. package/dist/formats/responses.d.ts.map +1 -0
  108. package/dist/formats/responses.js +9 -0
  109. package/dist/formats/responses.js.map +1 -0
  110. package/dist/index.d.ts +26 -0
  111. package/dist/index.d.ts.map +1 -0
  112. package/dist/index.js +11 -0
  113. package/dist/index.js.map +1 -0
  114. package/dist/json.d.ts +6 -0
  115. package/dist/json.d.ts.map +1 -0
  116. package/dist/json.js +10 -0
  117. package/dist/json.js.map +1 -0
  118. package/dist/messages.d.ts +82 -0
  119. package/dist/messages.d.ts.map +1 -0
  120. package/dist/messages.js +4 -0
  121. package/dist/messages.js.map +1 -0
  122. package/dist/model.d.ts +36 -0
  123. package/dist/model.d.ts.map +1 -0
  124. package/dist/model.js +4 -0
  125. package/dist/model.js.map +1 -0
  126. package/dist/models.d.ts +9 -0
  127. package/dist/models.d.ts.map +1 -0
  128. package/dist/models.js +19 -0
  129. package/dist/models.js.map +1 -0
  130. package/dist/providers/anthropic.d.ts +130 -0
  131. package/dist/providers/anthropic.d.ts.map +1 -0
  132. package/dist/providers/anthropic.js +5 -0
  133. package/dist/providers/anthropic.js.map +1 -0
  134. package/dist/providers/fireworks.d.ts +108 -0
  135. package/dist/providers/fireworks.d.ts.map +1 -0
  136. package/dist/providers/fireworks.js +6 -0
  137. package/dist/providers/fireworks.js.map +1 -0
  138. package/dist/providers/openai.d.ts +193 -0
  139. package/dist/providers/openai.d.ts.map +1 -0
  140. package/dist/providers/openai.js +4 -0
  141. package/dist/providers/openai.js.map +1 -0
  142. package/dist/providers.d.ts +50 -0
  143. package/dist/providers.d.ts.map +1 -0
  144. package/dist/providers.js +5 -0
  145. package/dist/providers.js.map +1 -0
  146. package/dist/read/anthropic.d.ts +15 -0
  147. package/dist/read/anthropic.d.ts.map +1 -0
  148. package/dist/read/anthropic.js +56 -0
  149. package/dist/read/anthropic.js.map +1 -0
  150. package/dist/read/responses.d.ts +26 -0
  151. package/dist/read/responses.d.ts.map +1 -0
  152. package/dist/read/responses.js +121 -0
  153. package/dist/read/responses.js.map +1 -0
  154. package/dist/read.d.ts +32 -0
  155. package/dist/read.d.ts.map +1 -0
  156. package/dist/read.js +73 -0
  157. package/dist/read.js.map +1 -0
  158. package/dist/request.d.ts +23 -0
  159. package/dist/request.d.ts.map +1 -0
  160. package/dist/request.js +4 -0
  161. package/dist/request.js.map +1 -0
  162. package/dist/response.d.ts +38 -0
  163. package/dist/response.d.ts.map +1 -0
  164. package/dist/response.js +4 -0
  165. package/dist/response.js.map +1 -0
  166. package/dist/secrets.d.ts +22 -0
  167. package/dist/secrets.d.ts.map +1 -0
  168. package/dist/secrets.js +35 -0
  169. package/dist/secrets.js.map +1 -0
  170. package/dist/tool-calls.d.ts +28 -0
  171. package/dist/tool-calls.d.ts.map +1 -0
  172. package/dist/tool-calls.js +4 -0
  173. package/dist/tool-calls.js.map +1 -0
  174. package/dist/tools.d.ts +33 -0
  175. package/dist/tools.d.ts.map +1 -0
  176. package/dist/tools.js +4 -0
  177. package/dist/tools.js.map +1 -0
  178. package/dist/usage.d.ts +31 -0
  179. package/dist/usage.d.ts.map +1 -0
  180. package/dist/usage.js +3 -0
  181. package/dist/usage.js.map +1 -0
  182. package/dist/version.d.ts +2 -0
  183. package/dist/version.d.ts.map +1 -0
  184. package/dist/version.js +6 -0
  185. package/dist/version.js.map +1 -0
  186. package/package.json +33 -3
  187. package/src/catalog/anthropic.ts +83 -0
  188. package/src/catalog/fireworks.ts +121 -0
  189. package/src/catalog/openai.ts +133 -0
  190. package/src/client/anthropic/errors.ts +88 -0
  191. package/src/client/anthropic/request.ts +272 -0
  192. package/src/client/anthropic/response.ts +236 -0
  193. package/src/client/direct.ts +157 -0
  194. package/src/client/gateway.ts +120 -0
  195. package/src/client/http.ts +231 -0
  196. package/src/client/llm.ts +151 -0
  197. package/src/client/responses/errors.ts +166 -0
  198. package/src/client/responses/profile.ts +55 -0
  199. package/src/client/responses/providers.ts +87 -0
  200. package/src/client/responses/request.ts +326 -0
  201. package/src/client/responses/response.ts +203 -0
  202. package/src/client/util.ts +81 -0
  203. package/src/client.ts +20 -0
  204. package/src/content.ts +46 -0
  205. package/src/convert/anthropic.ts +115 -0
  206. package/src/convert/index.ts +275 -0
  207. package/src/convert/responses.ts +203 -0
  208. package/src/convert/types.ts +104 -0
  209. package/src/cost.ts +71 -0
  210. package/src/failure.ts +164 -0
  211. package/src/fields.ts +13 -0
  212. package/src/formats/anthropic.ts +191 -0
  213. package/src/formats/responses.ts +207 -0
  214. package/src/index.ts +44 -0
  215. package/src/json.ts +13 -0
  216. package/src/messages.ts +99 -0
  217. package/src/model.ts +41 -0
  218. package/src/models.ts +23 -0
  219. package/src/providers/anthropic.ts +137 -0
  220. package/src/providers/fireworks.ts +140 -0
  221. package/src/providers/openai.ts +275 -0
  222. package/src/providers.ts +59 -0
  223. package/src/read/anthropic.ts +64 -0
  224. package/src/read/responses.ts +159 -0
  225. package/src/read.ts +108 -0
  226. package/src/request.ts +28 -0
  227. package/src/response.ts +44 -0
  228. package/src/secrets.ts +40 -0
  229. package/src/tool-calls.ts +33 -0
  230. package/src/tools.ts +38 -0
  231. package/src/usage.ts +33 -0
  232. package/src/version.ts +6 -0
@@ -0,0 +1,63 @@
1
+ // Small helpers the adapters share.
2
+ import { LlmError } from '../failure.js';
3
+ import { isArray, isObject } from '../json.js';
4
+ export function invalidRequest(provider, message) {
5
+ return new LlmError(message, {
6
+ kind: 'invalid_request',
7
+ ...(provider === undefined ? {} : { provider }),
8
+ });
9
+ }
10
+ export function invalidResponse(provider, message, body) {
11
+ return new LlmError(message, {
12
+ kind: 'invalid_response',
13
+ provider,
14
+ ...(body === undefined ? {} : { providerError: cut(body) }),
15
+ });
16
+ }
17
+ /**
18
+ * A part's `providerOptions`, or the request's `options`, refused when it sets
19
+ * a field the client sets itself on the same object: that is never
20
+ * overwritten silently.
21
+ */
22
+ export function ownFields(provider, fields, owned, where, field = 'providerOptions') {
23
+ if (fields === undefined)
24
+ return {};
25
+ if (!isObject(fields))
26
+ throw invalidRequest(provider, `${where}.${field} must be an object`);
27
+ for (const key of owned) {
28
+ if (key in fields) {
29
+ throw invalidRequest(provider, `${where}.${field}.${key} is set by the request: set it there`);
30
+ }
31
+ }
32
+ return fields;
33
+ }
34
+ /** A count of tokens: a whole number, zero or more. */
35
+ export function tokens(value) {
36
+ return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0 ? value : undefined;
37
+ }
38
+ /** `record` without `keys`, and without fields that are null, which say nothing. */
39
+ export function omit(record, keys) {
40
+ const skip = new Set(keys);
41
+ return Object.fromEntries(Object.entries(record).filter(([key, value]) => !skip.has(key) && value !== null));
42
+ }
43
+ /** Error bodies are cut short, so a proxy's HTML page does not fill a failure. */
44
+ export function cut(body) {
45
+ return typeof body === 'string' && body.length > 4096 ? body.slice(0, 4096) : body;
46
+ }
47
+ /** The text of content that is one text part with no options: sent as a plain string. */
48
+ export function plainText(content) {
49
+ if (!isArray(content) || content.length !== 1)
50
+ return undefined;
51
+ const [only] = content;
52
+ return isObject(only) &&
53
+ only['type'] === 'text' &&
54
+ typeof only['text'] === 'string' &&
55
+ only['providerOptions'] === undefined
56
+ ? only['text']
57
+ : undefined;
58
+ }
59
+ /** A value as a message shows it. */
60
+ export function show(value) {
61
+ return typeof value === 'string' ? value : (JSON.stringify(value) ?? 'nothing');
62
+ }
63
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/client/util.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export * from './index.js';
2
+ export { callProvider, readCredentials } from './client/direct.js';
3
+ export type { CallOptions } from './client/direct.js';
4
+ export { callGateway, GATEWAY_ROUTE, VERSION_HEADER } from './client/gateway.js';
5
+ export type { Gateway, GatewayCallOptions, GatewayEffect, GatewayFailure, GatewayRequest, } from './client/gateway.js';
6
+ export { createLlm } from './client/llm.js';
7
+ export type { LlmClient, LlmContext, LlmOptions } from './client/llm.js';
8
+ export { LLM_VERSION } from './version.js';
9
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAKA,cAAc,YAAY,CAAC;AAE3B,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACnE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACjF,YAAY,EACV,OAAO,EACP,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,cAAc,GACf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
package/dist/client.js ADDED
@@ -0,0 +1,10 @@
1
+ // The I/O half of @acentric/llm, for handlers only: it calls providers with
2
+ // fetch. It reads keys and the gateway from the handler's secrets, never from
3
+ // the environment, so the same code runs on every runner. It also has
4
+ // everything in the pure entry, so a handler imports from one place.
5
+ export * from './index.js';
6
+ export { callProvider, readCredentials } from './client/direct.js';
7
+ export { callGateway, GATEWAY_ROUTE, VERSION_HEADER } from './client/gateway.js';
8
+ export { createLlm } from './client/llm.js';
9
+ export { LLM_VERSION } from './version.js';
10
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,8EAA8E;AAC9E,sEAAsE;AACtE,qEAAqE;AAErE,cAAc,YAAY,CAAC;AAE3B,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAEnE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAQjF,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,38 @@
1
+ import type { Metadata, ProviderFields } from './fields.js';
2
+ /** Where an image or file comes from. */
3
+ export type MediaSource = {
4
+ readonly type: 'url';
5
+ readonly url: string;
6
+ } | {
7
+ readonly type: 'base64';
8
+ /** An IANA media type, such as `image/png` or `application/pdf`. */
9
+ readonly mediaType: string;
10
+ readonly data: string;
11
+ } | {
12
+ /** A file in the provider's own storage. Works only with the provider that issued it. */
13
+ readonly type: 'file_id';
14
+ readonly id: string;
15
+ };
16
+ type PartBase = {
17
+ /** Merged into the provider's block for this part. */
18
+ readonly providerOptions?: ProviderFields;
19
+ readonly metadata?: Metadata;
20
+ };
21
+ export type TextPart = PartBase & {
22
+ readonly type: 'text';
23
+ readonly text: string;
24
+ };
25
+ export type ImagePart = PartBase & {
26
+ readonly type: 'image';
27
+ readonly source: MediaSource;
28
+ };
29
+ /** A document, such as a PDF. */
30
+ export type FilePart = PartBase & {
31
+ readonly type: 'file';
32
+ readonly source: MediaSource;
33
+ readonly filename?: string;
34
+ };
35
+ /** Content of user messages and tool results. */
36
+ export type ContentPart = TextPart | ImagePart | FilePart;
37
+ export {};
38
+ //# sourceMappingURL=content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../src/content.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE5D,yCAAyC;AACzC,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAC9C;IACE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,oEAAoE;IACpE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,GACD;IACE,yFAAyF;IACzF,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB,CAAC;AAEN,KAAK,QAAQ,GAAG;IACd,sDAAsD;IACtD,QAAQ,CAAC,eAAe,CAAC,EAAE,cAAc,CAAC;IAC1C,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG;IACjC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B,CAAC;AAEF,iCAAiC;AACjC,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,iDAAiD;AACjD,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC"}
@@ -0,0 +1,5 @@
1
+ // Content shared by every provider: what user messages, system messages and
2
+ // tool results are made of. Small on purpose; anything one provider adds goes
3
+ // in a part's `providerOptions`.
4
+ export {};
5
+ //# sourceMappingURL=content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.js","sourceRoot":"","sources":["../src/content.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,8EAA8E;AAC9E,iCAAiC"}
@@ -0,0 +1,3 @@
1
+ import type { FormatConverter } from './types.js';
2
+ export declare const anthropicConverter: FormatConverter;
3
+ //# sourceMappingURL=anthropic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/convert/anthropic.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAmB,eAAe,EAAE,MAAM,YAAY,CAAC;AA4BnE,eAAO,MAAM,kBAAkB,EAAE,eAiFhC,CAAC"}
@@ -0,0 +1,114 @@
1
+ // The Anthropic Messages format's side of conversion.
2
+ import { isArray, isObject } from '../json.js';
3
+ /** Signed reasoning the target cannot use: dropped, or kept as text. */
4
+ function carryReasoning(text, context) {
5
+ if (context.reasoning === 'drop' || text === '') {
6
+ context.change('dropped', 'reasoning', text === '' ? 'no readable text' : 'bound to its model');
7
+ return undefined;
8
+ }
9
+ context.change('rewritten', 'reasoning', 'as assistant text');
10
+ return { type: 'text', text };
11
+ }
12
+ /** Anthropic takes a call's input only as an object; anything else is wrapped. */
13
+ function toolInput(args, context) {
14
+ try {
15
+ const parsed = JSON.parse(args);
16
+ if (isObject(parsed))
17
+ return parsed;
18
+ }
19
+ catch {
20
+ // Wrapped below.
21
+ }
22
+ context.change('rewritten', 'tool_arguments', 'not a JSON object: wrapped as { arguments }');
23
+ return { arguments: args };
24
+ }
25
+ function string(value) {
26
+ return typeof value === 'string' ? value : '';
27
+ }
28
+ export const anthropicConverter = {
29
+ sameFormat(items, sameProvider, context) {
30
+ const out = [];
31
+ for (const block of items) {
32
+ const type = block['type'];
33
+ // Signed thinking from another model is read by some models and silently
34
+ // ignored by others, so it never moves between models.
35
+ if (type === 'thinking' || type === 'redacted_thinking') {
36
+ const carried = carryReasoning(string(block['thinking']), context);
37
+ if (carried !== undefined)
38
+ out.push(carried);
39
+ }
40
+ else if (sameProvider || type === 'text' || type === 'tool_use') {
41
+ out.push(block);
42
+ }
43
+ else {
44
+ context.change('dropped', 'provider_item', string(type) || 'unknown');
45
+ }
46
+ }
47
+ return out;
48
+ },
49
+ read(items, context) {
50
+ return items.map((block) => {
51
+ switch (block['type']) {
52
+ case 'text': {
53
+ const citations = block['citations'];
54
+ if (isArray(citations) && citations.length > 0) {
55
+ context.change('dropped', 'citations', `${citations.length} citations`);
56
+ }
57
+ return { kind: 'text', text: string(block['text']) };
58
+ }
59
+ case 'thinking':
60
+ return { kind: 'reasoning', text: string(block['thinking']) };
61
+ case 'redacted_thinking':
62
+ return { kind: 'reasoning', text: '' };
63
+ case 'tool_use':
64
+ return {
65
+ kind: 'call',
66
+ id: string(block['id']),
67
+ name: string(block['name']),
68
+ arguments: JSON.stringify(block['input'] ?? {}),
69
+ };
70
+ default:
71
+ return { kind: 'other', type: string(block['type']) || 'unknown' };
72
+ }
73
+ });
74
+ },
75
+ write(items, context) {
76
+ const out = [];
77
+ for (const item of items) {
78
+ switch (item.kind) {
79
+ case 'text':
80
+ // Anthropic refuses empty text blocks.
81
+ if (item.text !== '')
82
+ out.push({ type: 'text', text: item.text });
83
+ break;
84
+ case 'refusal':
85
+ context.change('rewritten', 'refusal', 'as assistant text');
86
+ if (item.text !== '')
87
+ out.push({ type: 'text', text: item.text });
88
+ break;
89
+ case 'reasoning': {
90
+ const carried = carryReasoning(item.text, context);
91
+ if (carried !== undefined)
92
+ out.push(carried);
93
+ break;
94
+ }
95
+ case 'call':
96
+ out.push({
97
+ type: 'tool_use',
98
+ id: context.callId(item.id),
99
+ name: item.name,
100
+ input: toolInput(item.arguments, context),
101
+ });
102
+ break;
103
+ case 'custom_call':
104
+ context.droppedCalls.add(item.id);
105
+ context.change('dropped', 'tool_call', `custom tool ${item.name}`);
106
+ break;
107
+ case 'other':
108
+ context.change('dropped', 'provider_item', item.type);
109
+ }
110
+ }
111
+ return out;
112
+ },
113
+ };
114
+ //# sourceMappingURL=anthropic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/convert/anthropic.ts"],"names":[],"mappings":"AAAA,sDAAsD;AAItD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG/C,wEAAwE;AACxE,SAAS,cAAc,CAAC,IAAY,EAAE,OAAgB;IACpD,IAAI,OAAO,CAAC,SAAS,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;QAChD,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW,EAAE,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC;QAChG,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,WAAW,EAAE,mBAAmB,CAAC,CAAC;IAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAChC,CAAC;AAED,kFAAkF;AAClF,SAAS,SAAS,CAAC,IAAY,EAAE,OAAgB;IAC/C,IAAI,CAAC;QACH,MAAM,MAAM,GAAS,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,QAAQ,CAAC,MAAM,CAAC;YAAE,OAAO,MAAM,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,iBAAiB;IACnB,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,gBAAgB,EAAE,6CAA6C,CAAC,CAAC;IAC7F,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAC7B,CAAC;AAED,SAAS,MAAM,CAAC,KAAuB;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAChD,CAAC;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAoB;IACjD,UAAU,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO;QACrC,MAAM,GAAG,GAAiB,EAAE,CAAC;QAC7B,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;YAC3B,yEAAyE;YACzE,uDAAuD;YACvD,IAAI,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,mBAAmB,EAAE,CAAC;gBACxD,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;gBACnE,IAAI,OAAO,KAAK,SAAS;oBAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC/C,CAAC;iBAAM,IAAI,YAAY,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;gBAClE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,CAAC;YACxE,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,IAAI,CAAC,KAAK,EAAE,OAAO;QACjB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAU,EAAE;YACjC,QAAQ,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;gBACtB,KAAK,MAAM,CAAC,CAAC,CAAC;oBACZ,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC;oBACrC,IAAI,OAAO,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC/C,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC,MAAM,YAAY,CAAC,CAAC;oBAC1E,CAAC;oBACD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;gBACvD,CAAC;gBACD,KAAK,UAAU;oBACb,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;gBAChE,KAAK,mBAAmB;oBACtB,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;gBACzC,KAAK,UAAU;oBACb,OAAO;wBACL,IAAI,EAAE,MAAM;wBACZ,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;wBACvB,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;wBAC3B,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;qBAChD,CAAC;gBACJ;oBACE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC;YACvE,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK,EAAE,OAAO;QAClB,MAAM,GAAG,GAAiB,EAAE,CAAC;QAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;gBAClB,KAAK,MAAM;oBACT,uCAAuC;oBACvC,IAAI,IAAI,CAAC,IAAI,KAAK,EAAE;wBAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;oBAClE,MAAM;gBACR,KAAK,SAAS;oBACZ,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,SAAS,EAAE,mBAAmB,CAAC,CAAC;oBAC5D,IAAI,IAAI,CAAC,IAAI,KAAK,EAAE;wBAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;oBAClE,MAAM;gBACR,KAAK,WAAW,CAAC,CAAC,CAAC;oBACjB,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;oBACnD,IAAI,OAAO,KAAK,SAAS;wBAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBAC7C,MAAM;gBACR,CAAC;gBACD,KAAK,MAAM;oBACT,GAAG,CAAC,IAAI,CAAC;wBACP,IAAI,EAAE,UAAU;wBAChB,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;wBAC3B,IAAI,EAAE,IAAI,CAAC,IAAI;wBACf,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC;qBAC1C,CAAC,CAAC;oBACH,MAAM;gBACR,KAAK,aAAa;oBAChB,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBAClC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW,EAAE,eAAe,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;oBACnE,MAAM;gBACR,KAAK,OAAO;oBACV,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;CACF,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { Message } from '../messages.js';
2
+ import type { Provider } from '../providers.js';
3
+ import type { Conversion, ConvertOptions, ConvertTarget } from './types.js';
4
+ export type { Conversion, ConversionChange, ConvertOptions, ConvertTarget } from './types.js';
5
+ /**
6
+ * The conversation, ready to send to `to.provider` and `to.model`, with every
7
+ * change made to get it. Messages that already fit the target come back
8
+ * unchanged, and the application's `custom` messages are kept. Conversion
9
+ * loses things, so keep the original and convert it each time.
10
+ */
11
+ export declare function convert<P extends Provider>(messages: readonly Message[], to: ConvertTarget<P>, options?: ConvertOptions): Conversion<Message<P>>;
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/convert/index.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAoB,OAAO,EAAqB,MAAM,gBAAgB,CAAC;AACnF,OAAO,KAAK,EAAa,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAG3D,OAAO,KAAK,EAGV,UAAU,EAEV,cAAc,EACd,aAAa,EAGd,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAkD9F;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,QAAQ,EACxC,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC,EACpB,OAAO,GAAE,cAAmB,GAC3B,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CA8BxB"}
@@ -0,0 +1,221 @@
1
+ // Moving a conversation to another provider or model. Pure.
2
+ //
3
+ // Assistant and native messages are the only ones that belong to a provider.
4
+ // An assistant message from the target's own provider and model is kept as it
5
+ // is. One from another provider or model in the same API format is filtered.
6
+ // Any other is read into a common form and written in the target's format.
7
+ // Shared messages keep their shape, less what the target cannot take.
8
+ import { anthropicConverter } from './anthropic.js';
9
+ import { responsesConverter } from './responses.js';
10
+ /** What each provider takes. A new provider fails to compile until it is here. */
11
+ const CAPABILITIES = {
12
+ anthropic: {
13
+ api: 'anthropic-messages',
14
+ customTools: false,
15
+ files: true,
16
+ fileIds: true,
17
+ plainReasoning: false,
18
+ },
19
+ // OpenAI takes reasoning items with only text, and ignores them.
20
+ openai: {
21
+ api: 'openai-responses',
22
+ customTools: true,
23
+ files: true,
24
+ fileIds: true,
25
+ plainReasoning: false,
26
+ },
27
+ // Fireworks drops file parts without an error, has no file storage, and
28
+ // takes custom tools its models never call.
29
+ fireworks: {
30
+ api: 'openai-responses',
31
+ customTools: false,
32
+ files: false,
33
+ fileIds: false,
34
+ plainReasoning: true,
35
+ },
36
+ };
37
+ /**
38
+ * The fields each provider reads in `providerOptions` on shared parts and tool
39
+ * results. A field other providers own and the target does not is dropped;
40
+ * one nobody owns is kept. Nothing is translated: where cache breakpoints go
41
+ * is a choice for each request, and providers place and limit them differently.
42
+ */
43
+ const PART_OPTIONS = {
44
+ anthropic: ['cache_control', 'citations', 'context', 'title', 'transformations', 'toolset_name'],
45
+ openai: ['detail', 'prompt_cache_breakpoint', 'caller', 'namespace'],
46
+ fireworks: ['detail'],
47
+ };
48
+ const FORMATS = {
49
+ 'openai-responses': responsesConverter,
50
+ 'anthropic-messages': anthropicConverter,
51
+ };
52
+ /** The IDs Anthropic takes for tool calls. Other formats take any string. */
53
+ const ANTHROPIC_CALL_ID = /^[a-zA-Z0-9_-]+$/;
54
+ /**
55
+ * The conversation, ready to send to `to.provider` and `to.model`, with every
56
+ * change made to get it. Messages that already fit the target come back
57
+ * unchanged, and the application's `custom` messages are kept. Conversion
58
+ * loses things, so keep the original and convert it each time.
59
+ */
60
+ export function convert(messages, to, options = {}) {
61
+ const target = { ...CAPABILITIES[to.provider], provider: to.provider, model: to.model };
62
+ const changes = [];
63
+ const rewritten = new Set();
64
+ let index = 0;
65
+ const context = {
66
+ target,
67
+ reasoning: options.reasoning ?? 'drop',
68
+ droppedCalls: new Set(),
69
+ change(action, what, detail) {
70
+ changes.push({ index, action, what, detail });
71
+ },
72
+ callId(id) {
73
+ if (target.api !== 'anthropic-messages' || ANTHROPIC_CALL_ID.test(id))
74
+ return id;
75
+ const mapped = `${id.replaceAll(/[^a-zA-Z0-9_-]/g, '_')}_${hash(id)}`;
76
+ // Reported once, where the call is: its result follows the same mapping.
77
+ if (!rewritten.has(id))
78
+ context.change('rewritten', 'tool_call_id', `${id} → ${mapped}`);
79
+ rewritten.add(id);
80
+ return mapped;
81
+ },
82
+ };
83
+ const foreign = foreignOptions(to.provider);
84
+ const out = [];
85
+ for (const [at, message] of messages.entries()) {
86
+ index = at;
87
+ const converted = convertMessage(message, context, foreign);
88
+ if (converted !== undefined)
89
+ out.push(converted);
90
+ }
91
+ return { messages: forProvider(out), changes };
92
+ }
93
+ function convertMessage(message, context, foreign) {
94
+ switch (message.role) {
95
+ case 'custom':
96
+ return message;
97
+ case 'assistant':
98
+ return convertAssistant(message, context);
99
+ case 'native':
100
+ if (message.provider === context.target.provider)
101
+ return message;
102
+ context.change('dropped', 'message', `${message.provider} native items`);
103
+ return undefined;
104
+ case 'tool_result':
105
+ return convertToolResult(message, context, foreign);
106
+ case 'user': {
107
+ const content = parts(message.content, context, foreign);
108
+ if (content.length > 0)
109
+ return { ...message, content };
110
+ context.change('dropped', 'message', 'user message left empty');
111
+ return undefined;
112
+ }
113
+ case 'system': {
114
+ const content = parts(message.content, context, foreign);
115
+ if (content.length > 0)
116
+ return { ...message, content };
117
+ context.change('dropped', 'message', 'system message left empty');
118
+ return undefined;
119
+ }
120
+ }
121
+ }
122
+ function convertAssistant(message, context) {
123
+ const { target } = context;
124
+ const sameProvider = message.provider === target.provider;
125
+ if (sameProvider && message.model === target.model)
126
+ return message;
127
+ const items = message.content;
128
+ const content = message.api === target.api
129
+ ? FORMATS[message.api].sameFormat(items, sameProvider, context)
130
+ : FORMATS[target.api].write(FORMATS[message.api].read(items, context), context);
131
+ if (content.length === 0) {
132
+ context.change('dropped', 'message', 'assistant message left empty');
133
+ return undefined;
134
+ }
135
+ // A response ID belongs to the provider that answered.
136
+ const { id, ...rest } = message;
137
+ return assistant({
138
+ ...rest,
139
+ ...(sameProvider && id !== undefined ? { id } : {}),
140
+ provider: target.provider,
141
+ api: target.api,
142
+ model: target.model,
143
+ content,
144
+ });
145
+ }
146
+ function convertToolResult(message, context, foreign) {
147
+ if (context.droppedCalls.has(message.toolCallId)) {
148
+ context.change('dropped', 'tool_result', `answers dropped call ${message.toolCallId}`);
149
+ return undefined;
150
+ }
151
+ const { providerOptions, ...rest } = message;
152
+ const fields = keptOptions(providerOptions, context, foreign);
153
+ return {
154
+ ...rest,
155
+ toolCallId: context.callId(message.toolCallId),
156
+ content: parts(message.content, context, foreign),
157
+ ...(fields === undefined ? {} : { providerOptions: fields }),
158
+ };
159
+ }
160
+ function parts(content, context, foreign) {
161
+ const { target } = context;
162
+ return content.flatMap((part) => {
163
+ if (part.type === 'file' && !target.files) {
164
+ context.change('dropped', 'part', `file part: ${target.provider} takes no files`);
165
+ return [];
166
+ }
167
+ if (part.type !== 'text' && part.source.type === 'file_id' && !target.fileIds) {
168
+ context.change('dropped', 'part', `${part.type} by file ID: ${target.provider} takes none`);
169
+ return [];
170
+ }
171
+ if (part.providerOptions === undefined)
172
+ return [part];
173
+ const fields = keptOptions(part.providerOptions, context, foreign);
174
+ return [fields === undefined ? withoutOptions(part) : { ...part, providerOptions: fields }];
175
+ });
176
+ }
177
+ function withoutOptions(part) {
178
+ const { providerOptions: _providerOptions, ...rest } = part;
179
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion
180
+ return rest;
181
+ }
182
+ /** `providerOptions` without other providers' fields, or undefined when none are left. */
183
+ function keptOptions(value, context, foreign) {
184
+ if (value === undefined)
185
+ return undefined;
186
+ const kept = Object.fromEntries(Object.entries(value).filter(([key]) => {
187
+ if (!foreign.has(key))
188
+ return true;
189
+ context.change('dropped', 'part_option', key);
190
+ return false;
191
+ }));
192
+ return Object.keys(kept).length > 0 ? kept : undefined;
193
+ }
194
+ /** Fields other providers own that `provider` does not. */
195
+ function foreignOptions(provider) {
196
+ const own = new Set(PART_OPTIONS[provider]);
197
+ return new Set(Object.entries(PART_OPTIONS)
198
+ .filter(([other]) => other !== provider)
199
+ .flatMap(([, keys]) => keys)
200
+ .filter((key) => !own.has(key)));
201
+ }
202
+ /** A converted assistant message: its items are the target format's, written above. */
203
+ function assistant(message) {
204
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion
205
+ return message;
206
+ }
207
+ /** The converted messages, every one now for provider `P`. */
208
+ function forProvider(messages) {
209
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion
210
+ return messages;
211
+ }
212
+ /** FNV-1a in base 36: a short, stable suffix that keeps rewritten IDs apart. */
213
+ function hash(text) {
214
+ let value = 0x811c9dc5;
215
+ for (let at = 0; at < text.length; at += 1) {
216
+ value ^= text.charCodeAt(at);
217
+ value = Math.imul(value, 0x01000193) >>> 0;
218
+ }
219
+ return value.toString(36);
220
+ }
221
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/convert/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { FormatConverter } from './types.js';
2
+ export declare const responsesConverter: FormatConverter;
3
+ //# sourceMappingURL=responses.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../src/convert/responses.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAmB,eAAe,EAAE,MAAM,YAAY,CAAC;AAgDnE,eAAO,MAAM,kBAAkB,EAAE,eAqJhC,CAAC"}