@x12i/openrouter-runtime 1.0.5 → 1.0.6
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 +46 -22
- package/dist/index.cjs +86 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -2
- package/dist/index.d.ts +9 -2
- package/dist/index.js +83 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,6 +32,33 @@ const response = await runtime.run({
|
|
|
32
32
|
console.log(response.text);
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
## Console logging
|
|
36
|
+
|
|
37
|
+
Turn on runtime console logs with:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
OPENROUTER_RUNTIME_LOGS=true
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
When that env var is `true` / `1` / `yes` / `on`, and you do not pass a custom `logger`, the runtime logs to the console:
|
|
44
|
+
|
|
45
|
+
- `runtime.request.started` — includes `streaming: false` and `entrypoint: "run"`
|
|
46
|
+
- `runtime.request.compiled` — includes `bodyStream: false` and any streaming-related warning codes
|
|
47
|
+
- `runtime.response.normalized`
|
|
48
|
+
- `runtime.executeStreamingChat.called` — if someone hits the reserved streaming method
|
|
49
|
+
- provider retry / function-tool events
|
|
50
|
+
|
|
51
|
+
This package does **not** auto-load `.env`. Put the vars in your environment (shell export, process manager, or host `dotenv`) before calling `createOpenRouterRuntime()`. See `.env.example`.
|
|
52
|
+
|
|
53
|
+
Example:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
OPEN_ROUTER_KEY=sk-or-...
|
|
57
|
+
OPENROUTER_RUNTIME_LOGS=true
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
You can still pass an explicit `logger` to override the console logger.
|
|
61
|
+
|
|
35
62
|
## Server Tools
|
|
36
63
|
|
|
37
64
|
Enable OpenRouter server tools through `serverTools`:
|
|
@@ -73,7 +100,11 @@ Function calls are executed locally and looped back to OpenRouter until a final
|
|
|
73
100
|
|
|
74
101
|
## Streaming
|
|
75
102
|
|
|
76
|
-
`
|
|
103
|
+
### `run()` is non-streaming — always
|
|
104
|
+
|
|
105
|
+
`runtime.run(request)` never streams. It is the only supported execution path today.
|
|
106
|
+
|
|
107
|
+
Use it for background tasks, graph nodes, tool calls, structured output, research jobs, classification, extraction, patch generation, and automation.
|
|
77
108
|
|
|
78
109
|
```ts
|
|
79
110
|
const response = await runtime.run({
|
|
@@ -84,33 +115,26 @@ const response = await runtime.run({
|
|
|
84
115
|
|
|
85
116
|
This sends a normal non-streaming OpenRouter request and returns a completed `RuntimeResponse`.
|
|
86
117
|
|
|
87
|
-
|
|
118
|
+
`run()` always sends `stream: false` on the OpenRouter body. Any truthy `rawOpenRouterOverrides.stream` is overwritten and reported as `STREAMING_OVERRIDE_IGNORED_FOR_RUN`. Nested `serverTools.advisor.stream` is also forced off with `ADVISOR_STREAMING_IGNORED_FOR_RUN`.
|
|
88
119
|
|
|
89
|
-
|
|
120
|
+
### Streaming lives on a separate method: `executeStreamingChat()`
|
|
90
121
|
|
|
91
|
-
|
|
122
|
+
Streaming is **not** available through `run()`, and the old `runtime.stream()` name was **removed on purpose**.
|
|
92
123
|
|
|
93
|
-
|
|
124
|
+
Clients that still call `runtime.stream(...)` will break. That is intentional — so mistaken streaming usage is caught immediately.
|
|
125
|
+
|
|
126
|
+
The reserved streaming entrypoint is:
|
|
94
127
|
|
|
95
128
|
```ts
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
// send token deltas to browser/client
|
|
129
|
+
for await (const event of runtime.executeStreamingChat(request)) {
|
|
130
|
+
// token deltas / stream events (not implemented yet)
|
|
99
131
|
}
|
|
100
132
|
```
|
|
101
133
|
|
|
102
|
-
Today, `
|
|
103
|
-
|
|
104
|
-
Do not pass streaming through raw overrides:
|
|
105
|
-
|
|
106
|
-
```ts
|
|
107
|
-
await runtime.run({
|
|
108
|
-
model: "openai/gpt-5.2",
|
|
109
|
-
prompt: "Summarize this document.",
|
|
110
|
-
rawOpenRouterOverrides: {
|
|
111
|
-
stream: true
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
```
|
|
134
|
+
Today, `executeStreamingChat()` throws `STREAMING_NOT_IMPLEMENTED`. Treat this package as a non-streaming runtime until that method is implemented.
|
|
115
135
|
|
|
116
|
-
|
|
136
|
+
| Method | Streaming? | Status |
|
|
137
|
+
| --- | --- | --- |
|
|
138
|
+
| `runtime.run(request)` | No | Supported |
|
|
139
|
+
| `runtime.executeStreamingChat(request)` | Yes (future) | Throws `STREAMING_NOT_IMPLEMENTED` |
|
|
140
|
+
| `runtime.stream(request)` | — | **Removed** — breaks by design |
|
package/dist/index.cjs
CHANGED
|
@@ -24,18 +24,45 @@ __export(index_exports, {
|
|
|
24
24
|
RuntimeConfigError: () => RuntimeConfigError,
|
|
25
25
|
buildOpenRouterServerTools: () => buildOpenRouterServerTools,
|
|
26
26
|
compileRuntimeRequest: () => compileRuntimeRequest,
|
|
27
|
-
|
|
27
|
+
createConsoleLogger: () => createConsoleLogger,
|
|
28
|
+
createOpenRouterRuntime: () => createOpenRouterRuntime,
|
|
29
|
+
isRuntimeLoggingEnabled: () => isRuntimeLoggingEnabled
|
|
28
30
|
});
|
|
29
31
|
module.exports = __toCommonJS(index_exports);
|
|
30
32
|
|
|
33
|
+
// src/utils/console-logger.ts
|
|
34
|
+
var TRUTHY = /* @__PURE__ */ new Set(["1", "true", "yes", "on"]);
|
|
35
|
+
function isRuntimeLoggingEnabled(env = typeof process === "undefined" ? void 0 : process.env) {
|
|
36
|
+
const value = env?.OPENROUTER_RUNTIME_LOGS?.trim().toLowerCase();
|
|
37
|
+
return value !== void 0 && TRUTHY.has(value);
|
|
38
|
+
}
|
|
39
|
+
function createConsoleLogger() {
|
|
40
|
+
return {
|
|
41
|
+
debug(event, data) {
|
|
42
|
+
console.debug(`[openrouter-runtime] ${event}`, data ?? "");
|
|
43
|
+
},
|
|
44
|
+
info(event, data) {
|
|
45
|
+
console.info(`[openrouter-runtime] ${event}`, data ?? "");
|
|
46
|
+
},
|
|
47
|
+
warn(event, data) {
|
|
48
|
+
console.warn(`[openrouter-runtime] ${event}`, data ?? "");
|
|
49
|
+
},
|
|
50
|
+
error(event, data) {
|
|
51
|
+
console.error(`[openrouter-runtime] ${event}`, data ?? "");
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
31
56
|
// src/config/defaults.ts
|
|
32
57
|
function resolveRuntimeOptions(options) {
|
|
58
|
+
const logger = options.logger ?? (isRuntimeLoggingEnabled() ? createConsoleLogger() : void 0);
|
|
33
59
|
return {
|
|
34
60
|
...options,
|
|
35
61
|
apiKey: options.apiKey ?? readOpenRouterApiKeyFromEnv() ?? "",
|
|
36
62
|
baseUrl: options.baseUrl ?? "https://openrouter.ai/api/v1",
|
|
37
63
|
defaultHeaders: options.defaultHeaders ?? {},
|
|
38
|
-
fetch: options.fetch ?? globalThis.fetch
|
|
64
|
+
fetch: options.fetch ?? globalThis.fetch,
|
|
65
|
+
...logger ? { logger } : {}
|
|
39
66
|
};
|
|
40
67
|
}
|
|
41
68
|
function resolveDefaults(options) {
|
|
@@ -924,13 +951,38 @@ function compileRuntimeRequest(request, defaults, options = { apiKey: "" }, cont
|
|
|
924
951
|
}
|
|
925
952
|
function enforceStreamingPolicyForRun(body, warnings, context) {
|
|
926
953
|
if (context.streaming) return;
|
|
927
|
-
if (body.stream
|
|
954
|
+
if (body.stream !== void 0 && body.stream !== false) {
|
|
928
955
|
warnings.push({
|
|
929
956
|
code: "STREAMING_OVERRIDE_IGNORED_FOR_RUN",
|
|
930
|
-
message: "runtime.run() is non-streaming. Use runtime.
|
|
957
|
+
message: "runtime.run() is non-streaming. Use runtime.executeStreamingChat() when streaming is implemented.",
|
|
958
|
+
details: { ignoredStreamValue: body.stream }
|
|
959
|
+
});
|
|
960
|
+
}
|
|
961
|
+
body.stream = false;
|
|
962
|
+
stripAdvisorStreaming(body, warnings);
|
|
963
|
+
}
|
|
964
|
+
function stripAdvisorStreaming(body, warnings) {
|
|
965
|
+
const tools = body.tools;
|
|
966
|
+
if (!Array.isArray(tools)) return;
|
|
967
|
+
let stripped = 0;
|
|
968
|
+
for (const tool of tools) {
|
|
969
|
+
if (!tool || typeof tool !== "object") continue;
|
|
970
|
+
const record = tool;
|
|
971
|
+
if (record.type !== "openrouter:advisor") continue;
|
|
972
|
+
const parameters = record.parameters;
|
|
973
|
+
if (!parameters || typeof parameters !== "object") continue;
|
|
974
|
+
const params = parameters;
|
|
975
|
+
if (params.stream === void 0 || params.stream === false) continue;
|
|
976
|
+
params.stream = false;
|
|
977
|
+
stripped += 1;
|
|
978
|
+
}
|
|
979
|
+
if (stripped > 0) {
|
|
980
|
+
warnings.push({
|
|
981
|
+
code: "ADVISOR_STREAMING_IGNORED_FOR_RUN",
|
|
982
|
+
message: "runtime.run() disables advisor.stream. Nested advisor streaming is not supported on the non-streaming entrypoint.",
|
|
983
|
+
details: { advisorsStripped: stripped }
|
|
931
984
|
});
|
|
932
985
|
}
|
|
933
|
-
delete body.stream;
|
|
934
986
|
}
|
|
935
987
|
function resolveApiMode(request, defaultMode = "auto", serverTools) {
|
|
936
988
|
const mode = request.apiMode ?? defaultMode;
|
|
@@ -964,7 +1016,7 @@ function buildChatBody(request, baseBody) {
|
|
|
964
1016
|
return clean({
|
|
965
1017
|
...baseBody,
|
|
966
1018
|
messages,
|
|
967
|
-
|
|
1019
|
+
max_completion_tokens: request.maxTokens,
|
|
968
1020
|
response_format: request.responseFormat
|
|
969
1021
|
});
|
|
970
1022
|
}
|
|
@@ -1306,10 +1358,10 @@ function optional6(key, value) {
|
|
|
1306
1358
|
}
|
|
1307
1359
|
|
|
1308
1360
|
// src/runtime/streaming.ts
|
|
1309
|
-
async function*
|
|
1361
|
+
async function* executeStreamingChatNotImplemented() {
|
|
1310
1362
|
throw new RuntimeConfigError(
|
|
1311
1363
|
"STREAMING_NOT_IMPLEMENTED",
|
|
1312
|
-
"
|
|
1364
|
+
"executeStreamingChat() is reserved and not implemented yet. Use runtime.run() for non-streaming execution."
|
|
1313
1365
|
);
|
|
1314
1366
|
}
|
|
1315
1367
|
|
|
@@ -1322,24 +1374,43 @@ function createOpenRouterRuntime(options) {
|
|
|
1322
1374
|
async run(request) {
|
|
1323
1375
|
const requestWithId = { ...request, id: request.id ?? createRuntimeId() };
|
|
1324
1376
|
try {
|
|
1325
|
-
resolvedOptions.logger?.info?.("runtime.request.started", {
|
|
1377
|
+
resolvedOptions.logger?.info?.("runtime.request.started", {
|
|
1378
|
+
requestId: requestWithId.id,
|
|
1379
|
+
streaming: false,
|
|
1380
|
+
entrypoint: "run"
|
|
1381
|
+
});
|
|
1326
1382
|
await resolvedOptions.hooks?.beforeCompile?.(requestWithId);
|
|
1327
1383
|
const compiled = compileRuntimeRequest(requestWithId, defaults, resolvedOptions, { streaming: false });
|
|
1328
1384
|
await resolvedOptions.hooks?.afterCompile?.(compiled);
|
|
1329
1385
|
resolvedOptions.logger?.debug?.("runtime.request.compiled", {
|
|
1330
1386
|
requestId: requestWithId.id,
|
|
1331
|
-
apiMode: compiled.apiMode
|
|
1387
|
+
apiMode: compiled.apiMode,
|
|
1388
|
+
streaming: false,
|
|
1389
|
+
bodyStream: compiled.body.stream,
|
|
1390
|
+
streamingWarnings: compiled.warnings.filter((warning) => warning.code.includes("STREAMING") || warning.code.includes("ADVISOR_STREAMING")).map((warning) => warning.code)
|
|
1332
1391
|
});
|
|
1333
1392
|
await resolvedOptions.hooks?.beforeOpenRouterRequest?.(compiled);
|
|
1334
1393
|
const response = compiled.apiMode === "chat" ? await runChat(requestWithId, compiled, context) : await runResponses(requestWithId, compiled, context);
|
|
1335
1394
|
await resolvedOptions.hooks?.afterOpenRouterResponse?.(response.raw.response);
|
|
1336
|
-
resolvedOptions.logger?.info?.("runtime.response.normalized", {
|
|
1395
|
+
resolvedOptions.logger?.info?.("runtime.response.normalized", {
|
|
1396
|
+
requestId: requestWithId.id,
|
|
1397
|
+
status: response.status,
|
|
1398
|
+
streaming: false
|
|
1399
|
+
});
|
|
1337
1400
|
return response;
|
|
1338
1401
|
} catch (error) {
|
|
1339
1402
|
return errorResponse(requestWithId, error);
|
|
1340
1403
|
}
|
|
1341
1404
|
},
|
|
1342
|
-
|
|
1405
|
+
executeStreamingChat(request) {
|
|
1406
|
+
resolvedOptions.logger?.warn?.("runtime.executeStreamingChat.called", {
|
|
1407
|
+
requestId: request.id,
|
|
1408
|
+
streaming: true,
|
|
1409
|
+
entrypoint: "executeStreamingChat",
|
|
1410
|
+
implemented: false
|
|
1411
|
+
});
|
|
1412
|
+
return executeStreamingChatNotImplemented();
|
|
1413
|
+
}
|
|
1343
1414
|
};
|
|
1344
1415
|
function errorResponse(request, error) {
|
|
1345
1416
|
const runtimeError = normalizeError(error);
|
|
@@ -1432,6 +1503,8 @@ function operatorHintFor(code) {
|
|
|
1432
1503
|
RuntimeConfigError,
|
|
1433
1504
|
buildOpenRouterServerTools,
|
|
1434
1505
|
compileRuntimeRequest,
|
|
1435
|
-
|
|
1506
|
+
createConsoleLogger,
|
|
1507
|
+
createOpenRouterRuntime,
|
|
1508
|
+
isRuntimeLoggingEnabled
|
|
1436
1509
|
});
|
|
1437
1510
|
//# sourceMappingURL=index.cjs.map
|