@opencode/ai 0.0.0-reserved → 2.0.1

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 (288) hide show
  1. package/README.md +879 -2
  2. package/dist/cache-policy.d.ts +2 -0
  3. package/dist/cache-policy.js +129 -0
  4. package/dist/image-client.d.ts +19 -0
  5. package/dist/image-client.js +28 -0
  6. package/dist/image.d.ts +110 -0
  7. package/dist/image.js +103 -0
  8. package/dist/index.d.ts +18 -0
  9. package/dist/index.js +12 -0
  10. package/dist/llm.d.ts +252 -0
  11. package/dist/llm.js +74 -0
  12. package/dist/protocols/alibaba-chat.d.ts +225 -0
  13. package/dist/protocols/alibaba-chat.js +75 -0
  14. package/dist/protocols/alibaba-messages.d.ts +350 -0
  15. package/dist/protocols/alibaba-messages.js +40 -0
  16. package/dist/protocols/alibaba-responses.d.ts +255 -0
  17. package/dist/protocols/alibaba-responses.js +80 -0
  18. package/dist/protocols/anthropic-messages.d.ts +980 -0
  19. package/dist/protocols/anthropic-messages.js +1460 -0
  20. package/dist/protocols/bedrock-converse.d.ts +499 -0
  21. package/dist/protocols/bedrock-converse.js +643 -0
  22. package/dist/protocols/bedrock-event-stream.d.ts +9 -0
  23. package/dist/protocols/bedrock-event-stream.js +97 -0
  24. package/dist/protocols/gemini.d.ts +285 -0
  25. package/dist/protocols/gemini.js +671 -0
  26. package/dist/protocols/google-images.d.ts +30 -0
  27. package/dist/protocols/google-images.js +181 -0
  28. package/dist/protocols/index.d.ts +12 -0
  29. package/dist/protocols/index.js +12 -0
  30. package/dist/protocols/meta-images.d.ts +26 -0
  31. package/dist/protocols/meta-images.js +89 -0
  32. package/dist/protocols/meta-messages.d.ts +356 -0
  33. package/dist/protocols/meta-messages.js +41 -0
  34. package/dist/protocols/meta-responses.d.ts +473 -0
  35. package/dist/protocols/meta-responses.js +173 -0
  36. package/dist/protocols/mistral-chat.d.ts +540 -0
  37. package/dist/protocols/mistral-chat.js +624 -0
  38. package/dist/protocols/open-responses-channel.d.ts +25 -0
  39. package/dist/protocols/open-responses-channel.js +141 -0
  40. package/dist/protocols/open-responses-continuation.d.ts +16 -0
  41. package/dist/protocols/open-responses-continuation.js +170 -0
  42. package/dist/protocols/open-responses.d.ts +1715 -0
  43. package/dist/protocols/open-responses.js +1228 -0
  44. package/dist/protocols/openai-chat.d.ts +860 -0
  45. package/dist/protocols/openai-chat.js +966 -0
  46. package/dist/protocols/openai-compatible-chat.d.ts +109 -0
  47. package/dist/protocols/openai-compatible-chat.js +19 -0
  48. package/dist/protocols/openai-compatible-responses.d.ts +172 -0
  49. package/dist/protocols/openai-compatible-responses.js +18 -0
  50. package/dist/protocols/openai-images.d.ts +32 -0
  51. package/dist/protocols/openai-images.js +183 -0
  52. package/dist/protocols/openai-responses.d.ts +1389 -0
  53. package/dist/protocols/openai-responses.js +260 -0
  54. package/dist/protocols/shared.d.ts +193 -0
  55. package/dist/protocols/shared.js +290 -0
  56. package/dist/protocols/utils/bedrock-auth.d.ts +60 -0
  57. package/dist/protocols/utils/bedrock-auth.js +85 -0
  58. package/dist/protocols/utils/bedrock-cache.d.ts +19 -0
  59. package/dist/protocols/utils/bedrock-cache.js +49 -0
  60. package/dist/protocols/utils/bedrock-media.d.ts +55 -0
  61. package/dist/protocols/utils/bedrock-media.js +73 -0
  62. package/dist/protocols/utils/cache.d.ts +6 -0
  63. package/dist/protocols/utils/cache.js +5 -0
  64. package/dist/protocols/utils/gemini-tool-schema.d.ts +2 -0
  65. package/dist/protocols/utils/gemini-tool-schema.js +103 -0
  66. package/dist/protocols/utils/image-input.d.ts +21 -0
  67. package/dist/protocols/utils/image-input.js +20 -0
  68. package/dist/protocols/utils/lifecycle.d.ts +24 -0
  69. package/dist/protocols/utils/lifecycle.js +72 -0
  70. package/dist/protocols/utils/meta-image.d.ts +2 -0
  71. package/dist/protocols/utils/meta-image.js +13 -0
  72. package/dist/protocols/utils/open-responses-options.d.ts +56 -0
  73. package/dist/protocols/utils/open-responses-options.js +61 -0
  74. package/dist/protocols/utils/openai-image.d.ts +5 -0
  75. package/dist/protocols/utils/openai-image.js +18 -0
  76. package/dist/protocols/utils/openai-options.d.ts +16 -0
  77. package/dist/protocols/utils/openai-options.js +14 -0
  78. package/dist/protocols/utils/partial-json-options.d.ts +62 -0
  79. package/dist/protocols/utils/partial-json-options.js +52 -0
  80. package/dist/protocols/utils/partial-json.d.ts +8 -0
  81. package/dist/protocols/utils/partial-json.js +279 -0
  82. package/dist/protocols/utils/responses-checkpoint.d.ts +4 -0
  83. package/dist/protocols/utils/responses-checkpoint.js +107 -0
  84. package/dist/protocols/utils/responses-compaction.d.ts +4 -0
  85. package/dist/protocols/utils/responses-compaction.js +129 -0
  86. package/dist/protocols/utils/responses-hosted-tools.d.ts +26 -0
  87. package/dist/protocols/utils/responses-hosted-tools.js +32 -0
  88. package/dist/protocols/utils/tool-schema.d.ts +8 -0
  89. package/dist/protocols/utils/tool-schema.js +54 -0
  90. package/dist/protocols/utils/tool-stream.d.ts +710 -0
  91. package/dist/protocols/utils/tool-stream.js +155 -0
  92. package/dist/protocols/xai-images.d.ts +26 -0
  93. package/dist/protocols/xai-images.js +106 -0
  94. package/dist/protocols/xai-responses.d.ts +250 -0
  95. package/dist/protocols/xai-responses.js +81 -0
  96. package/dist/protocols/zai-chat.d.ts +202 -0
  97. package/dist/protocols/zai-chat.js +49 -0
  98. package/dist/protocols/zai-images.d.ts +22 -0
  99. package/dist/protocols/zai-images.js +79 -0
  100. package/dist/protocols/zai-messages.d.ts +344 -0
  101. package/dist/protocols/zai-messages.js +27 -0
  102. package/dist/protocols.d.ts +1 -0
  103. package/dist/protocols.js +1 -0
  104. package/dist/provider-error.d.ts +15 -0
  105. package/dist/provider-error.js +125 -0
  106. package/dist/provider-package.d.ts +15 -0
  107. package/dist/provider-package.js +1 -0
  108. package/dist/provider.d.ts +23 -0
  109. package/dist/provider.js +2 -0
  110. package/dist/providers/alibaba/chat.d.ts +1 -0
  111. package/dist/providers/alibaba/chat.js +1 -0
  112. package/dist/providers/alibaba/messages.d.ts +3 -0
  113. package/dist/providers/alibaba/messages.js +1 -0
  114. package/dist/providers/alibaba/responses.d.ts +3 -0
  115. package/dist/providers/alibaba/responses.js +1 -0
  116. package/dist/providers/alibaba.d.ts +711 -0
  117. package/dist/providers/alibaba.js +94 -0
  118. package/dist/providers/amazon-bedrock/mantle/chat.d.ts +2 -0
  119. package/dist/providers/amazon-bedrock/mantle/chat.js +1 -0
  120. package/dist/providers/amazon-bedrock/mantle/responses.d.ts +2 -0
  121. package/dist/providers/amazon-bedrock/mantle/responses.js +1 -0
  122. package/dist/providers/amazon-bedrock/mantle.d.ts +2 -0
  123. package/dist/providers/amazon-bedrock/mantle.js +1 -0
  124. package/dist/providers/amazon-bedrock-mantle.d.ts +313 -0
  125. package/dist/providers/amazon-bedrock-mantle.js +79 -0
  126. package/dist/providers/amazon-bedrock.d.ts +173 -0
  127. package/dist/providers/amazon-bedrock.js +41 -0
  128. package/dist/providers/anthropic-compatible.d.ts +309 -0
  129. package/dist/providers/anthropic-compatible.js +50 -0
  130. package/dist/providers/anthropic.d.ts +307 -0
  131. package/dist/providers/anthropic.js +42 -0
  132. package/dist/providers/azure/chat.d.ts +2 -0
  133. package/dist/providers/azure/chat.js +1 -0
  134. package/dist/providers/azure/responses.d.ts +2 -0
  135. package/dist/providers/azure/responses.js +1 -0
  136. package/dist/providers/azure.d.ts +598 -0
  137. package/dist/providers/azure.js +115 -0
  138. package/dist/providers/baseten.d.ts +228 -0
  139. package/dist/providers/baseten.js +38 -0
  140. package/dist/providers/cerebras.d.ts +227 -0
  141. package/dist/providers/cerebras.js +40 -0
  142. package/dist/providers/cloudflare-ai-gateway.d.ts +237 -0
  143. package/dist/providers/cloudflare-ai-gateway.js +65 -0
  144. package/dist/providers/cloudflare-workers-ai.d.ts +231 -0
  145. package/dist/providers/cloudflare-workers-ai.js +51 -0
  146. package/dist/providers/deepinfra.d.ts +227 -0
  147. package/dist/providers/deepinfra.js +43 -0
  148. package/dist/providers/deepseek.d.ts +228 -0
  149. package/dist/providers/deepseek.js +41 -0
  150. package/dist/providers/fireworks.d.ts +228 -0
  151. package/dist/providers/fireworks.js +38 -0
  152. package/dist/providers/google-vertex/chat.d.ts +2 -0
  153. package/dist/providers/google-vertex/chat.js +1 -0
  154. package/dist/providers/google-vertex/gemini.d.ts +2 -0
  155. package/dist/providers/google-vertex/gemini.js +1 -0
  156. package/dist/providers/google-vertex/messages.d.ts +2 -0
  157. package/dist/providers/google-vertex/messages.js +1 -0
  158. package/dist/providers/google-vertex/responses.d.ts +2 -0
  159. package/dist/providers/google-vertex/responses.js +1 -0
  160. package/dist/providers/google-vertex-chat.d.ts +132 -0
  161. package/dist/providers/google-vertex-chat.js +55 -0
  162. package/dist/providers/google-vertex-messages.d.ts +306 -0
  163. package/dist/providers/google-vertex-messages.js +75 -0
  164. package/dist/providers/google-vertex-responses.d.ts +197 -0
  165. package/dist/providers/google-vertex-responses.js +56 -0
  166. package/dist/providers/google-vertex-shared.d.ts +22 -0
  167. package/dist/providers/google-vertex-shared.js +72 -0
  168. package/dist/providers/google-vertex.d.ts +119 -0
  169. package/dist/providers/google-vertex.js +98 -0
  170. package/dist/providers/google.d.ts +114 -0
  171. package/dist/providers/google.js +42 -0
  172. package/dist/providers/groq.d.ts +314 -0
  173. package/dist/providers/groq.js +81 -0
  174. package/dist/providers/index.d.ts +31 -0
  175. package/dist/providers/index.js +31 -0
  176. package/dist/providers/meta/chat.d.ts +2 -0
  177. package/dist/providers/meta/chat.js +1 -0
  178. package/dist/providers/meta/messages.d.ts +2 -0
  179. package/dist/providers/meta/messages.js +1 -0
  180. package/dist/providers/meta/responses.d.ts +2 -0
  181. package/dist/providers/meta/responses.js +1 -0
  182. package/dist/providers/meta.d.ts +636 -0
  183. package/dist/providers/meta.js +113 -0
  184. package/dist/providers/minimax/chat.d.ts +4 -0
  185. package/dist/providers/minimax/chat.js +8 -0
  186. package/dist/providers/minimax/messages.d.ts +1 -0
  187. package/dist/providers/minimax/messages.js +1 -0
  188. package/dist/providers/minimax/responses.d.ts +4 -0
  189. package/dist/providers/minimax/responses.js +8 -0
  190. package/dist/providers/minimax.d.ts +598 -0
  191. package/dist/providers/minimax.js +89 -0
  192. package/dist/providers/mistral.d.ts +207 -0
  193. package/dist/providers/mistral.js +28 -0
  194. package/dist/providers/moonshot/chat.d.ts +1 -0
  195. package/dist/providers/moonshot/chat.js +1 -0
  196. package/dist/providers/moonshot/messages.d.ts +4 -0
  197. package/dist/providers/moonshot/messages.js +8 -0
  198. package/dist/providers/moonshot/responses.d.ts +4 -0
  199. package/dist/providers/moonshot/responses.js +8 -0
  200. package/dist/providers/moonshot.d.ts +596 -0
  201. package/dist/providers/moonshot.js +90 -0
  202. package/dist/providers/open-responses-options.d.ts +6 -0
  203. package/dist/providers/open-responses-options.js +1 -0
  204. package/dist/providers/openai/chat.d.ts +2 -0
  205. package/dist/providers/openai/chat.js +1 -0
  206. package/dist/providers/openai/responses.d.ts +2 -0
  207. package/dist/providers/openai/responses.js +1 -0
  208. package/dist/providers/openai-compatible/responses.d.ts +1 -0
  209. package/dist/providers/openai-compatible/responses.js +1 -0
  210. package/dist/providers/openai-compatible-responses.d.ts +195 -0
  211. package/dist/providers/openai-compatible-responses.js +32 -0
  212. package/dist/providers/openai-compatible.d.ts +130 -0
  213. package/dist/providers/openai-compatible.js +33 -0
  214. package/dist/providers/openai-options.d.ts +26 -0
  215. package/dist/providers/openai-options.js +41 -0
  216. package/dist/providers/openai.d.ts +404 -0
  217. package/dist/providers/openai.js +82 -0
  218. package/dist/providers/openrouter.d.ts +563 -0
  219. package/dist/providers/openrouter.js +114 -0
  220. package/dist/providers/togetherai.d.ts +227 -0
  221. package/dist/providers/togetherai.js +40 -0
  222. package/dist/providers/xai.d.ts +163 -0
  223. package/dist/providers/xai.js +88 -0
  224. package/dist/providers/zai/chat.d.ts +1 -0
  225. package/dist/providers/zai/chat.js +1 -0
  226. package/dist/providers/zai-coding-plan/chat.d.ts +1 -0
  227. package/dist/providers/zai-coding-plan/chat.js +1 -0
  228. package/dist/providers/zai-coding-plan/messages.d.ts +4 -0
  229. package/dist/providers/zai-coding-plan/messages.js +8 -0
  230. package/dist/providers/zai-coding-plan/responses.d.ts +4 -0
  231. package/dist/providers/zai-coding-plan/responses.js +8 -0
  232. package/dist/providers/zai-coding-plan.d.ts +577 -0
  233. package/dist/providers/zai-coding-plan.js +63 -0
  234. package/dist/providers/zai.d.ts +149 -0
  235. package/dist/providers/zai.js +53 -0
  236. package/dist/providers.d.ts +1 -0
  237. package/dist/providers.js +1 -0
  238. package/dist/route/auth-options.d.ts +34 -0
  239. package/dist/route/auth-options.js +14 -0
  240. package/dist/route/auth.d.ts +51 -0
  241. package/dist/route/auth.js +87 -0
  242. package/dist/route/client.d.ts +430 -0
  243. package/dist/route/client.js +307 -0
  244. package/dist/route/endpoint.d.ts +28 -0
  245. package/dist/route/endpoint.js +21 -0
  246. package/dist/route/executor.d.ts +27 -0
  247. package/dist/route/executor.js +183 -0
  248. package/dist/route/framing.d.ts +29 -0
  249. package/dist/route/framing.js +14 -0
  250. package/dist/route/index.d.ts +16 -0
  251. package/dist/route/index.js +9 -0
  252. package/dist/route/protocol.d.ts +76 -0
  253. package/dist/route/protocol.js +16 -0
  254. package/dist/route/transport/http.d.ts +34 -0
  255. package/dist/route/transport/http.js +68 -0
  256. package/dist/route/transport/index.d.ts +41 -0
  257. package/dist/route/transport/index.js +4 -0
  258. package/dist/route/transport/websocket-channel.d.ts +57 -0
  259. package/dist/route/transport/websocket-channel.js +1 -0
  260. package/dist/route/transport/websocket.d.ts +56 -0
  261. package/dist/route/transport/websocket.js +370 -0
  262. package/dist/route.d.ts +1 -0
  263. package/dist/route.js +1 -0
  264. package/dist/schema/errors.d.ts +170 -0
  265. package/dist/schema/errors.js +131 -0
  266. package/dist/schema/events.d.ts +8123 -0
  267. package/dist/schema/events.js +550 -0
  268. package/dist/schema/ids.d.ts +17 -0
  269. package/dist/schema/ids.js +10 -0
  270. package/dist/schema/index.d.ts +5 -0
  271. package/dist/schema/index.js +5 -0
  272. package/dist/schema/messages.d.ts +646 -0
  273. package/dist/schema/messages.js +301 -0
  274. package/dist/schema/options.d.ts +159 -0
  275. package/dist/schema/options.js +189 -0
  276. package/dist/testing.d.ts +1693 -0
  277. package/dist/testing.js +129 -0
  278. package/dist/tool-history.d.ts +2 -0
  279. package/dist/tool-history.js +84 -0
  280. package/dist/tool-runtime.d.ts +15 -0
  281. package/dist/tool-runtime.js +62 -0
  282. package/dist/tool.d.ts +136 -0
  283. package/dist/tool.js +66 -0
  284. package/dist/utils/record.d.ts +2 -0
  285. package/dist/utils/record.js +2 -0
  286. package/dist/utils/sanitize.d.ts +1 -0
  287. package/dist/utils/sanitize.js +12 -0
  288. package/package.json +43 -10
