ainvoker 3.0.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,7 +6,7 @@ Official TypeScript/JavaScript SDK for the AInvoker AI gateway.
6
6
 
7
7
  AInvoker is an AI gateway. This package calls one HTTP API and routes to providers such as OpenAI and Gemini. Create projects, API keys, and billing in the [dashboard](https://ainvoker.com). Use the SDK to call models from your application.
8
8
 
9
- Current release: **2.0.0** (`ai.text.chat` for `POST /v1/text/chat`).
9
+ Current release: **3.2.0** (`ai.text.chat` and `ai.text.stream` for `POST /v1/text/chat` and `POST /v1/text/stream`, with optional `reasoning`).
10
10
 
11
11
  ## Install
12
12
 
@@ -44,7 +44,7 @@ try {
44
44
 
45
45
  1. [Sign up](https://ainvoker.com/signup) and open your Personal workspace.
46
46
  2. Create a project and an API key (`ain_…`). Keep it server-side.
47
- 3. Call `ai.text.chat`. See [Getting Started](https://ainvoker.com/docs/getting-started).
47
+ 3. Call `ai.text.chat` or `ai.text.stream`. See [Getting Started](https://ainvoker.com/docs/getting-started).
48
48
 
49
49
  ## Client options
50
50
 
@@ -64,13 +64,39 @@ try {
64
64
  | `messages` | Yes | At least one message. Roles: `system`, `user`, `assistant`. |
65
65
  | `temperature` | No | Sampling temperature from 0 to 2. |
66
66
  | `maxTokens` | No | Maximum tokens to generate. When omitted, the gateway reserves and caps output at 8192. |
67
+ | `reasoning` | No | `minimal`, `low`, `medium`, or `high`. Thinking depth for models that support it (Gemini); lower reaches the first token faster. Ignored by models without thinking, such as `gpt-4o-mini`. Omit for the provider default. |
67
68
 
68
- The result is `{ id, model, message, usage }`. `usage` is `{ inputTokens, outputTokens, totalTokens }` or `null` when the gateway does not report it.
69
+ The result is `{ id, model, message, usage }`. `usage` is `{ inputTokens, outputTokens, totalTokens }` or `null` when the gateway does not report it. For thinking models, `outputTokens` includes thinking tokens.
69
70
 
70
- For Gemini models, include at least one `user` or `assistant` message. A system-only prompt is not enough. Streaming is not available.
71
+ For Gemini models, include at least one `user` or `assistant` message. A system-only prompt is not enough.
71
72
 
72
73
  Model catalog and plan limits: [Models](https://ainvoker.com/docs/models) · [Limits](https://ainvoker.com/docs/limits).
73
74
 
75
+ ## Text stream
76
+
77
+ `ai.text.stream(params)` calls `POST /v1/text/stream` with the same params as chat. It returns an async iterable of typed events (it does **not** unwrap a `{ data }` envelope):
78
+
79
+ | Event | Fields |
80
+ | --- | --- |
81
+ | `meta` | `id`, `model` |
82
+ | `delta` | `content` |
83
+ | `done` | `message`, `usage` |
84
+ | `error` | `code`, `message` |
85
+
86
+ ```ts
87
+ for await (const event of ai.text.stream({
88
+ provider: "openai",
89
+ model: "gpt-4o-mini",
90
+ messages: [{ role: "user", content: "Hello" }],
91
+ })) {
92
+ if (event.type === "delta") process.stdout.write(event.content)
93
+ }
94
+ ```
95
+
96
+ Non-2xx responses before the stream starts throw `AInvokerError` like chat. If an `error` event arrives mid-stream, the SDK yields that event and then throws `AInvokerError` (HTTP status `200` because the SSE response already started; `code` and `message` come from the event).
97
+
98
+ See [Text Stream](https://ainvoker.com/docs/text-stream).
99
+
74
100
  ## Errors
75
101
 
76
102
  Failures throw `AInvokerError` (`status`, `code`, `message`, and `body` when the response was parsed). Use `isAInvokerError` to narrow the type.
package/dist/index.cjs CHANGED
@@ -35,6 +35,144 @@ function parseErrorPayload(json) {
35
35
  function hasDataEnvelope(json) {
36
36
  return isRecord(json) && "data" in json;
37
37
  }
38
+ function mapSseEvent(eventName, data) {
39
+ if (!isRecord(data)) {
40
+ return null;
41
+ }
42
+ if (eventName === "meta") {
43
+ if (typeof data.id === "string" && typeof data.model === "string") {
44
+ return { type: "meta", id: data.id, model: data.model };
45
+ }
46
+ return null;
47
+ }
48
+ if (eventName === "delta") {
49
+ if (typeof data.content === "string") {
50
+ return { type: "delta", content: data.content };
51
+ }
52
+ return null;
53
+ }
54
+ if (eventName === "done") {
55
+ if (isRecord(data.message) && (data.message.role === "system" || data.message.role === "user" || data.message.role === "assistant") && typeof data.message.content === "string") {
56
+ const usage = data.usage === null ? null : isRecord(data.usage) && typeof data.usage.inputTokens === "number" && typeof data.usage.outputTokens === "number" && typeof data.usage.totalTokens === "number" ? {
57
+ inputTokens: data.usage.inputTokens,
58
+ outputTokens: data.usage.outputTokens,
59
+ totalTokens: data.usage.totalTokens
60
+ } : null;
61
+ return {
62
+ type: "done",
63
+ message: {
64
+ role: data.message.role,
65
+ content: data.message.content
66
+ },
67
+ usage
68
+ };
69
+ }
70
+ return null;
71
+ }
72
+ if (eventName === "error") {
73
+ if (typeof data.code === "string" && typeof data.message === "string") {
74
+ return { type: "error", code: data.code, message: data.message };
75
+ }
76
+ return null;
77
+ }
78
+ return null;
79
+ }
80
+ async function* parseTextStreamBody(body, responseStatus) {
81
+ const reader = body.getReader();
82
+ const decoder = new TextDecoder();
83
+ let buffer = "";
84
+ let eventName = "message";
85
+ const dataLines = [];
86
+ const flush = () => {
87
+ if (dataLines.length === 0) {
88
+ eventName = "message";
89
+ return null;
90
+ }
91
+ const raw = dataLines.join("\n");
92
+ dataLines.length = 0;
93
+ const name = eventName;
94
+ eventName = "message";
95
+ let json;
96
+ try {
97
+ json = JSON.parse(raw);
98
+ } catch {
99
+ throw new AInvokerError(
100
+ responseStatus,
101
+ "INVALID_RESPONSE",
102
+ "Stream event data was not valid JSON",
103
+ raw
104
+ );
105
+ }
106
+ const mapped = mapSseEvent(name, json);
107
+ if (!mapped) {
108
+ throw new AInvokerError(
109
+ responseStatus,
110
+ "INVALID_RESPONSE",
111
+ `Unrecognized stream event "${name}"`,
112
+ json
113
+ );
114
+ }
115
+ return mapped;
116
+ };
117
+ try {
118
+ while (true) {
119
+ const { done, value } = await reader.read();
120
+ if (done) {
121
+ break;
122
+ }
123
+ buffer += decoder.decode(value, { stream: true });
124
+ while (true) {
125
+ const newlineIndex = buffer.indexOf("\n");
126
+ if (newlineIndex < 0) {
127
+ break;
128
+ }
129
+ let line = buffer.slice(0, newlineIndex);
130
+ buffer = buffer.slice(newlineIndex + 1);
131
+ if (line.endsWith("\r")) {
132
+ line = line.slice(0, -1);
133
+ }
134
+ if (line === "") {
135
+ const event2 = flush();
136
+ if (event2) {
137
+ yield event2;
138
+ if (event2.type === "error") {
139
+ throw new AInvokerError(responseStatus, event2.code, event2.message, event2);
140
+ }
141
+ }
142
+ continue;
143
+ }
144
+ if (line.startsWith(":")) {
145
+ continue;
146
+ }
147
+ if (line.startsWith("event:")) {
148
+ eventName = line.slice(6).replace(/^ /, "");
149
+ continue;
150
+ }
151
+ if (line.startsWith("data:")) {
152
+ dataLines.push(line.slice(5).replace(/^ /, ""));
153
+ }
154
+ }
155
+ }
156
+ buffer += decoder.decode();
157
+ if (buffer.length > 0) {
158
+ const trailing = buffer.replace(/\r$/, "");
159
+ if (trailing.startsWith("event:")) {
160
+ eventName = trailing.slice(6).replace(/^ /, "");
161
+ } else if (trailing.startsWith("data:")) {
162
+ dataLines.push(trailing.slice(5).replace(/^ /, ""));
163
+ }
164
+ }
165
+ const event = flush();
166
+ if (event) {
167
+ yield event;
168
+ if (event.type === "error") {
169
+ throw new AInvokerError(responseStatus, event.code, event.message, event);
170
+ }
171
+ }
172
+ } finally {
173
+ reader.releaseLock();
174
+ }
175
+ }
38
176
  var HttpClient = class {
39
177
  apiKey;
40
178
  baseUrl;
@@ -42,11 +180,14 @@ var HttpClient = class {
42
180
  this.apiKey = options.apiKey;
43
181
  this.baseUrl = options.baseUrl.replace(/\/+$/, "");
44
182
  }
183
+ urlFor(path) {
184
+ return `${this.baseUrl}${path.startsWith("/") ? path : `/${path}`}`;
185
+ }
45
186
  /**
46
187
  * POST JSON to a path under `baseUrl`. Unwraps `{ data: T }` on success.
47
188
  */
48
189
  async post(path, body) {
49
- const url = `${this.baseUrl}${path.startsWith("/") ? path : `/${path}`}`;
190
+ const url = this.urlFor(path);
50
191
  let response;
51
192
  try {
52
193
  response = await fetch(url, {
@@ -95,9 +236,66 @@ var HttpClient = class {
95
236
  }
96
237
  return json.data;
97
238
  }
239
+ /**
240
+ * POST JSON and consume an SSE body as typed {@link TextStreamEvent}s.
241
+ * Does not unwrap a `{ data }` envelope. Non-2xx before the stream throws like {@link post}.
242
+ */
243
+ async *postStream(path, body) {
244
+ const url = this.urlFor(path);
245
+ let response;
246
+ try {
247
+ response = await fetch(url, {
248
+ method: "POST",
249
+ headers: {
250
+ Authorization: `Bearer ${this.apiKey}`,
251
+ "Content-Type": "application/json",
252
+ Accept: "text/event-stream"
253
+ },
254
+ body: JSON.stringify(body)
255
+ });
256
+ } catch (cause) {
257
+ const message = cause instanceof Error ? cause.message : "Network request failed";
258
+ throw new AInvokerError(0, "NETWORK_ERROR", message);
259
+ }
260
+ if (!response.ok) {
261
+ const text = await response.text();
262
+ let json = void 0;
263
+ if (text.length > 0) {
264
+ try {
265
+ json = JSON.parse(text);
266
+ } catch {
267
+ throw new AInvokerError(
268
+ response.status,
269
+ "INVALID_RESPONSE",
270
+ "Response body was not valid JSON",
271
+ text
272
+ );
273
+ }
274
+ }
275
+ const parsed = parseErrorPayload(json);
276
+ throw new AInvokerError(
277
+ response.status,
278
+ parsed?.code ?? "HTTP_ERROR",
279
+ parsed?.message ?? `Request failed with status ${response.status}`,
280
+ json
281
+ );
282
+ }
283
+ if (!response.body) {
284
+ throw new AInvokerError(
285
+ response.status,
286
+ "INVALID_RESPONSE",
287
+ "Stream response missing body"
288
+ );
289
+ }
290
+ yield* parseTextStreamBody(response.body, response.status);
291
+ }
98
292
  };
99
293
 
100
294
  // src/resources/text.ts
295
+ function toGatewayModel(params) {
296
+ const { provider, model } = params;
297
+ return provider !== void 0 && provider !== "" ? `${provider}/${model}` : model;
298
+ }
101
299
  var TextResource = class {
102
300
  constructor(http) {
103
301
  this.http = http;
@@ -105,10 +303,16 @@ var TextResource = class {
105
303
  http;
106
304
  chat(params) {
107
305
  const { provider, model, ...rest } = params;
108
- const gatewayModel = provider !== void 0 && provider !== "" ? `${provider}/${model}` : model;
109
306
  return this.http.post("/v1/text/chat", {
110
307
  ...rest,
111
- model: gatewayModel
308
+ model: toGatewayModel({ provider, model })
309
+ });
310
+ }
311
+ stream(params) {
312
+ const { provider, model, ...rest } = params;
313
+ return this.http.postStream("/v1/text/stream", {
314
+ ...rest,
315
+ model: toGatewayModel({ provider, model })
112
316
  });
113
317
  }
114
318
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/resources/text.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * Known AInvoker API / SDK error codes.\r\n * Unknown server codes remain assignable via the open string union.\r\n */\r\nexport type AInvokerErrorCode =\r\n | \"UNAUTHORIZED\"\r\n | \"FORBIDDEN\"\r\n | \"NOT_FOUND\"\r\n | \"VALIDATION_ERROR\"\r\n | \"CONFLICT\"\r\n | \"UPSTREAM_ERROR\"\r\n | \"INTERNAL_ERROR\"\r\n | \"NETWORK_ERROR\"\r\n | \"INVALID_RESPONSE\"\r\n | \"HTTP_ERROR\"\r\n | (string & {})\r\n\r\n/**\r\n * Error thrown when the AInvoker API returns a non-success response\r\n * or the response body cannot be parsed as expected.\r\n */\r\nexport class AInvokerError extends Error {\r\n readonly status: number\r\n readonly code: AInvokerErrorCode\r\n /** Parsed response body when available (error envelope or raw JSON). */\r\n readonly body: unknown\r\n\r\n constructor(\r\n status: number,\r\n code: AInvokerErrorCode,\r\n message: string,\r\n body: unknown = undefined,\r\n ) {\r\n super(message)\r\n this.name = \"AInvokerError\"\r\n this.status = status\r\n this.code = code\r\n this.body = body\r\n }\r\n}\r\n\r\n/** Type guard for {@link AInvokerError}. */\r\nexport function isAInvokerError(error: unknown): error is AInvokerError {\r\n return error instanceof AInvokerError\r\n}\r\n","import { AInvokerError } from \"./errors.js\"\r\nimport type { AInvokerErrorCode } from \"./errors.js\"\r\nimport type { DataEnvelope } from \"./types.js\"\r\n\r\nexport interface HttpClientOptions {\r\n apiKey: string\r\n baseUrl: string\r\n}\r\n\r\nfunction isRecord(value: unknown): value is Record<string, unknown> {\r\n return value !== null && typeof value === \"object\"\r\n}\r\n\r\nfunction parseErrorPayload(json: unknown): { code: AInvokerErrorCode; message: string } | null {\r\n if (!isRecord(json) || !isRecord(json.error)) {\r\n return null\r\n }\r\n const { code, message } = json.error\r\n if (typeof code !== \"string\" || typeof message !== \"string\") {\r\n return null\r\n }\r\n return { code, message }\r\n}\r\n\r\nfunction hasDataEnvelope(json: unknown): json is DataEnvelope<unknown> {\r\n return isRecord(json) && \"data\" in json\r\n}\r\n\r\nexport class HttpClient {\r\n private readonly apiKey: string\r\n private readonly baseUrl: string\r\n\r\n constructor(options: HttpClientOptions) {\r\n this.apiKey = options.apiKey\r\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\")\r\n }\r\n\r\n /**\r\n * POST JSON to a path under `baseUrl`. Unwraps `{ data: T }` on success.\r\n */\r\n async post<T>(path: string, body: unknown): Promise<T> {\r\n const url = `${this.baseUrl}${path.startsWith(\"/\") ? path : `/${path}`}`\r\n\r\n let response: Response\r\n try {\r\n response = await fetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n Authorization: `Bearer ${this.apiKey}`,\r\n \"Content-Type\": \"application/json\",\r\n Accept: \"application/json\",\r\n },\r\n body: JSON.stringify(body),\r\n })\r\n } catch (cause) {\r\n const message = cause instanceof Error ? cause.message : \"Network request failed\"\r\n throw new AInvokerError(0, \"NETWORK_ERROR\", message)\r\n }\r\n\r\n const text = await response.text()\r\n let json: unknown = undefined\r\n if (text.length > 0) {\r\n try {\r\n json = JSON.parse(text) as unknown\r\n } catch {\r\n throw new AInvokerError(\r\n response.status,\r\n \"INVALID_RESPONSE\",\r\n \"Response body was not valid JSON\",\r\n text,\r\n )\r\n }\r\n }\r\n\r\n if (!response.ok) {\r\n const parsed = parseErrorPayload(json)\r\n throw new AInvokerError(\r\n response.status,\r\n parsed?.code ?? \"HTTP_ERROR\",\r\n parsed?.message ?? `Request failed with status ${response.status}`,\r\n json,\r\n )\r\n }\r\n\r\n if (!hasDataEnvelope(json)) {\r\n throw new AInvokerError(\r\n response.status,\r\n \"INVALID_RESPONSE\",\r\n \"Response missing data envelope\",\r\n json,\r\n )\r\n }\r\n\r\n return json.data as T\r\n }\r\n}\r\n","import type { HttpClient } from \"../http.js\"\r\nimport type {\r\n TextChatEscapeParams,\r\n TextChatParams,\r\n TextChatResult,\r\n} from \"../types.js\"\r\n\r\n/**\r\n * Text modality methods (`/v1/text/...`).\r\n */\r\nexport class TextResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n /**\r\n * Text chat completion via the AInvoker gateway (`POST /v1/text/chat`).\r\n *\r\n * Pass `provider` and `model` for typed autocomplete. When `provider` is set,\r\n * the SDK joins them into a `provider/model` slug. When `provider` is omitted,\r\n * the bare `model` name is sent and the API resolves it.\r\n */\r\n chat(params: TextChatParams): Promise<TextChatResult>\r\n chat<P extends string, M extends string>(\r\n params: TextChatEscapeParams<P, M>,\r\n ): Promise<TextChatResult>\r\n chat(\r\n params: TextChatParams | TextChatEscapeParams<string, string>,\r\n ): Promise<TextChatResult> {\r\n const { provider, model, ...rest } = params\r\n const gatewayModel =\r\n provider !== undefined && provider !== \"\"\r\n ? `${provider}/${model}`\r\n : model\r\n\r\n return this.http.post<TextChatResult>(\"/v1/text/chat\", {\r\n ...rest,\r\n model: gatewayModel,\r\n })\r\n }\r\n}\r\n","import { HttpClient } from \"./http.js\"\r\nimport { TextResource } from \"./resources/text.js\"\r\nimport type { AInvokerOptions } from \"./types.js\"\r\n\r\nconst DEFAULT_BASE_URL = \"https://ainvoker-api.onrender.com\"\r\n\r\n/**\r\n * Official AInvoker SDK client.\r\n *\r\n * Use modality namespaces such as {@link AInvoker.text} for gateway calls.\r\n */\r\nexport class AInvoker {\r\n /** Text modality (`/v1/text/...`). */\r\n readonly text: TextResource\r\n\r\n constructor(options: AInvokerOptions) {\r\n if (!options.apiKey || options.apiKey.trim().length === 0) {\r\n throw new Error(\"AInvoker: apiKey is required\")\r\n }\r\n\r\n const http = new HttpClient({\r\n apiKey: options.apiKey,\r\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\r\n })\r\n\r\n this.text = new TextResource(http)\r\n }\r\n}\r\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/resources/text.ts","../src/client.ts"],"names":["event"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * Known AInvoker API / SDK error codes.\r\n * Unknown server codes remain assignable via the open string union.\r\n */\r\nexport type AInvokerErrorCode =\r\n | \"UNAUTHORIZED\"\r\n | \"FORBIDDEN\"\r\n | \"NOT_FOUND\"\r\n | \"VALIDATION_ERROR\"\r\n | \"CONFLICT\"\r\n | \"UPSTREAM_ERROR\"\r\n | \"INTERNAL_ERROR\"\r\n | \"NETWORK_ERROR\"\r\n | \"INVALID_RESPONSE\"\r\n | \"HTTP_ERROR\"\r\n | (string & {})\r\n\r\n/**\r\n * Error thrown when the AInvoker API returns a non-success response\r\n * or the response body cannot be parsed as expected.\r\n */\r\nexport class AInvokerError extends Error {\r\n readonly status: number\r\n readonly code: AInvokerErrorCode\r\n /** Parsed response body when available (error envelope or raw JSON). */\r\n readonly body: unknown\r\n\r\n constructor(\r\n status: number,\r\n code: AInvokerErrorCode,\r\n message: string,\r\n body: unknown = undefined,\r\n ) {\r\n super(message)\r\n this.name = \"AInvokerError\"\r\n this.status = status\r\n this.code = code\r\n this.body = body\r\n }\r\n}\r\n\r\n/** Type guard for {@link AInvokerError}. */\r\nexport function isAInvokerError(error: unknown): error is AInvokerError {\r\n return error instanceof AInvokerError\r\n}\r\n","import { AInvokerError } from \"./errors.js\"\r\nimport type { AInvokerErrorCode } from \"./errors.js\"\r\nimport type { DataEnvelope, TextStreamEvent } from \"./types.js\"\r\n\r\nexport interface HttpClientOptions {\r\n apiKey: string\r\n baseUrl: string\r\n}\r\n\r\nfunction isRecord(value: unknown): value is Record<string, unknown> {\r\n return value !== null && typeof value === \"object\"\r\n}\r\n\r\nfunction parseErrorPayload(json: unknown): { code: AInvokerErrorCode; message: string } | null {\r\n if (!isRecord(json) || !isRecord(json.error)) {\r\n return null\r\n }\r\n const { code, message } = json.error\r\n if (typeof code !== \"string\" || typeof message !== \"string\") {\r\n return null\r\n }\r\n return { code, message }\r\n}\r\n\r\nfunction hasDataEnvelope(json: unknown): json is DataEnvelope<unknown> {\r\n return isRecord(json) && \"data\" in json\r\n}\r\n\r\nfunction mapSseEvent(eventName: string, data: unknown): TextStreamEvent | null {\r\n if (!isRecord(data)) {\r\n return null\r\n }\r\n\r\n if (eventName === \"meta\") {\r\n if (typeof data.id === \"string\" && typeof data.model === \"string\") {\r\n return { type: \"meta\", id: data.id, model: data.model }\r\n }\r\n return null\r\n }\r\n\r\n if (eventName === \"delta\") {\r\n if (typeof data.content === \"string\") {\r\n return { type: \"delta\", content: data.content }\r\n }\r\n return null\r\n }\r\n\r\n if (eventName === \"done\") {\r\n if (\r\n isRecord(data.message) &&\r\n (data.message.role === \"system\" ||\r\n data.message.role === \"user\" ||\r\n data.message.role === \"assistant\") &&\r\n typeof data.message.content === \"string\"\r\n ) {\r\n const usage =\r\n data.usage === null\r\n ? null\r\n : isRecord(data.usage) &&\r\n typeof data.usage.inputTokens === \"number\" &&\r\n typeof data.usage.outputTokens === \"number\" &&\r\n typeof data.usage.totalTokens === \"number\"\r\n ? {\r\n inputTokens: data.usage.inputTokens,\r\n outputTokens: data.usage.outputTokens,\r\n totalTokens: data.usage.totalTokens,\r\n }\r\n : null\r\n return {\r\n type: \"done\",\r\n message: {\r\n role: data.message.role,\r\n content: data.message.content,\r\n },\r\n usage,\r\n }\r\n }\r\n return null\r\n }\r\n\r\n if (eventName === \"error\") {\r\n if (typeof data.code === \"string\" && typeof data.message === \"string\") {\r\n return { type: \"error\", code: data.code, message: data.message }\r\n }\r\n return null\r\n }\r\n\r\n return null\r\n}\r\n\r\n/**\r\n * Parse SSE from a fetch body. Yields typed gateway stream events.\r\n * After an `error` event is yielded, throws AInvokerError.\r\n */\r\nasync function* parseTextStreamBody(\r\n body: ReadableStream<Uint8Array>,\r\n responseStatus: number,\r\n): AsyncGenerator<TextStreamEvent> {\r\n const reader = body.getReader()\r\n const decoder = new TextDecoder()\r\n let buffer = \"\"\r\n let eventName = \"message\"\r\n const dataLines: string[] = []\r\n\r\n const flush = (): TextStreamEvent | null => {\r\n if (dataLines.length === 0) {\r\n eventName = \"message\"\r\n return null\r\n }\r\n const raw = dataLines.join(\"\\n\")\r\n dataLines.length = 0\r\n const name = eventName\r\n eventName = \"message\"\r\n\r\n let json: unknown\r\n try {\r\n json = JSON.parse(raw) as unknown\r\n } catch {\r\n throw new AInvokerError(\r\n responseStatus,\r\n \"INVALID_RESPONSE\",\r\n \"Stream event data was not valid JSON\",\r\n raw,\r\n )\r\n }\r\n\r\n const mapped = mapSseEvent(name, json)\r\n if (!mapped) {\r\n throw new AInvokerError(\r\n responseStatus,\r\n \"INVALID_RESPONSE\",\r\n `Unrecognized stream event \"${name}\"`,\r\n json,\r\n )\r\n }\r\n return mapped\r\n }\r\n\r\n try {\r\n while (true) {\r\n const { done, value } = await reader.read()\r\n if (done) {\r\n break\r\n }\r\n\r\n buffer += decoder.decode(value, { stream: true })\r\n\r\n while (true) {\r\n const newlineIndex = buffer.indexOf(\"\\n\")\r\n if (newlineIndex < 0) {\r\n break\r\n }\r\n\r\n let line = buffer.slice(0, newlineIndex)\r\n buffer = buffer.slice(newlineIndex + 1)\r\n if (line.endsWith(\"\\r\")) {\r\n line = line.slice(0, -1)\r\n }\r\n\r\n if (line === \"\") {\r\n const event = flush()\r\n if (event) {\r\n yield event\r\n if (event.type === \"error\") {\r\n throw new AInvokerError(responseStatus, event.code, event.message, event)\r\n }\r\n }\r\n continue\r\n }\r\n\r\n if (line.startsWith(\":\")) {\r\n continue\r\n }\r\n\r\n if (line.startsWith(\"event:\")) {\r\n eventName = line.slice(6).replace(/^ /, \"\")\r\n continue\r\n }\r\n\r\n if (line.startsWith(\"data:\")) {\r\n dataLines.push(line.slice(5).replace(/^ /, \"\"))\r\n }\r\n }\r\n }\r\n\r\n buffer += decoder.decode()\r\n if (buffer.length > 0) {\r\n const trailing = buffer.replace(/\\r$/, \"\")\r\n if (trailing.startsWith(\"event:\")) {\r\n eventName = trailing.slice(6).replace(/^ /, \"\")\r\n } else if (trailing.startsWith(\"data:\")) {\r\n dataLines.push(trailing.slice(5).replace(/^ /, \"\"))\r\n }\r\n }\r\n\r\n const event = flush()\r\n if (event) {\r\n yield event\r\n if (event.type === \"error\") {\r\n throw new AInvokerError(responseStatus, event.code, event.message, event)\r\n }\r\n }\r\n } finally {\r\n reader.releaseLock()\r\n }\r\n}\r\n\r\nexport class HttpClient {\r\n private readonly apiKey: string\r\n private readonly baseUrl: string\r\n\r\n constructor(options: HttpClientOptions) {\r\n this.apiKey = options.apiKey\r\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\")\r\n }\r\n\r\n private urlFor(path: string): string {\r\n return `${this.baseUrl}${path.startsWith(\"/\") ? path : `/${path}`}`\r\n }\r\n\r\n /**\r\n * POST JSON to a path under `baseUrl`. Unwraps `{ data: T }` on success.\r\n */\r\n async post<T>(path: string, body: unknown): Promise<T> {\r\n const url = this.urlFor(path)\r\n\r\n let response: Response\r\n try {\r\n response = await fetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n Authorization: `Bearer ${this.apiKey}`,\r\n \"Content-Type\": \"application/json\",\r\n Accept: \"application/json\",\r\n },\r\n body: JSON.stringify(body),\r\n })\r\n } catch (cause) {\r\n const message = cause instanceof Error ? cause.message : \"Network request failed\"\r\n throw new AInvokerError(0, \"NETWORK_ERROR\", message)\r\n }\r\n\r\n const text = await response.text()\r\n let json: unknown = undefined\r\n if (text.length > 0) {\r\n try {\r\n json = JSON.parse(text) as unknown\r\n } catch {\r\n throw new AInvokerError(\r\n response.status,\r\n \"INVALID_RESPONSE\",\r\n \"Response body was not valid JSON\",\r\n text,\r\n )\r\n }\r\n }\r\n\r\n if (!response.ok) {\r\n const parsed = parseErrorPayload(json)\r\n throw new AInvokerError(\r\n response.status,\r\n parsed?.code ?? \"HTTP_ERROR\",\r\n parsed?.message ?? `Request failed with status ${response.status}`,\r\n json,\r\n )\r\n }\r\n\r\n if (!hasDataEnvelope(json)) {\r\n throw new AInvokerError(\r\n response.status,\r\n \"INVALID_RESPONSE\",\r\n \"Response missing data envelope\",\r\n json,\r\n )\r\n }\r\n\r\n return json.data as T\r\n }\r\n\r\n /**\r\n * POST JSON and consume an SSE body as typed {@link TextStreamEvent}s.\r\n * Does not unwrap a `{ data }` envelope. Non-2xx before the stream throws like {@link post}.\r\n */\r\n async *postStream(path: string, body: unknown): AsyncGenerator<TextStreamEvent> {\r\n const url = this.urlFor(path)\r\n\r\n let response: Response\r\n try {\r\n response = await fetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n Authorization: `Bearer ${this.apiKey}`,\r\n \"Content-Type\": \"application/json\",\r\n Accept: \"text/event-stream\",\r\n },\r\n body: JSON.stringify(body),\r\n })\r\n } catch (cause) {\r\n const message = cause instanceof Error ? cause.message : \"Network request failed\"\r\n throw new AInvokerError(0, \"NETWORK_ERROR\", message)\r\n }\r\n\r\n if (!response.ok) {\r\n const text = await response.text()\r\n let json: unknown = undefined\r\n if (text.length > 0) {\r\n try {\r\n json = JSON.parse(text) as unknown\r\n } catch {\r\n throw new AInvokerError(\r\n response.status,\r\n \"INVALID_RESPONSE\",\r\n \"Response body was not valid JSON\",\r\n text,\r\n )\r\n }\r\n }\r\n const parsed = parseErrorPayload(json)\r\n throw new AInvokerError(\r\n response.status,\r\n parsed?.code ?? \"HTTP_ERROR\",\r\n parsed?.message ?? `Request failed with status ${response.status}`,\r\n json,\r\n )\r\n }\r\n\r\n if (!response.body) {\r\n throw new AInvokerError(\r\n response.status,\r\n \"INVALID_RESPONSE\",\r\n \"Stream response missing body\",\r\n )\r\n }\r\n\r\n yield* parseTextStreamBody(response.body, response.status)\r\n }\r\n}\r\n","import type { HttpClient } from \"../http.js\"\r\nimport type {\r\n TextChatEscapeParams,\r\n TextChatParams,\r\n TextChatResult,\r\n TextStreamEvent,\r\n} from \"../types.js\"\r\n\r\nfunction toGatewayModel(params: {\r\n provider?: string\r\n model: string\r\n}): string {\r\n const { provider, model } = params\r\n return provider !== undefined && provider !== \"\" ? `${provider}/${model}` : model\r\n}\r\n\r\n/**\r\n * Text modality methods (`/v1/text/...`).\r\n */\r\nexport class TextResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n /**\r\n * Text chat completion via the AInvoker gateway (`POST /v1/text/chat`).\r\n *\r\n * Pass `provider` and `model` for typed autocomplete. When `provider` is set,\r\n * the SDK joins them into a `provider/model` slug. When `provider` is omitted,\r\n * the bare `model` name is sent and the API resolves it.\r\n */\r\n chat(params: TextChatParams): Promise<TextChatResult>\r\n chat<P extends string, M extends string>(\r\n params: TextChatEscapeParams<P, M>,\r\n ): Promise<TextChatResult>\r\n chat(\r\n params: TextChatParams | TextChatEscapeParams<string, string>,\r\n ): Promise<TextChatResult> {\r\n const { provider, model, ...rest } = params\r\n return this.http.post<TextChatResult>(\"/v1/text/chat\", {\r\n ...rest,\r\n model: toGatewayModel({ provider, model }),\r\n })\r\n }\r\n\r\n /**\r\n * Stream a text completion (`POST /v1/text/stream`) as an async iterable of\r\n * {@link TextStreamEvent}. Same params and provider/model joining as {@link chat}.\r\n *\r\n * Non-2xx before the stream starts throws {@link AInvokerError}. An `error`\r\n * event is yielded, then the iterator throws {@link AInvokerError}.\r\n */\r\n stream(params: TextChatParams): AsyncGenerator<TextStreamEvent>\r\n stream<P extends string, M extends string>(\r\n params: TextChatEscapeParams<P, M>,\r\n ): AsyncGenerator<TextStreamEvent>\r\n stream(\r\n params: TextChatParams | TextChatEscapeParams<string, string>,\r\n ): AsyncGenerator<TextStreamEvent> {\r\n const { provider, model, ...rest } = params\r\n return this.http.postStream(\"/v1/text/stream\", {\r\n ...rest,\r\n model: toGatewayModel({ provider, model }),\r\n })\r\n }\r\n}\r\n","import { HttpClient } from \"./http.js\"\r\nimport { TextResource } from \"./resources/text.js\"\r\nimport type { AInvokerOptions } from \"./types.js\"\r\n\r\nconst DEFAULT_BASE_URL = \"https://ainvoker-api.onrender.com\"\r\n\r\n/**\r\n * Official AInvoker SDK client.\r\n *\r\n * Use modality namespaces such as {@link AInvoker.text} for gateway calls.\r\n */\r\nexport class AInvoker {\r\n /** Text modality (`/v1/text/...`). */\r\n readonly text: TextResource\r\n\r\n constructor(options: AInvokerOptions) {\r\n if (!options.apiKey || options.apiKey.trim().length === 0) {\r\n throw new Error(\"AInvoker: apiKey is required\")\r\n }\r\n\r\n const http = new HttpClient({\r\n apiKey: options.apiKey,\r\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\r\n })\r\n\r\n this.text = new TextResource(http)\r\n }\r\n}\r\n"]}
package/dist/index.d.cts CHANGED
@@ -1,17 +1,3 @@
1
- interface HttpClientOptions {
2
- apiKey: string;
3
- baseUrl: string;
4
- }
5
- declare class HttpClient {
6
- private readonly apiKey;
7
- private readonly baseUrl;
8
- constructor(options: HttpClientOptions);
9
- /**
10
- * POST JSON to a path under `baseUrl`. Unwraps `{ data: T }` on success.
11
- */
12
- post<T>(path: string, body: unknown): Promise<T>;
13
- }
14
-
15
1
  /**
16
2
  * Client configuration for {@link AInvoker}.
17
3
  */
@@ -51,6 +37,8 @@ type TextCatalogPair = {
51
37
  model: TextCatalog[P];
52
38
  };
53
39
  }[TextProvider];
40
+ /** Thinking depth for models that support it. */
41
+ type TextReasoning = "minimal" | "low" | "medium" | "high";
54
42
  type TextChatFields = {
55
43
  messages: ChatMessage[];
56
44
  /** Sampling temperature (0–2). */
@@ -60,6 +48,12 @@ type TextChatFields = {
60
48
  * When omitted, the gateway reserves and caps output at 8192.
61
49
  */
62
50
  maxTokens?: number;
51
+ /**
52
+ * Thinking depth for models that support it (Gemini). Lower is faster to the
53
+ * first token. Ignored by models without thinking (for example gpt-4o-mini).
54
+ * When omitted, the provider default applies.
55
+ */
56
+ reasoning?: TextReasoning;
63
57
  };
64
58
  /**
65
59
  * Provider omitted: model may be any catalog name (or a future API name).
@@ -108,6 +102,46 @@ interface TextChatResult {
108
102
  message: ChatMessage;
109
103
  usage: ChatUsage | null;
110
104
  }
105
+ /**
106
+ * Events from {@link TextResource.stream} (`POST /v1/text/stream`).
107
+ * The SDK adds `type`; the wire SSE uses the event name instead.
108
+ */
109
+ type TextStreamEvent = {
110
+ type: "meta";
111
+ id: string;
112
+ model: string;
113
+ } | {
114
+ type: "delta";
115
+ content: string;
116
+ } | {
117
+ type: "done";
118
+ message: ChatMessage;
119
+ usage: ChatUsage | null;
120
+ } | {
121
+ type: "error";
122
+ code: string;
123
+ message: string;
124
+ };
125
+
126
+ interface HttpClientOptions {
127
+ apiKey: string;
128
+ baseUrl: string;
129
+ }
130
+ declare class HttpClient {
131
+ private readonly apiKey;
132
+ private readonly baseUrl;
133
+ constructor(options: HttpClientOptions);
134
+ private urlFor;
135
+ /**
136
+ * POST JSON to a path under `baseUrl`. Unwraps `{ data: T }` on success.
137
+ */
138
+ post<T>(path: string, body: unknown): Promise<T>;
139
+ /**
140
+ * POST JSON and consume an SSE body as typed {@link TextStreamEvent}s.
141
+ * Does not unwrap a `{ data }` envelope. Non-2xx before the stream throws like {@link post}.
142
+ */
143
+ postStream(path: string, body: unknown): AsyncGenerator<TextStreamEvent>;
144
+ }
111
145
 
112
146
  /**
113
147
  * Text modality methods (`/v1/text/...`).
@@ -124,6 +158,15 @@ declare class TextResource {
124
158
  */
125
159
  chat(params: TextChatParams): Promise<TextChatResult>;
126
160
  chat<P extends string, M extends string>(params: TextChatEscapeParams<P, M>): Promise<TextChatResult>;
161
+ /**
162
+ * Stream a text completion (`POST /v1/text/stream`) as an async iterable of
163
+ * {@link TextStreamEvent}. Same params and provider/model joining as {@link chat}.
164
+ *
165
+ * Non-2xx before the stream starts throws {@link AInvokerError}. An `error`
166
+ * event is yielded, then the iterator throws {@link AInvokerError}.
167
+ */
168
+ stream(params: TextChatParams): AsyncGenerator<TextStreamEvent>;
169
+ stream<P extends string, M extends string>(params: TextChatEscapeParams<P, M>): AsyncGenerator<TextStreamEvent>;
127
170
  }
128
171
 
129
172
  /**
@@ -156,4 +199,4 @@ declare class AInvokerError extends Error {
156
199
  /** Type guard for {@link AInvokerError}. */
157
200
  declare function isAInvokerError(error: unknown): error is AInvokerError;
158
201
 
159
- export { AInvoker, AInvokerError, type AInvokerErrorCode, type AInvokerOptions, type ChatMessage, type ChatUsage, type TextCatalog, type TextCatalogPair, type TextChatEscapeParams, type TextChatParams, type TextChatResult, type TextModel, type TextProvider, isAInvokerError };
202
+ export { AInvoker, AInvokerError, type AInvokerErrorCode, type AInvokerOptions, type ChatMessage, type ChatUsage, type TextCatalog, type TextCatalogPair, type TextChatEscapeParams, type TextChatParams, type TextChatResult, type TextModel, type TextProvider, type TextReasoning, type TextStreamEvent, isAInvokerError };
package/dist/index.d.ts CHANGED
@@ -1,17 +1,3 @@
1
- interface HttpClientOptions {
2
- apiKey: string;
3
- baseUrl: string;
4
- }
5
- declare class HttpClient {
6
- private readonly apiKey;
7
- private readonly baseUrl;
8
- constructor(options: HttpClientOptions);
9
- /**
10
- * POST JSON to a path under `baseUrl`. Unwraps `{ data: T }` on success.
11
- */
12
- post<T>(path: string, body: unknown): Promise<T>;
13
- }
14
-
15
1
  /**
16
2
  * Client configuration for {@link AInvoker}.
17
3
  */
@@ -51,6 +37,8 @@ type TextCatalogPair = {
51
37
  model: TextCatalog[P];
52
38
  };
53
39
  }[TextProvider];
40
+ /** Thinking depth for models that support it. */
41
+ type TextReasoning = "minimal" | "low" | "medium" | "high";
54
42
  type TextChatFields = {
55
43
  messages: ChatMessage[];
56
44
  /** Sampling temperature (0–2). */
@@ -60,6 +48,12 @@ type TextChatFields = {
60
48
  * When omitted, the gateway reserves and caps output at 8192.
61
49
  */
62
50
  maxTokens?: number;
51
+ /**
52
+ * Thinking depth for models that support it (Gemini). Lower is faster to the
53
+ * first token. Ignored by models without thinking (for example gpt-4o-mini).
54
+ * When omitted, the provider default applies.
55
+ */
56
+ reasoning?: TextReasoning;
63
57
  };
64
58
  /**
65
59
  * Provider omitted: model may be any catalog name (or a future API name).
@@ -108,6 +102,46 @@ interface TextChatResult {
108
102
  message: ChatMessage;
109
103
  usage: ChatUsage | null;
110
104
  }
105
+ /**
106
+ * Events from {@link TextResource.stream} (`POST /v1/text/stream`).
107
+ * The SDK adds `type`; the wire SSE uses the event name instead.
108
+ */
109
+ type TextStreamEvent = {
110
+ type: "meta";
111
+ id: string;
112
+ model: string;
113
+ } | {
114
+ type: "delta";
115
+ content: string;
116
+ } | {
117
+ type: "done";
118
+ message: ChatMessage;
119
+ usage: ChatUsage | null;
120
+ } | {
121
+ type: "error";
122
+ code: string;
123
+ message: string;
124
+ };
125
+
126
+ interface HttpClientOptions {
127
+ apiKey: string;
128
+ baseUrl: string;
129
+ }
130
+ declare class HttpClient {
131
+ private readonly apiKey;
132
+ private readonly baseUrl;
133
+ constructor(options: HttpClientOptions);
134
+ private urlFor;
135
+ /**
136
+ * POST JSON to a path under `baseUrl`. Unwraps `{ data: T }` on success.
137
+ */
138
+ post<T>(path: string, body: unknown): Promise<T>;
139
+ /**
140
+ * POST JSON and consume an SSE body as typed {@link TextStreamEvent}s.
141
+ * Does not unwrap a `{ data }` envelope. Non-2xx before the stream throws like {@link post}.
142
+ */
143
+ postStream(path: string, body: unknown): AsyncGenerator<TextStreamEvent>;
144
+ }
111
145
 
112
146
  /**
113
147
  * Text modality methods (`/v1/text/...`).
@@ -124,6 +158,15 @@ declare class TextResource {
124
158
  */
125
159
  chat(params: TextChatParams): Promise<TextChatResult>;
126
160
  chat<P extends string, M extends string>(params: TextChatEscapeParams<P, M>): Promise<TextChatResult>;
161
+ /**
162
+ * Stream a text completion (`POST /v1/text/stream`) as an async iterable of
163
+ * {@link TextStreamEvent}. Same params and provider/model joining as {@link chat}.
164
+ *
165
+ * Non-2xx before the stream starts throws {@link AInvokerError}. An `error`
166
+ * event is yielded, then the iterator throws {@link AInvokerError}.
167
+ */
168
+ stream(params: TextChatParams): AsyncGenerator<TextStreamEvent>;
169
+ stream<P extends string, M extends string>(params: TextChatEscapeParams<P, M>): AsyncGenerator<TextStreamEvent>;
127
170
  }
128
171
 
129
172
  /**
@@ -156,4 +199,4 @@ declare class AInvokerError extends Error {
156
199
  /** Type guard for {@link AInvokerError}. */
157
200
  declare function isAInvokerError(error: unknown): error is AInvokerError;
158
201
 
159
- export { AInvoker, AInvokerError, type AInvokerErrorCode, type AInvokerOptions, type ChatMessage, type ChatUsage, type TextCatalog, type TextCatalogPair, type TextChatEscapeParams, type TextChatParams, type TextChatResult, type TextModel, type TextProvider, isAInvokerError };
202
+ export { AInvoker, AInvokerError, type AInvokerErrorCode, type AInvokerOptions, type ChatMessage, type ChatUsage, type TextCatalog, type TextCatalogPair, type TextChatEscapeParams, type TextChatParams, type TextChatResult, type TextModel, type TextProvider, type TextReasoning, type TextStreamEvent, isAInvokerError };
package/dist/index.js CHANGED
@@ -33,6 +33,144 @@ function parseErrorPayload(json) {
33
33
  function hasDataEnvelope(json) {
34
34
  return isRecord(json) && "data" in json;
35
35
  }
36
+ function mapSseEvent(eventName, data) {
37
+ if (!isRecord(data)) {
38
+ return null;
39
+ }
40
+ if (eventName === "meta") {
41
+ if (typeof data.id === "string" && typeof data.model === "string") {
42
+ return { type: "meta", id: data.id, model: data.model };
43
+ }
44
+ return null;
45
+ }
46
+ if (eventName === "delta") {
47
+ if (typeof data.content === "string") {
48
+ return { type: "delta", content: data.content };
49
+ }
50
+ return null;
51
+ }
52
+ if (eventName === "done") {
53
+ if (isRecord(data.message) && (data.message.role === "system" || data.message.role === "user" || data.message.role === "assistant") && typeof data.message.content === "string") {
54
+ const usage = data.usage === null ? null : isRecord(data.usage) && typeof data.usage.inputTokens === "number" && typeof data.usage.outputTokens === "number" && typeof data.usage.totalTokens === "number" ? {
55
+ inputTokens: data.usage.inputTokens,
56
+ outputTokens: data.usage.outputTokens,
57
+ totalTokens: data.usage.totalTokens
58
+ } : null;
59
+ return {
60
+ type: "done",
61
+ message: {
62
+ role: data.message.role,
63
+ content: data.message.content
64
+ },
65
+ usage
66
+ };
67
+ }
68
+ return null;
69
+ }
70
+ if (eventName === "error") {
71
+ if (typeof data.code === "string" && typeof data.message === "string") {
72
+ return { type: "error", code: data.code, message: data.message };
73
+ }
74
+ return null;
75
+ }
76
+ return null;
77
+ }
78
+ async function* parseTextStreamBody(body, responseStatus) {
79
+ const reader = body.getReader();
80
+ const decoder = new TextDecoder();
81
+ let buffer = "";
82
+ let eventName = "message";
83
+ const dataLines = [];
84
+ const flush = () => {
85
+ if (dataLines.length === 0) {
86
+ eventName = "message";
87
+ return null;
88
+ }
89
+ const raw = dataLines.join("\n");
90
+ dataLines.length = 0;
91
+ const name = eventName;
92
+ eventName = "message";
93
+ let json;
94
+ try {
95
+ json = JSON.parse(raw);
96
+ } catch {
97
+ throw new AInvokerError(
98
+ responseStatus,
99
+ "INVALID_RESPONSE",
100
+ "Stream event data was not valid JSON",
101
+ raw
102
+ );
103
+ }
104
+ const mapped = mapSseEvent(name, json);
105
+ if (!mapped) {
106
+ throw new AInvokerError(
107
+ responseStatus,
108
+ "INVALID_RESPONSE",
109
+ `Unrecognized stream event "${name}"`,
110
+ json
111
+ );
112
+ }
113
+ return mapped;
114
+ };
115
+ try {
116
+ while (true) {
117
+ const { done, value } = await reader.read();
118
+ if (done) {
119
+ break;
120
+ }
121
+ buffer += decoder.decode(value, { stream: true });
122
+ while (true) {
123
+ const newlineIndex = buffer.indexOf("\n");
124
+ if (newlineIndex < 0) {
125
+ break;
126
+ }
127
+ let line = buffer.slice(0, newlineIndex);
128
+ buffer = buffer.slice(newlineIndex + 1);
129
+ if (line.endsWith("\r")) {
130
+ line = line.slice(0, -1);
131
+ }
132
+ if (line === "") {
133
+ const event2 = flush();
134
+ if (event2) {
135
+ yield event2;
136
+ if (event2.type === "error") {
137
+ throw new AInvokerError(responseStatus, event2.code, event2.message, event2);
138
+ }
139
+ }
140
+ continue;
141
+ }
142
+ if (line.startsWith(":")) {
143
+ continue;
144
+ }
145
+ if (line.startsWith("event:")) {
146
+ eventName = line.slice(6).replace(/^ /, "");
147
+ continue;
148
+ }
149
+ if (line.startsWith("data:")) {
150
+ dataLines.push(line.slice(5).replace(/^ /, ""));
151
+ }
152
+ }
153
+ }
154
+ buffer += decoder.decode();
155
+ if (buffer.length > 0) {
156
+ const trailing = buffer.replace(/\r$/, "");
157
+ if (trailing.startsWith("event:")) {
158
+ eventName = trailing.slice(6).replace(/^ /, "");
159
+ } else if (trailing.startsWith("data:")) {
160
+ dataLines.push(trailing.slice(5).replace(/^ /, ""));
161
+ }
162
+ }
163
+ const event = flush();
164
+ if (event) {
165
+ yield event;
166
+ if (event.type === "error") {
167
+ throw new AInvokerError(responseStatus, event.code, event.message, event);
168
+ }
169
+ }
170
+ } finally {
171
+ reader.releaseLock();
172
+ }
173
+ }
36
174
  var HttpClient = class {
37
175
  apiKey;
38
176
  baseUrl;
@@ -40,11 +178,14 @@ var HttpClient = class {
40
178
  this.apiKey = options.apiKey;
41
179
  this.baseUrl = options.baseUrl.replace(/\/+$/, "");
42
180
  }
181
+ urlFor(path) {
182
+ return `${this.baseUrl}${path.startsWith("/") ? path : `/${path}`}`;
183
+ }
43
184
  /**
44
185
  * POST JSON to a path under `baseUrl`. Unwraps `{ data: T }` on success.
45
186
  */
46
187
  async post(path, body) {
47
- const url = `${this.baseUrl}${path.startsWith("/") ? path : `/${path}`}`;
188
+ const url = this.urlFor(path);
48
189
  let response;
49
190
  try {
50
191
  response = await fetch(url, {
@@ -93,9 +234,66 @@ var HttpClient = class {
93
234
  }
94
235
  return json.data;
95
236
  }
237
+ /**
238
+ * POST JSON and consume an SSE body as typed {@link TextStreamEvent}s.
239
+ * Does not unwrap a `{ data }` envelope. Non-2xx before the stream throws like {@link post}.
240
+ */
241
+ async *postStream(path, body) {
242
+ const url = this.urlFor(path);
243
+ let response;
244
+ try {
245
+ response = await fetch(url, {
246
+ method: "POST",
247
+ headers: {
248
+ Authorization: `Bearer ${this.apiKey}`,
249
+ "Content-Type": "application/json",
250
+ Accept: "text/event-stream"
251
+ },
252
+ body: JSON.stringify(body)
253
+ });
254
+ } catch (cause) {
255
+ const message = cause instanceof Error ? cause.message : "Network request failed";
256
+ throw new AInvokerError(0, "NETWORK_ERROR", message);
257
+ }
258
+ if (!response.ok) {
259
+ const text = await response.text();
260
+ let json = void 0;
261
+ if (text.length > 0) {
262
+ try {
263
+ json = JSON.parse(text);
264
+ } catch {
265
+ throw new AInvokerError(
266
+ response.status,
267
+ "INVALID_RESPONSE",
268
+ "Response body was not valid JSON",
269
+ text
270
+ );
271
+ }
272
+ }
273
+ const parsed = parseErrorPayload(json);
274
+ throw new AInvokerError(
275
+ response.status,
276
+ parsed?.code ?? "HTTP_ERROR",
277
+ parsed?.message ?? `Request failed with status ${response.status}`,
278
+ json
279
+ );
280
+ }
281
+ if (!response.body) {
282
+ throw new AInvokerError(
283
+ response.status,
284
+ "INVALID_RESPONSE",
285
+ "Stream response missing body"
286
+ );
287
+ }
288
+ yield* parseTextStreamBody(response.body, response.status);
289
+ }
96
290
  };
97
291
 
98
292
  // src/resources/text.ts
293
+ function toGatewayModel(params) {
294
+ const { provider, model } = params;
295
+ return provider !== void 0 && provider !== "" ? `${provider}/${model}` : model;
296
+ }
99
297
  var TextResource = class {
100
298
  constructor(http) {
101
299
  this.http = http;
@@ -103,10 +301,16 @@ var TextResource = class {
103
301
  http;
104
302
  chat(params) {
105
303
  const { provider, model, ...rest } = params;
106
- const gatewayModel = provider !== void 0 && provider !== "" ? `${provider}/${model}` : model;
107
304
  return this.http.post("/v1/text/chat", {
108
305
  ...rest,
109
- model: gatewayModel
306
+ model: toGatewayModel({ provider, model })
307
+ });
308
+ }
309
+ stream(params) {
310
+ const { provider, model, ...rest } = params;
311
+ return this.http.postStream("/v1/text/stream", {
312
+ ...rest,
313
+ model: toGatewayModel({ provider, model })
110
314
  });
111
315
  }
112
316
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/resources/text.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Known AInvoker API / SDK error codes.\r\n * Unknown server codes remain assignable via the open string union.\r\n */\r\nexport type AInvokerErrorCode =\r\n | \"UNAUTHORIZED\"\r\n | \"FORBIDDEN\"\r\n | \"NOT_FOUND\"\r\n | \"VALIDATION_ERROR\"\r\n | \"CONFLICT\"\r\n | \"UPSTREAM_ERROR\"\r\n | \"INTERNAL_ERROR\"\r\n | \"NETWORK_ERROR\"\r\n | \"INVALID_RESPONSE\"\r\n | \"HTTP_ERROR\"\r\n | (string & {})\r\n\r\n/**\r\n * Error thrown when the AInvoker API returns a non-success response\r\n * or the response body cannot be parsed as expected.\r\n */\r\nexport class AInvokerError extends Error {\r\n readonly status: number\r\n readonly code: AInvokerErrorCode\r\n /** Parsed response body when available (error envelope or raw JSON). */\r\n readonly body: unknown\r\n\r\n constructor(\r\n status: number,\r\n code: AInvokerErrorCode,\r\n message: string,\r\n body: unknown = undefined,\r\n ) {\r\n super(message)\r\n this.name = \"AInvokerError\"\r\n this.status = status\r\n this.code = code\r\n this.body = body\r\n }\r\n}\r\n\r\n/** Type guard for {@link AInvokerError}. */\r\nexport function isAInvokerError(error: unknown): error is AInvokerError {\r\n return error instanceof AInvokerError\r\n}\r\n","import { AInvokerError } from \"./errors.js\"\r\nimport type { AInvokerErrorCode } from \"./errors.js\"\r\nimport type { DataEnvelope } from \"./types.js\"\r\n\r\nexport interface HttpClientOptions {\r\n apiKey: string\r\n baseUrl: string\r\n}\r\n\r\nfunction isRecord(value: unknown): value is Record<string, unknown> {\r\n return value !== null && typeof value === \"object\"\r\n}\r\n\r\nfunction parseErrorPayload(json: unknown): { code: AInvokerErrorCode; message: string } | null {\r\n if (!isRecord(json) || !isRecord(json.error)) {\r\n return null\r\n }\r\n const { code, message } = json.error\r\n if (typeof code !== \"string\" || typeof message !== \"string\") {\r\n return null\r\n }\r\n return { code, message }\r\n}\r\n\r\nfunction hasDataEnvelope(json: unknown): json is DataEnvelope<unknown> {\r\n return isRecord(json) && \"data\" in json\r\n}\r\n\r\nexport class HttpClient {\r\n private readonly apiKey: string\r\n private readonly baseUrl: string\r\n\r\n constructor(options: HttpClientOptions) {\r\n this.apiKey = options.apiKey\r\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\")\r\n }\r\n\r\n /**\r\n * POST JSON to a path under `baseUrl`. Unwraps `{ data: T }` on success.\r\n */\r\n async post<T>(path: string, body: unknown): Promise<T> {\r\n const url = `${this.baseUrl}${path.startsWith(\"/\") ? path : `/${path}`}`\r\n\r\n let response: Response\r\n try {\r\n response = await fetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n Authorization: `Bearer ${this.apiKey}`,\r\n \"Content-Type\": \"application/json\",\r\n Accept: \"application/json\",\r\n },\r\n body: JSON.stringify(body),\r\n })\r\n } catch (cause) {\r\n const message = cause instanceof Error ? cause.message : \"Network request failed\"\r\n throw new AInvokerError(0, \"NETWORK_ERROR\", message)\r\n }\r\n\r\n const text = await response.text()\r\n let json: unknown = undefined\r\n if (text.length > 0) {\r\n try {\r\n json = JSON.parse(text) as unknown\r\n } catch {\r\n throw new AInvokerError(\r\n response.status,\r\n \"INVALID_RESPONSE\",\r\n \"Response body was not valid JSON\",\r\n text,\r\n )\r\n }\r\n }\r\n\r\n if (!response.ok) {\r\n const parsed = parseErrorPayload(json)\r\n throw new AInvokerError(\r\n response.status,\r\n parsed?.code ?? \"HTTP_ERROR\",\r\n parsed?.message ?? `Request failed with status ${response.status}`,\r\n json,\r\n )\r\n }\r\n\r\n if (!hasDataEnvelope(json)) {\r\n throw new AInvokerError(\r\n response.status,\r\n \"INVALID_RESPONSE\",\r\n \"Response missing data envelope\",\r\n json,\r\n )\r\n }\r\n\r\n return json.data as T\r\n }\r\n}\r\n","import type { HttpClient } from \"../http.js\"\r\nimport type {\r\n TextChatEscapeParams,\r\n TextChatParams,\r\n TextChatResult,\r\n} from \"../types.js\"\r\n\r\n/**\r\n * Text modality methods (`/v1/text/...`).\r\n */\r\nexport class TextResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n /**\r\n * Text chat completion via the AInvoker gateway (`POST /v1/text/chat`).\r\n *\r\n * Pass `provider` and `model` for typed autocomplete. When `provider` is set,\r\n * the SDK joins them into a `provider/model` slug. When `provider` is omitted,\r\n * the bare `model` name is sent and the API resolves it.\r\n */\r\n chat(params: TextChatParams): Promise<TextChatResult>\r\n chat<P extends string, M extends string>(\r\n params: TextChatEscapeParams<P, M>,\r\n ): Promise<TextChatResult>\r\n chat(\r\n params: TextChatParams | TextChatEscapeParams<string, string>,\r\n ): Promise<TextChatResult> {\r\n const { provider, model, ...rest } = params\r\n const gatewayModel =\r\n provider !== undefined && provider !== \"\"\r\n ? `${provider}/${model}`\r\n : model\r\n\r\n return this.http.post<TextChatResult>(\"/v1/text/chat\", {\r\n ...rest,\r\n model: gatewayModel,\r\n })\r\n }\r\n}\r\n","import { HttpClient } from \"./http.js\"\r\nimport { TextResource } from \"./resources/text.js\"\r\nimport type { AInvokerOptions } from \"./types.js\"\r\n\r\nconst DEFAULT_BASE_URL = \"https://ainvoker-api.onrender.com\"\r\n\r\n/**\r\n * Official AInvoker SDK client.\r\n *\r\n * Use modality namespaces such as {@link AInvoker.text} for gateway calls.\r\n */\r\nexport class AInvoker {\r\n /** Text modality (`/v1/text/...`). */\r\n readonly text: TextResource\r\n\r\n constructor(options: AInvokerOptions) {\r\n if (!options.apiKey || options.apiKey.trim().length === 0) {\r\n throw new Error(\"AInvoker: apiKey is required\")\r\n }\r\n\r\n const http = new HttpClient({\r\n apiKey: options.apiKey,\r\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\r\n })\r\n\r\n this.text = new TextResource(http)\r\n }\r\n}\r\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/resources/text.ts","../src/client.ts"],"names":["event"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Known AInvoker API / SDK error codes.\r\n * Unknown server codes remain assignable via the open string union.\r\n */\r\nexport type AInvokerErrorCode =\r\n | \"UNAUTHORIZED\"\r\n | \"FORBIDDEN\"\r\n | \"NOT_FOUND\"\r\n | \"VALIDATION_ERROR\"\r\n | \"CONFLICT\"\r\n | \"UPSTREAM_ERROR\"\r\n | \"INTERNAL_ERROR\"\r\n | \"NETWORK_ERROR\"\r\n | \"INVALID_RESPONSE\"\r\n | \"HTTP_ERROR\"\r\n | (string & {})\r\n\r\n/**\r\n * Error thrown when the AInvoker API returns a non-success response\r\n * or the response body cannot be parsed as expected.\r\n */\r\nexport class AInvokerError extends Error {\r\n readonly status: number\r\n readonly code: AInvokerErrorCode\r\n /** Parsed response body when available (error envelope or raw JSON). */\r\n readonly body: unknown\r\n\r\n constructor(\r\n status: number,\r\n code: AInvokerErrorCode,\r\n message: string,\r\n body: unknown = undefined,\r\n ) {\r\n super(message)\r\n this.name = \"AInvokerError\"\r\n this.status = status\r\n this.code = code\r\n this.body = body\r\n }\r\n}\r\n\r\n/** Type guard for {@link AInvokerError}. */\r\nexport function isAInvokerError(error: unknown): error is AInvokerError {\r\n return error instanceof AInvokerError\r\n}\r\n","import { AInvokerError } from \"./errors.js\"\r\nimport type { AInvokerErrorCode } from \"./errors.js\"\r\nimport type { DataEnvelope, TextStreamEvent } from \"./types.js\"\r\n\r\nexport interface HttpClientOptions {\r\n apiKey: string\r\n baseUrl: string\r\n}\r\n\r\nfunction isRecord(value: unknown): value is Record<string, unknown> {\r\n return value !== null && typeof value === \"object\"\r\n}\r\n\r\nfunction parseErrorPayload(json: unknown): { code: AInvokerErrorCode; message: string } | null {\r\n if (!isRecord(json) || !isRecord(json.error)) {\r\n return null\r\n }\r\n const { code, message } = json.error\r\n if (typeof code !== \"string\" || typeof message !== \"string\") {\r\n return null\r\n }\r\n return { code, message }\r\n}\r\n\r\nfunction hasDataEnvelope(json: unknown): json is DataEnvelope<unknown> {\r\n return isRecord(json) && \"data\" in json\r\n}\r\n\r\nfunction mapSseEvent(eventName: string, data: unknown): TextStreamEvent | null {\r\n if (!isRecord(data)) {\r\n return null\r\n }\r\n\r\n if (eventName === \"meta\") {\r\n if (typeof data.id === \"string\" && typeof data.model === \"string\") {\r\n return { type: \"meta\", id: data.id, model: data.model }\r\n }\r\n return null\r\n }\r\n\r\n if (eventName === \"delta\") {\r\n if (typeof data.content === \"string\") {\r\n return { type: \"delta\", content: data.content }\r\n }\r\n return null\r\n }\r\n\r\n if (eventName === \"done\") {\r\n if (\r\n isRecord(data.message) &&\r\n (data.message.role === \"system\" ||\r\n data.message.role === \"user\" ||\r\n data.message.role === \"assistant\") &&\r\n typeof data.message.content === \"string\"\r\n ) {\r\n const usage =\r\n data.usage === null\r\n ? null\r\n : isRecord(data.usage) &&\r\n typeof data.usage.inputTokens === \"number\" &&\r\n typeof data.usage.outputTokens === \"number\" &&\r\n typeof data.usage.totalTokens === \"number\"\r\n ? {\r\n inputTokens: data.usage.inputTokens,\r\n outputTokens: data.usage.outputTokens,\r\n totalTokens: data.usage.totalTokens,\r\n }\r\n : null\r\n return {\r\n type: \"done\",\r\n message: {\r\n role: data.message.role,\r\n content: data.message.content,\r\n },\r\n usage,\r\n }\r\n }\r\n return null\r\n }\r\n\r\n if (eventName === \"error\") {\r\n if (typeof data.code === \"string\" && typeof data.message === \"string\") {\r\n return { type: \"error\", code: data.code, message: data.message }\r\n }\r\n return null\r\n }\r\n\r\n return null\r\n}\r\n\r\n/**\r\n * Parse SSE from a fetch body. Yields typed gateway stream events.\r\n * After an `error` event is yielded, throws AInvokerError.\r\n */\r\nasync function* parseTextStreamBody(\r\n body: ReadableStream<Uint8Array>,\r\n responseStatus: number,\r\n): AsyncGenerator<TextStreamEvent> {\r\n const reader = body.getReader()\r\n const decoder = new TextDecoder()\r\n let buffer = \"\"\r\n let eventName = \"message\"\r\n const dataLines: string[] = []\r\n\r\n const flush = (): TextStreamEvent | null => {\r\n if (dataLines.length === 0) {\r\n eventName = \"message\"\r\n return null\r\n }\r\n const raw = dataLines.join(\"\\n\")\r\n dataLines.length = 0\r\n const name = eventName\r\n eventName = \"message\"\r\n\r\n let json: unknown\r\n try {\r\n json = JSON.parse(raw) as unknown\r\n } catch {\r\n throw new AInvokerError(\r\n responseStatus,\r\n \"INVALID_RESPONSE\",\r\n \"Stream event data was not valid JSON\",\r\n raw,\r\n )\r\n }\r\n\r\n const mapped = mapSseEvent(name, json)\r\n if (!mapped) {\r\n throw new AInvokerError(\r\n responseStatus,\r\n \"INVALID_RESPONSE\",\r\n `Unrecognized stream event \"${name}\"`,\r\n json,\r\n )\r\n }\r\n return mapped\r\n }\r\n\r\n try {\r\n while (true) {\r\n const { done, value } = await reader.read()\r\n if (done) {\r\n break\r\n }\r\n\r\n buffer += decoder.decode(value, { stream: true })\r\n\r\n while (true) {\r\n const newlineIndex = buffer.indexOf(\"\\n\")\r\n if (newlineIndex < 0) {\r\n break\r\n }\r\n\r\n let line = buffer.slice(0, newlineIndex)\r\n buffer = buffer.slice(newlineIndex + 1)\r\n if (line.endsWith(\"\\r\")) {\r\n line = line.slice(0, -1)\r\n }\r\n\r\n if (line === \"\") {\r\n const event = flush()\r\n if (event) {\r\n yield event\r\n if (event.type === \"error\") {\r\n throw new AInvokerError(responseStatus, event.code, event.message, event)\r\n }\r\n }\r\n continue\r\n }\r\n\r\n if (line.startsWith(\":\")) {\r\n continue\r\n }\r\n\r\n if (line.startsWith(\"event:\")) {\r\n eventName = line.slice(6).replace(/^ /, \"\")\r\n continue\r\n }\r\n\r\n if (line.startsWith(\"data:\")) {\r\n dataLines.push(line.slice(5).replace(/^ /, \"\"))\r\n }\r\n }\r\n }\r\n\r\n buffer += decoder.decode()\r\n if (buffer.length > 0) {\r\n const trailing = buffer.replace(/\\r$/, \"\")\r\n if (trailing.startsWith(\"event:\")) {\r\n eventName = trailing.slice(6).replace(/^ /, \"\")\r\n } else if (trailing.startsWith(\"data:\")) {\r\n dataLines.push(trailing.slice(5).replace(/^ /, \"\"))\r\n }\r\n }\r\n\r\n const event = flush()\r\n if (event) {\r\n yield event\r\n if (event.type === \"error\") {\r\n throw new AInvokerError(responseStatus, event.code, event.message, event)\r\n }\r\n }\r\n } finally {\r\n reader.releaseLock()\r\n }\r\n}\r\n\r\nexport class HttpClient {\r\n private readonly apiKey: string\r\n private readonly baseUrl: string\r\n\r\n constructor(options: HttpClientOptions) {\r\n this.apiKey = options.apiKey\r\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\")\r\n }\r\n\r\n private urlFor(path: string): string {\r\n return `${this.baseUrl}${path.startsWith(\"/\") ? path : `/${path}`}`\r\n }\r\n\r\n /**\r\n * POST JSON to a path under `baseUrl`. Unwraps `{ data: T }` on success.\r\n */\r\n async post<T>(path: string, body: unknown): Promise<T> {\r\n const url = this.urlFor(path)\r\n\r\n let response: Response\r\n try {\r\n response = await fetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n Authorization: `Bearer ${this.apiKey}`,\r\n \"Content-Type\": \"application/json\",\r\n Accept: \"application/json\",\r\n },\r\n body: JSON.stringify(body),\r\n })\r\n } catch (cause) {\r\n const message = cause instanceof Error ? cause.message : \"Network request failed\"\r\n throw new AInvokerError(0, \"NETWORK_ERROR\", message)\r\n }\r\n\r\n const text = await response.text()\r\n let json: unknown = undefined\r\n if (text.length > 0) {\r\n try {\r\n json = JSON.parse(text) as unknown\r\n } catch {\r\n throw new AInvokerError(\r\n response.status,\r\n \"INVALID_RESPONSE\",\r\n \"Response body was not valid JSON\",\r\n text,\r\n )\r\n }\r\n }\r\n\r\n if (!response.ok) {\r\n const parsed = parseErrorPayload(json)\r\n throw new AInvokerError(\r\n response.status,\r\n parsed?.code ?? \"HTTP_ERROR\",\r\n parsed?.message ?? `Request failed with status ${response.status}`,\r\n json,\r\n )\r\n }\r\n\r\n if (!hasDataEnvelope(json)) {\r\n throw new AInvokerError(\r\n response.status,\r\n \"INVALID_RESPONSE\",\r\n \"Response missing data envelope\",\r\n json,\r\n )\r\n }\r\n\r\n return json.data as T\r\n }\r\n\r\n /**\r\n * POST JSON and consume an SSE body as typed {@link TextStreamEvent}s.\r\n * Does not unwrap a `{ data }` envelope. Non-2xx before the stream throws like {@link post}.\r\n */\r\n async *postStream(path: string, body: unknown): AsyncGenerator<TextStreamEvent> {\r\n const url = this.urlFor(path)\r\n\r\n let response: Response\r\n try {\r\n response = await fetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n Authorization: `Bearer ${this.apiKey}`,\r\n \"Content-Type\": \"application/json\",\r\n Accept: \"text/event-stream\",\r\n },\r\n body: JSON.stringify(body),\r\n })\r\n } catch (cause) {\r\n const message = cause instanceof Error ? cause.message : \"Network request failed\"\r\n throw new AInvokerError(0, \"NETWORK_ERROR\", message)\r\n }\r\n\r\n if (!response.ok) {\r\n const text = await response.text()\r\n let json: unknown = undefined\r\n if (text.length > 0) {\r\n try {\r\n json = JSON.parse(text) as unknown\r\n } catch {\r\n throw new AInvokerError(\r\n response.status,\r\n \"INVALID_RESPONSE\",\r\n \"Response body was not valid JSON\",\r\n text,\r\n )\r\n }\r\n }\r\n const parsed = parseErrorPayload(json)\r\n throw new AInvokerError(\r\n response.status,\r\n parsed?.code ?? \"HTTP_ERROR\",\r\n parsed?.message ?? `Request failed with status ${response.status}`,\r\n json,\r\n )\r\n }\r\n\r\n if (!response.body) {\r\n throw new AInvokerError(\r\n response.status,\r\n \"INVALID_RESPONSE\",\r\n \"Stream response missing body\",\r\n )\r\n }\r\n\r\n yield* parseTextStreamBody(response.body, response.status)\r\n }\r\n}\r\n","import type { HttpClient } from \"../http.js\"\r\nimport type {\r\n TextChatEscapeParams,\r\n TextChatParams,\r\n TextChatResult,\r\n TextStreamEvent,\r\n} from \"../types.js\"\r\n\r\nfunction toGatewayModel(params: {\r\n provider?: string\r\n model: string\r\n}): string {\r\n const { provider, model } = params\r\n return provider !== undefined && provider !== \"\" ? `${provider}/${model}` : model\r\n}\r\n\r\n/**\r\n * Text modality methods (`/v1/text/...`).\r\n */\r\nexport class TextResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n /**\r\n * Text chat completion via the AInvoker gateway (`POST /v1/text/chat`).\r\n *\r\n * Pass `provider` and `model` for typed autocomplete. When `provider` is set,\r\n * the SDK joins them into a `provider/model` slug. When `provider` is omitted,\r\n * the bare `model` name is sent and the API resolves it.\r\n */\r\n chat(params: TextChatParams): Promise<TextChatResult>\r\n chat<P extends string, M extends string>(\r\n params: TextChatEscapeParams<P, M>,\r\n ): Promise<TextChatResult>\r\n chat(\r\n params: TextChatParams | TextChatEscapeParams<string, string>,\r\n ): Promise<TextChatResult> {\r\n const { provider, model, ...rest } = params\r\n return this.http.post<TextChatResult>(\"/v1/text/chat\", {\r\n ...rest,\r\n model: toGatewayModel({ provider, model }),\r\n })\r\n }\r\n\r\n /**\r\n * Stream a text completion (`POST /v1/text/stream`) as an async iterable of\r\n * {@link TextStreamEvent}. Same params and provider/model joining as {@link chat}.\r\n *\r\n * Non-2xx before the stream starts throws {@link AInvokerError}. An `error`\r\n * event is yielded, then the iterator throws {@link AInvokerError}.\r\n */\r\n stream(params: TextChatParams): AsyncGenerator<TextStreamEvent>\r\n stream<P extends string, M extends string>(\r\n params: TextChatEscapeParams<P, M>,\r\n ): AsyncGenerator<TextStreamEvent>\r\n stream(\r\n params: TextChatParams | TextChatEscapeParams<string, string>,\r\n ): AsyncGenerator<TextStreamEvent> {\r\n const { provider, model, ...rest } = params\r\n return this.http.postStream(\"/v1/text/stream\", {\r\n ...rest,\r\n model: toGatewayModel({ provider, model }),\r\n })\r\n }\r\n}\r\n","import { HttpClient } from \"./http.js\"\r\nimport { TextResource } from \"./resources/text.js\"\r\nimport type { AInvokerOptions } from \"./types.js\"\r\n\r\nconst DEFAULT_BASE_URL = \"https://ainvoker-api.onrender.com\"\r\n\r\n/**\r\n * Official AInvoker SDK client.\r\n *\r\n * Use modality namespaces such as {@link AInvoker.text} for gateway calls.\r\n */\r\nexport class AInvoker {\r\n /** Text modality (`/v1/text/...`). */\r\n readonly text: TextResource\r\n\r\n constructor(options: AInvokerOptions) {\r\n if (!options.apiKey || options.apiKey.trim().length === 0) {\r\n throw new Error(\"AInvoker: apiKey is required\")\r\n }\r\n\r\n const http = new HttpClient({\r\n apiKey: options.apiKey,\r\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\r\n })\r\n\r\n this.text = new TextResource(http)\r\n }\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ainvoker",
3
- "version": "3.0.0",
3
+ "version": "3.2.0",
4
4
  "description": "Official TypeScript/JavaScript SDK for the AInvoker AI gateway",
5
5
  "license": "MIT",
6
6
  "author": "AInvoker",