@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 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
- `runtime.run(request)` is non-streaming by design. Use it for background tasks, graph nodes, tool calls, structured output, research jobs, classification, extraction, patch generation, and automation.
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
- ### Why `run()` is not streaming
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
- `run()` is designed for reliable runtime execution, not token-by-token UI delivery.
120
+ ### Streaming lives on a separate method: `executeStreamingChat()`
90
121
 
91
- Most runtime calls are background operations: graph nodes, tool loops, extraction, classification, research, patch generation, and structured output. For those workloads, streaming adds connection complexity without improving the final result.
122
+ Streaming is **not** available through `run()`, and the old `runtime.stream()` name was **removed on purpose**.
92
123
 
93
- When streaming support is added, it will be available through `runtime.stream(request)`, not through `runtime.run(request)`.
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
- // Future API
97
- for await (const event of runtime.stream(request)) {
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, `stream()` is reserved and throws `STREAMING_NOT_IMPLEMENTED`. The package should be treated as a non-streaming runtime.
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
- If `rawOpenRouterOverrides.stream = true` is provided to `runtime.run()`, it is ignored and reported as a `STREAMING_OVERRIDE_IGNORED_FOR_RUN` warning.
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
- createOpenRouterRuntime: () => createOpenRouterRuntime
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 === true) {
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.stream() when streaming is implemented."
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
- max_tokens: request.maxTokens,
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* streamNotImplemented() {
1361
+ async function* executeStreamingChatNotImplemented() {
1310
1362
  throw new RuntimeConfigError(
1311
1363
  "STREAMING_NOT_IMPLEMENTED",
1312
- "Streaming is reserved for a later phase. Use runtime.run() for non-streaming execution."
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", { requestId: requestWithId.id });
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", { requestId: requestWithId.id, status: response.status });
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
- stream: streamNotImplemented
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
- createOpenRouterRuntime
1506
+ createConsoleLogger,
1507
+ createOpenRouterRuntime,
1508
+ isRuntimeLoggingEnabled
1436
1509
  });
1437
1510
  //# sourceMappingURL=index.cjs.map