@@ -0,0 +1,76 @@
1
+ import { Schema, type Effect } from "effect";
2
+ import type { AIError, LLMEvent, LLMRequest, ProtocolID } from "../schema/index.js";
3
+ /**
4
+ * The semantic API contract of one model server family.
5
+ *
6
+ * A `Protocol` owns the parts of a route that are intrinsic to "what does
7
+ * this API look like": how a common `LLMRequest` becomes a provider-native
8
+ * body, what schema that body must satisfy before it is JSON-encoded, and
9
+ * how the streaming response decodes back into common `LLMEvent`s.
10
+ *
11
+ * Examples:
12
+ *
13
+ * - `OpenAIChat.protocol` — chat completions style
14
+ * - `OpenResponses.protocol` — provider-neutral Responses API baseline
15
+ * - `OpenAIResponses.protocol` — OpenAI extensions to that baseline
16
+ * - `AnthropicMessages.protocol` — messages API with content blocks
17
+ * - `Gemini.protocol` — generateContent
18
+ * - `BedrockConverse.protocol` — Converse with binary event-stream framing
19
+ *
20
+ * A `Protocol` is **not** a deployment. It does not know which URL, which
21
+ * headers, or which auth scheme to use. Those are deployment concerns owned
22
+ * by `Route.make(...)` along with the chosen `Endpoint`, `Auth`,
23
+ * and `Framing`. This separation is what lets DeepSeek, TogetherAI, Cerebras,
24
+ * etc. all reuse `OpenAIChat.protocol` without forking 300 lines per provider.
25
+ *
26
+ * The four type parameters reflect the pipeline:
27
+ *
28
+ * - `Body` — provider-native request body candidate. `Route.make(...)`
29
+ * validates and JSON-encodes it with `body.schema`.
30
+ * - `Frame` — one unit of the framed response stream. SSE: a JSON data
31
+ * string. AWS event stream: a parsed binary frame.
32
+ * - `Event` — schema-decoded provider event produced from one frame.
33
+ * - `State` — accumulator threaded through `stream.step` to translate event
34
+ * sequences into `LLMEvent` sequences.
35
+ */
36
+ export interface Protocol<Body, Frame, Event, State> {
37
+ /** Stable id for the wire protocol implementation. */
38
+ readonly id: ProtocolID;
39
+ /** Request side: schema for the provider-native body and how to build it. */
40
+ readonly body: ProtocolBody<Body>;
41
+ /** Response side: streaming state machine. */
42
+ readonly stream: ProtocolStream<Frame, Event, State>;
43
+ }
44
+ export interface ProtocolBody<Body> {
45
+ /** Schema for the validated provider-native body sent as the JSON request. */
46
+ readonly schema: Schema.Codec<Body, unknown>;
47
+ /** Build the provider-native body from a common `LLMRequest`. */
48
+ readonly from: (request: LLMRequest) => Effect.Effect<Body, AIError>;
49
+ }
50
+ export interface ProtocolStream<Frame, Event, State> {
51
+ /** Schema for one decoded streaming event, decoded from a transport frame. */
52
+ readonly event: Schema.Codec<Event, Frame>;
53
+ /** Initial parser state. Called once per response with the resolved request. */
54
+ readonly initial: (request: LLMRequest) => State;
55
+ /** Translate one event into emitted `LLMEvent`s plus the next state. */
56
+ readonly step: (state: State, event: Event) => Effect.Effect<readonly [State, ReadonlyArray<LLMEvent>], AIError>;
57
+ /** Optional request-completion signal for transports that do not end naturally. */
58
+ readonly terminal?: (event: Event) => boolean;
59
+ /** Optional effectful flush emitted when the framed stream ends. */
60
+ readonly onHalt?: (state: State) => Effect.Effect<ReadonlyArray<LLMEvent>, AIError>;
61
+ }
62
+ /**
63
+ * Construct a `Protocol` from its body and stream pieces:
64
+ *
65
+ * - `body.schema` infers the provider-native request body shape.
66
+ * - `body.from` ties the common `LLMRequest` to the provider body.
67
+ * - `stream.event` infers the decoded streaming event and the wire frame.
68
+ * - `stream.initial`, `stream.step`, and `stream.onHalt` infer the parser state.
69
+ *
70
+ * Provider implementations should usually call `Protocol.make({ ... })`
71
+ * without explicit type arguments; the schemas and parser functions are the
72
+ * source of truth.
73
+ */
74
+ export declare const make: <Body, Frame, Event, State>(input: Protocol<Body, Frame, Event, State>) => Protocol<Body, Frame, Event, State>;
75
+ export declare const jsonEvent: <const S extends Schema.Top>(schema: S) => Schema.fromJsonString<S>;
76
+ export * as Protocol from "./protocol.js";
@@ -0,0 +1,16 @@
1
+ import { Schema } from "effect";
2
+ /**
3
+ * Construct a `Protocol` from its body and stream pieces:
4
+ *
5
+ * - `body.schema` infers the provider-native request body shape.
6
+ * - `body.from` ties the common `LLMRequest` to the provider body.
7
+ * - `stream.event` infers the decoded streaming event and the wire frame.
8
+ * - `stream.initial`, `stream.step`, and `stream.onHalt` infer the parser state.
9
+ *
10
+ * Provider implementations should usually call `Protocol.make({ ... })`
11
+ * without explicit type arguments; the schemas and parser functions are the
12
+ * source of truth.
13
+ */
14
+ export const make = (input) => input;
15
+ export const jsonEvent = (schema) => Schema.fromJsonString(schema);
16
+ export * as Protocol from "./protocol.js";
@@ -0,0 +1,34 @@
1
+ import { Effect } from "effect";
2
+ import { Headers, HttpClientRequest } from "effect/unstable/http";
3
+ import { Framing } from "../framing.js";
4
+ import type { HttpMiddleware, Transport, TransportPrepareInput } from "./index.js";
5
+ export type JsonRequestInput<Body> = TransportPrepareInput<Body>;
6
+ export interface JsonRequestParts<Body = unknown> {
7
+ readonly url: string;
8
+ readonly jsonBody: Body | Record<string, unknown>;
9
+ readonly bodyText: string;
10
+ readonly headers: Headers.Headers;
11
+ }
12
+ export interface HttpPrepared<Frame> {
13
+ readonly request: HttpClientRequest.HttpClientRequest;
14
+ readonly framing: Framing.Definition<Frame>;
15
+ readonly middleware?: HttpMiddleware;
16
+ }
17
+ export declare const jsonRequestParts: <Body>(input: JsonRequestInput<Body>) => Effect.Effect<{
18
+ url: string;
19
+ jsonBody: Record<string, unknown> | Body;
20
+ bodyText: string;
21
+ headers: Headers.Headers;
22
+ }, import("../../schema/errors.js").AIError, never>;
23
+ export interface HttpJsonInput<_Body, Frame> {
24
+ readonly framing: Framing.Definition<Frame>;
25
+ }
26
+ export type HttpJsonPatch<Body, Frame> = Partial<HttpJsonInput<Body, Frame>>;
27
+ export interface HttpJsonTransport<Body, Frame> extends Transport<Body, HttpPrepared<Frame>, Frame> {
28
+ readonly with: (patch: HttpJsonPatch<Body, Frame>) => HttpJsonTransport<Body, Frame>;
29
+ }
30
+ export declare const httpJson: <Body, Frame>(input: HttpJsonInput<Body, Frame>) => HttpJsonTransport<Body, Frame>;
31
+ export declare const sseJson: {
32
+ readonly id: "http-json/sse";
33
+ readonly with: <Body>() => HttpJsonTransport<Body, string>;
34
+ };
@@ -0,0 +1,68 @@
1
+ import { Effect } from "effect";
2
+ import { Headers, HttpClientRequest } from "effect/unstable/http";
3
+ import { Auth } from "../auth.js";
4
+ import { render as renderEndpoint } from "../endpoint.js";
5
+ import { Framing } from "../framing.js";
6
+ import * as ProviderShared from "../../protocols/shared.js";
7
+ import { mergeJsonRecords } from "../../schema/index.js";
8
+ import { RequestExecutor } from "../executor.js";
9
+ const applyQuery = (url, query) => {
10
+ if (!query)
11
+ return url;
12
+ const next = new URL(url);
13
+ Object.entries(query).forEach(([key, value]) => next.searchParams.set(key, value));
14
+ return next.toString();
15
+ };
16
+ const bodyWithOverlay = (body, request, encodeBody) => Effect.gen(function* () {
17
+ if (request.http?.body === undefined)
18
+ return { jsonBody: body, bodyText: encodeBody(body) };
19
+ if (ProviderShared.isRecord(body)) {
20
+ const overlaid = mergeJsonRecords(body, request.http.body) ?? {};
21
+ return { jsonBody: overlaid, bodyText: ProviderShared.encodeJson(overlaid) };
22
+ }
23
+ return yield* ProviderShared.invalidRequest("http.body can only overlay JSON object request bodies");
24
+ });
25
+ export const jsonRequestParts = (input) => Effect.gen(function* () {
26
+ const url = applyQuery(renderEndpoint(input.endpoint, { request: input.request, body: input.body }).toString(), input.request.http?.query);
27
+ const body = yield* bodyWithOverlay(input.body, input.request, input.encodeBody);
28
+ const headers = yield* Auth.toEffect(input.auth)({
29
+ request: input.request,
30
+ method: "POST",
31
+ url,
32
+ body: body.bodyText,
33
+ headers: Headers.fromInput({
34
+ ...input.headers?.({ request: input.request }),
35
+ ...input.request.http?.headers,
36
+ }),
37
+ });
38
+ return { url, jsonBody: body.jsonBody, bodyText: body.bodyText, headers };
39
+ });
40
+ export const httpJson = (input) => ({
41
+ id: "http-json",
42
+ with: (patch) => httpJson({ ...input, ...patch }),
43
+ prepare: (prepareInput) => Effect.gen(function* () {
44
+ const parts = yield* jsonRequestParts({ ...prepareInput });
45
+ const request = ProviderShared.jsonPost({
46
+ url: parts.url,
47
+ body: parts.bodyText,
48
+ headers: parts.headers,
49
+ });
50
+ return {
51
+ request,
52
+ framing: input.framing,
53
+ middleware: prepareInput.middleware,
54
+ };
55
+ }),
56
+ execute: (prepared, _request, runtime) => Effect.gen(function* () {
57
+ const response = yield* runtime.http.execute(prepared.request, prepared.middleware);
58
+ return {
59
+ frames: prepared.framing.frame(RequestExecutor.responseStream(response)),
60
+ http: RequestExecutor.responseHttp(response),
61
+ body: prepared.framing.body,
62
+ };
63
+ }),
64
+ });
65
+ export const sseJson = {
66
+ id: "http-json/sse",
67
+ with: () => httpJson({ framing: Framing.sse }),
68
+ };
@@ -0,0 +1,41 @@
1
+ import type { Effect, Scope, Stream } from "effect";
2
+ import { Endpoint } from "../endpoint.js";
3
+ import { Auth } from "../auth.js";
4
+ import type { HttpMiddleware, Interface as RequestExecutorInterface } from "../executor.js";
5
+ import type { WebSocketChannelExecutor } from "./websocket-channel.js";
6
+ import type { AIError, HttpContext, LLMRequest } from "../../schema/index.js";
7
+ export interface TransportRuntime {
8
+ readonly http: RequestExecutorInterface;
9
+ }
10
+ export interface TransportExecution<Frame> {
11
+ readonly frames: Stream.Stream<Frame, AIError>;
12
+ readonly http?: HttpContext;
13
+ body?(frame: Frame): string | undefined;
14
+ /** Optional successful-consumption acknowledgement. HTTP leaves this absent. */
15
+ readonly complete?: Effect.Effect<void>;
16
+ }
17
+ export interface TransportExecuteOptions {
18
+ readonly webSocket?: WebSocketChannelExecutor;
19
+ }
20
+ export interface Transport<Body, Prepared, Frame> {
21
+ readonly id: string;
22
+ readonly prepare: (input: TransportPrepareInput<Body>) => Effect.Effect<Prepared, AIError>;
23
+ readonly execute: (prepared: Prepared, request: LLMRequest, runtime: TransportRuntime, options?: TransportExecuteOptions) => Effect.Effect<TransportExecution<Frame>, AIError, Scope.Scope>;
24
+ }
25
+ export interface TransportPrepareInput<Body> {
26
+ readonly body: Body;
27
+ readonly request: LLMRequest;
28
+ readonly endpoint: Endpoint.Definition<Body>;
29
+ readonly auth: Auth.Definition;
30
+ readonly encodeBody: (body: Body) => string;
31
+ readonly headers?: (input: {
32
+ readonly request: LLMRequest;
33
+ }) => Record<string, string>;
34
+ readonly middleware?: HttpMiddleware;
35
+ readonly webSocket?: WebSocketChannelExecutor;
36
+ }
37
+ export * as HttpTransport from "./http.js";
38
+ export type { HttpHandler, HttpMiddleware } from "../executor.js";
39
+ export type { ChannelCheckpoint, ChannelCreate, ChannelObservation, WebSocketChannelDriver, WebSocketChannelExchange, WebSocketChannelExecution, WebSocketChannelExecutor, } from "./websocket-channel.js";
40
+ export type { WebSocketConnection, WebSocketConnector, WebSocketRequest } from "./websocket.js";
41
+ export { WebSocketTransport } from "./websocket.js";
@@ -0,0 +1,4 @@
1
+ import { Endpoint } from "../endpoint.js";
2
+ import { Auth } from "../auth.js";
3
+ export * as HttpTransport from "./http.js";
4
+ export { WebSocketTransport } from "./websocket.js";
@@ -0,0 +1,57 @@
1
+ import type { Effect, Scope, Stream } from "effect";
2
+ import type { Headers } from "effect/unstable/http";
3
+ import type { AIError, HttpContext } from "../../schema/index.js";
4
+ export interface WebSocketChannelExecutor {
5
+ readonly execute: (exchange: WebSocketChannelExchange) => Effect.Effect<WebSocketChannelExecution, AIError, Scope.Scope>;
6
+ }
7
+ export interface WebSocketChannelExecution {
8
+ readonly frames: Stream.Stream<string, AIError>;
9
+ readonly http?: HttpContext;
10
+ /** Commits staged state after the decoded Route stream ends successfully. */
11
+ readonly complete: Effect.Effect<void>;
12
+ }
13
+ export interface WebSocketChannelExchange {
14
+ readonly id: string;
15
+ readonly connect: {
16
+ readonly url: string;
17
+ readonly headers: Headers.Headers;
18
+ /** Provider-safe connection age after which the channel executor should reconnect before sending. */
19
+ readonly rotateAfterMs?: number;
20
+ };
21
+ readonly fallback: () => Stream.Stream<string, AIError>;
22
+ readonly driver: WebSocketChannelDriver;
23
+ }
24
+ export interface WebSocketChannelDriver {
25
+ readonly create: (checkpoint: ChannelCheckpoint | undefined) => Effect.Effect<ChannelCreate, AIError>;
26
+ readonly observe: (create: ChannelCreate, frame: string) => Effect.Effect<ChannelObservation, AIError>;
27
+ }
28
+ export interface ChannelCreate {
29
+ readonly message: string;
30
+ readonly mode: "full" | "incremental";
31
+ }
32
+ export type ChannelObservation = {
33
+ readonly type: "frame";
34
+ readonly frame: string;
35
+ } | {
36
+ readonly type: "completed";
37
+ readonly frame: string;
38
+ readonly checkpoint?: ChannelCheckpoint;
39
+ } | {
40
+ readonly type: "incomplete";
41
+ readonly frame: string;
42
+ } | {
43
+ readonly type: "provider-failure";
44
+ readonly error: AIError;
45
+ } | {
46
+ readonly type: "rejected";
47
+ readonly error: AIError;
48
+ readonly recovery: "retry-full";
49
+ } | {
50
+ readonly type: "rejected";
51
+ readonly error: AIError;
52
+ readonly recovery: "rotate-and-retry-full";
53
+ };
54
+ export interface ChannelCheckpoint {
55
+ readonly protocol: string;
56
+ readonly value: unknown;
57
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,56 @@
1
+ import { Effect, Stream } from "effect";
2
+ import { Headers } from "effect/unstable/http";
3
+ import { Socket } from "effect/unstable/socket";
4
+ import { AIError, type HttpContext } from "../../schema/index.js";
5
+ import type { Transport } from "./index.js";
6
+ import type { WebSocketChannelExecutor } from "./websocket-channel.js";
7
+ export interface WebSocketRequest {
8
+ readonly url: string;
9
+ readonly headers: Headers.Headers;
10
+ }
11
+ export interface WebSocketConnection {
12
+ readonly http?: HttpContext;
13
+ readonly sendText: (message: string) => Effect.Effect<void, AIError>;
14
+ readonly messages: Stream.Stream<string | Uint8Array, AIError>;
15
+ readonly close: Effect.Effect<void, never>;
16
+ }
17
+ export interface WebSocketConnector {
18
+ readonly open: (input: WebSocketRequest) => Effect.Effect<WebSocketConnection, AIError>;
19
+ }
20
+ export declare const toWebSocketUrl: (value: string) => Effect.Effect<string, AIError, never>;
21
+ export declare const open: (input: WebSocketRequest) => Effect.Effect<WebSocketConnection, AIError, Socket.WebSocketConstructor>;
22
+ export declare const fromWebSocket: (ws: globalThis.WebSocket, input: WebSocketRequest) => Effect.Effect<WebSocketConnection, AIError>;
23
+ export declare const messageText: (message: string | Uint8Array, decoder: TextDecoder) => string;
24
+ export declare const makeDirect: (connector: WebSocketConnector) => WebSocketChannelExecutor;
25
+ export declare const direct: Effect.Effect<WebSocketChannelExecutor, never, Socket.WebSocketConstructor>;
26
+ export interface JsonPrepared {
27
+ readonly url: string;
28
+ readonly headers: Headers.Headers;
29
+ readonly message: string;
30
+ }
31
+ export interface JsonInput<Body, Message> {
32
+ readonly toMessage: (body: Body | Record<string, unknown>) => Effect.Effect<Message, AIError>;
33
+ readonly encodeMessage: (message: Message) => string;
34
+ }
35
+ export type JsonPatch<Body, Message> = Partial<JsonInput<Body, Message>>;
36
+ export interface JsonTransport<Body, Message> extends Transport<Body, JsonPrepared, string> {
37
+ readonly with: (patch: JsonPatch<Body, Message>) => JsonTransport<Body, Message>;
38
+ }
39
+ export declare const json: <Body, Message>(input: JsonInput<Body, Message>) => JsonTransport<Body, Message>;
40
+ export declare const jsonTransport: {
41
+ readonly id: "websocket-json";
42
+ readonly with: <Body, Message>(input: JsonInput<Body, Message>) => JsonTransport<Body, Message>;
43
+ };
44
+ export declare const WebSocketTransport: {
45
+ readonly json: <Body, Message>(input: JsonInput<Body, Message>) => JsonTransport<Body, Message>;
46
+ readonly jsonTransport: {
47
+ readonly id: "websocket-json";
48
+ readonly with: <Body, Message>(input: JsonInput<Body, Message>) => JsonTransport<Body, Message>;
49
+ };
50
+ readonly direct: Effect.Effect<WebSocketChannelExecutor, never, Socket.WebSocketConstructor>;
51
+ readonly makeDirect: (connector: WebSocketConnector) => WebSocketChannelExecutor;
52
+ readonly open: (input: WebSocketRequest) => Effect.Effect<WebSocketConnection, AIError, Socket.WebSocketConstructor>;
53
+ readonly fromWebSocket: (ws: globalThis.WebSocket, input: WebSocketRequest) => Effect.Effect<WebSocketConnection, AIError>;
54
+ readonly messageText: (message: string | Uint8Array, decoder: TextDecoder) => string;
55
+ readonly toWebSocketUrl: (value: string) => Effect.Effect<string, AIError, never>;
56
+ };