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 +30 -4
- package/dist/index.cjs +207 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +58 -15
- package/dist/index.d.ts +58 -15
- package/dist/index.js +207 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
|
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.
|
|
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 =
|
|
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:
|
|
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
|
};
|
package/dist/index.cjs.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.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 =
|
|
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:
|
|
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"]}
|