omnigateway 0.6.0 → 0.7.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 +20 -4
- package/bin/omni.js +215 -34
- package/gateway.js +256 -46
- package/package.json +1 -1
- package/public/assets/{_app.console-CZiI6B3b.js → _app.console-D6lrTxJt.js} +2 -2
- package/public/assets/_app.index-DUFa7RRT.js +62 -0
- package/public/assets/{_app.models-eOJ6ofIb.js → _app.models-CDpbIYHW.js} +1 -1
- package/public/assets/{client-Pvf9SEam.js → client-_6YMm6vh.js} +1 -1
- package/public/assets/{index-Cn4_VeBU.js → index-BRrBGt1i.js} +3 -3
- package/public/assets/stream-BD4FhzLn.js +1 -0
- package/public/index.html +2 -2
- package/public/shared/dashboard-sdk.js +1 -1
- package/public/assets/_app.index-BZCUXxIF.js +0 -62
- package/public/assets/stream-BXI9HD3l.js +0 -1
package/gateway.js
CHANGED
|
@@ -6795,6 +6795,7 @@ var MIGRATIONS = [
|
|
|
6795
6795
|
function openDb(path) {
|
|
6796
6796
|
const db = new Database(path, { create: true });
|
|
6797
6797
|
db.run("PRAGMA journal_mode = WAL");
|
|
6798
|
+
db.run("PRAGMA synchronous = NORMAL");
|
|
6798
6799
|
db.run("PRAGMA foreign_keys = ON");
|
|
6799
6800
|
db.run("PRAGMA busy_timeout = 5000");
|
|
6800
6801
|
db.run("CREATE TABLE IF NOT EXISTS migrations (id INTEGER PRIMARY KEY, applied_at INTEGER NOT NULL)");
|
|
@@ -7163,6 +7164,18 @@ function estimateInputTokens(request) {
|
|
|
7163
7164
|
total += toolTokens(tool);
|
|
7164
7165
|
return total;
|
|
7165
7166
|
}
|
|
7167
|
+
function estimateInputPrefixes(request) {
|
|
7168
|
+
let tools = 0;
|
|
7169
|
+
for (const tool of request.tools ?? [])
|
|
7170
|
+
tools += toolTokens(tool);
|
|
7171
|
+
let toolsAndSystem = tools;
|
|
7172
|
+
for (const block of request.system ?? [])
|
|
7173
|
+
toolsAndSystem += blockTokens(block);
|
|
7174
|
+
let total = toolsAndSystem;
|
|
7175
|
+
for (const message of request.messages)
|
|
7176
|
+
total += messageTokens(message);
|
|
7177
|
+
return { tools, toolsAndSystem, total };
|
|
7178
|
+
}
|
|
7166
7179
|
function estimateCachedInputTokens(request) {
|
|
7167
7180
|
let running = 0;
|
|
7168
7181
|
let cached = 0;
|
|
@@ -24697,7 +24710,7 @@ import { join as join3 } from "path";
|
|
|
24697
24710
|
|
|
24698
24711
|
// packages/plugin-api/src/version.ts
|
|
24699
24712
|
var PLUGIN_API_VERSION = 2;
|
|
24700
|
-
var DASHBOARD_SDK_VERSION = "0.1.
|
|
24713
|
+
var DASHBOARD_SDK_VERSION = "0.1.4";
|
|
24701
24714
|
// packages/plugin-api/src/manifest.ts
|
|
24702
24715
|
var CAPABILITIES = [
|
|
24703
24716
|
"storage",
|
|
@@ -25427,47 +25440,77 @@ var PROFILES = {
|
|
|
25427
25440
|
Object.setPrototypeOf(PROFILES, null);
|
|
25428
25441
|
|
|
25429
25442
|
// packages/providers/src/sse.ts
|
|
25443
|
+
var HOLDBACK = 2;
|
|
25444
|
+
var MAX_RECORD_CHARS = 10 * 1024 * 1024;
|
|
25430
25445
|
async function* parseSse(body) {
|
|
25431
25446
|
const reader = body.getReader();
|
|
25432
25447
|
const decoder3 = new TextDecoder;
|
|
25433
|
-
|
|
25448
|
+
const pending = [];
|
|
25449
|
+
let pendingChars = 0;
|
|
25450
|
+
let tail = "";
|
|
25434
25451
|
try {
|
|
25435
25452
|
while (true) {
|
|
25436
25453
|
const { done, value } = await reader.read();
|
|
25437
25454
|
if (done)
|
|
25438
25455
|
break;
|
|
25439
|
-
|
|
25440
|
-
|
|
25441
|
-
|
|
25442
|
-
`);
|
|
25443
|
-
let sep2 = buf.indexOf(`
|
|
25444
|
-
|
|
25456
|
+
const probe = tail + decoder3.decode(value, { stream: true });
|
|
25457
|
+
let start = 0;
|
|
25458
|
+
let nl = probe.indexOf(`
|
|
25445
25459
|
`);
|
|
25446
|
-
while (
|
|
25447
|
-
const
|
|
25448
|
-
|
|
25460
|
+
while (nl !== -1) {
|
|
25461
|
+
const end = separatorEnd(probe, nl);
|
|
25462
|
+
if (end === -1) {
|
|
25463
|
+
nl = probe.indexOf(`
|
|
25464
|
+
`, nl + 1);
|
|
25465
|
+
continue;
|
|
25466
|
+
}
|
|
25467
|
+
refuseIfOversized(pendingChars + (nl - start));
|
|
25468
|
+
pending.push(probe.slice(start, nl));
|
|
25469
|
+
const record2 = pending.join("");
|
|
25470
|
+
pending.length = 0;
|
|
25471
|
+
pendingChars = 0;
|
|
25449
25472
|
const msg = parseRecord(record2);
|
|
25450
25473
|
if (msg)
|
|
25451
25474
|
yield msg;
|
|
25452
|
-
|
|
25453
|
-
|
|
25454
|
-
|
|
25455
|
-
}
|
|
25456
|
-
|
|
25457
|
-
|
|
25458
|
-
|
|
25459
|
-
|
|
25460
|
-
|
|
25461
|
-
|
|
25475
|
+
start = end;
|
|
25476
|
+
nl = probe.indexOf(`
|
|
25477
|
+
`, end);
|
|
25478
|
+
}
|
|
25479
|
+
const keep2 = Math.min(HOLDBACK, probe.length - start);
|
|
25480
|
+
const settled = probe.slice(start, probe.length - keep2);
|
|
25481
|
+
if (settled.length > 0) {
|
|
25482
|
+
pending.push(settled);
|
|
25483
|
+
pendingChars += settled.length;
|
|
25484
|
+
}
|
|
25485
|
+
tail = probe.slice(probe.length - keep2);
|
|
25486
|
+
refuseIfOversized(pendingChars + tail.length);
|
|
25487
|
+
}
|
|
25488
|
+
const last = parseRecord(pending.join("") + tail);
|
|
25489
|
+
if (last)
|
|
25490
|
+
yield last;
|
|
25462
25491
|
} finally {
|
|
25463
25492
|
reader.releaseLock();
|
|
25464
25493
|
}
|
|
25465
25494
|
}
|
|
25495
|
+
function refuseIfOversized(chars) {
|
|
25496
|
+
if (chars <= MAX_RECORD_CHARS)
|
|
25497
|
+
return;
|
|
25498
|
+
throw new GatewayError("UPSTREAM", `upstream SSE record exceeded ${MAX_RECORD_CHARS} characters`, { gatewayAuthored: true });
|
|
25499
|
+
}
|
|
25500
|
+
function separatorEnd(text, at) {
|
|
25501
|
+
const next = text.charCodeAt(at + 1);
|
|
25502
|
+
if (next === 10)
|
|
25503
|
+
return at + 2;
|
|
25504
|
+
if (next === 13 && text.charCodeAt(at + 2) === 10)
|
|
25505
|
+
return at + 3;
|
|
25506
|
+
return -1;
|
|
25507
|
+
}
|
|
25466
25508
|
function parseRecord(record2) {
|
|
25467
25509
|
let event = "message";
|
|
25468
25510
|
const data = [];
|
|
25469
|
-
for (const
|
|
25511
|
+
for (const rawLine of record2.split(`
|
|
25470
25512
|
`)) {
|
|
25513
|
+
const line = rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine;
|
|
25471
25514
|
if (line.length === 0 || line.startsWith(":"))
|
|
25472
25515
|
continue;
|
|
25473
25516
|
const colon = line.indexOf(":");
|
|
@@ -25959,7 +26002,7 @@ async function* decodeAnthropic(messages, opts = {}) {
|
|
|
25959
26002
|
case "message_delta": {
|
|
25960
26003
|
const reason = d.delta?.stop_reason;
|
|
25961
26004
|
if (typeof reason === "string") {
|
|
25962
|
-
const mapped = STOP_REASON[reason];
|
|
26005
|
+
const mapped = Object.hasOwn(STOP_REASON, reason) ? STOP_REASON[reason] : undefined;
|
|
25963
26006
|
if (mapped === undefined) {
|
|
25964
26007
|
yield protocolError(`unrecognized Anthropic stop reason "${reason}"`);
|
|
25965
26008
|
return;
|
|
@@ -25989,7 +26032,7 @@ async function* decodeAnthropic(messages, opts = {}) {
|
|
|
25989
26032
|
terminal = true;
|
|
25990
26033
|
const type = String(d.error?.type);
|
|
25991
26034
|
const message = String(d.error?.message ?? "upstream error");
|
|
25992
|
-
const code = isFingerprintRefusal(type, message) ? "FINGERPRINT_REFUSED" : ERROR_TYPE[type] ?? "UPSTREAM";
|
|
26035
|
+
const code = isFingerprintRefusal(type, message) ? "FINGERPRINT_REFUSED" : (Object.hasOwn(ERROR_TYPE, type) ? ERROR_TYPE[type] : undefined) ?? "UPSTREAM";
|
|
25993
26036
|
yield { type: "error", code, message, retryable: RETRYABLE[code] };
|
|
25994
26037
|
break;
|
|
25995
26038
|
}
|
|
@@ -26195,14 +26238,15 @@ function addAutoCacheBreakpoints(body, req, note) {
|
|
|
26195
26238
|
let markedPrefix = 0;
|
|
26196
26239
|
const worthAMarker = (prefix) => prefix - markedPrefix >= AUTO_CACHE_MIN_TOKENS;
|
|
26197
26240
|
let stablePrefixMarked = false;
|
|
26198
|
-
const
|
|
26241
|
+
const prefixes = estimateInputPrefixes(req);
|
|
26242
|
+
const toolsPrefix = prefixes.tools;
|
|
26199
26243
|
const lastTool = body.tools?.at(-1);
|
|
26200
26244
|
if (lastTool !== undefined && worthAMarker(toolsPrefix)) {
|
|
26201
26245
|
lastTool.cache_control = { type: "ephemeral" };
|
|
26202
26246
|
markedPrefix = toolsPrefix;
|
|
26203
26247
|
stablePrefixMarked = true;
|
|
26204
26248
|
}
|
|
26205
|
-
const systemPrefix =
|
|
26249
|
+
const systemPrefix = prefixes.toolsAndSystem;
|
|
26206
26250
|
const lastSystem = body.system?.at(-1);
|
|
26207
26251
|
if (lastSystem !== undefined && worthAMarker(systemPrefix)) {
|
|
26208
26252
|
lastSystem.cache_control = { type: "ephemeral" };
|
|
@@ -26211,7 +26255,7 @@ function addAutoCacheBreakpoints(body, req, note) {
|
|
|
26211
26255
|
}
|
|
26212
26256
|
if (stablePrefixMarked)
|
|
26213
26257
|
note("anthropic:cache-breakpoint-added");
|
|
26214
|
-
if (!worthAMarker(
|
|
26258
|
+
if (!worthAMarker(prefixes.total))
|
|
26215
26259
|
return;
|
|
26216
26260
|
const lastHistory = lastCacheableHistoryBlock(body.messages);
|
|
26217
26261
|
if (lastHistory === undefined)
|
|
@@ -26506,7 +26550,18 @@ async function* decodeCustomChat(messages) {
|
|
|
26506
26550
|
}
|
|
26507
26551
|
}
|
|
26508
26552
|
if (typeof choice.finish_reason === "string") {
|
|
26509
|
-
|
|
26553
|
+
const reason = choice.finish_reason;
|
|
26554
|
+
const mapped = Object.hasOwn(CHAT_FINISH, reason) ? CHAT_FINISH[reason] : undefined;
|
|
26555
|
+
if (mapped === undefined) {
|
|
26556
|
+
yield {
|
|
26557
|
+
type: "error",
|
|
26558
|
+
code: "UPSTREAM",
|
|
26559
|
+
message: `unrecognized custom endpoint finish reason "${reason}"`,
|
|
26560
|
+
retryable: false
|
|
26561
|
+
};
|
|
26562
|
+
return;
|
|
26563
|
+
}
|
|
26564
|
+
stopReason = mapped;
|
|
26510
26565
|
}
|
|
26511
26566
|
}
|
|
26512
26567
|
if (done) {
|
|
@@ -26530,6 +26585,32 @@ var RESPONSES_ERROR_CODE = {
|
|
|
26530
26585
|
context_length_exceeded: "BAD_REQUEST",
|
|
26531
26586
|
content_policy_violation: "CONTENT_FILTER"
|
|
26532
26587
|
};
|
|
26588
|
+
var KNOWN_RESPONSES_EVENTS = new Set([
|
|
26589
|
+
"response.created",
|
|
26590
|
+
"response.queued",
|
|
26591
|
+
"response.in_progress",
|
|
26592
|
+
"response.output_item.added",
|
|
26593
|
+
"response.output_item.done",
|
|
26594
|
+
"response.content_part.added",
|
|
26595
|
+
"response.content_part.done",
|
|
26596
|
+
"response.output_text.delta",
|
|
26597
|
+
"response.output_text.done",
|
|
26598
|
+
"response.output_text.annotation.added",
|
|
26599
|
+
"response.refusal.delta",
|
|
26600
|
+
"response.refusal.done",
|
|
26601
|
+
"response.reasoning_summary_part.added",
|
|
26602
|
+
"response.reasoning_summary_part.done",
|
|
26603
|
+
"response.reasoning_summary_text.delta",
|
|
26604
|
+
"response.reasoning_summary_text.done",
|
|
26605
|
+
"response.reasoning_text.delta",
|
|
26606
|
+
"response.reasoning_text.done",
|
|
26607
|
+
"response.function_call_arguments.delta",
|
|
26608
|
+
"response.function_call_arguments.done",
|
|
26609
|
+
"response.completed",
|
|
26610
|
+
"response.incomplete",
|
|
26611
|
+
"response.failed",
|
|
26612
|
+
"error"
|
|
26613
|
+
]);
|
|
26533
26614
|
async function* decodeCustomResponses(messages) {
|
|
26534
26615
|
const indices = new Map;
|
|
26535
26616
|
let next = 0;
|
|
@@ -26546,6 +26627,17 @@ async function* decodeCustomResponses(messages) {
|
|
|
26546
26627
|
let terminal = false;
|
|
26547
26628
|
const ownsBlock = new Set;
|
|
26548
26629
|
for await (const msg of messages) {
|
|
26630
|
+
if (msg.data === "[DONE]")
|
|
26631
|
+
continue;
|
|
26632
|
+
if (!KNOWN_RESPONSES_EVENTS.has(msg.event)) {
|
|
26633
|
+
yield {
|
|
26634
|
+
type: "error",
|
|
26635
|
+
code: "UPSTREAM",
|
|
26636
|
+
message: `unrecognized custom endpoint stream event "${msg.event}"`,
|
|
26637
|
+
retryable: false
|
|
26638
|
+
};
|
|
26639
|
+
return;
|
|
26640
|
+
}
|
|
26549
26641
|
const d = json3(msg.data);
|
|
26550
26642
|
if (d === null)
|
|
26551
26643
|
continue;
|
|
@@ -26627,6 +26719,15 @@ async function* decodeCustomResponses(messages) {
|
|
|
26627
26719
|
stopReason = "maxTokens";
|
|
26628
26720
|
else if (reason === "content_filter")
|
|
26629
26721
|
stopReason = "contentFilter";
|
|
26722
|
+
else if (reason !== undefined || msg.event === "response.incomplete" || r.status !== undefined && r.status !== "completed") {
|
|
26723
|
+
yield {
|
|
26724
|
+
type: "error",
|
|
26725
|
+
code: "UPSTREAM",
|
|
26726
|
+
message: reason !== undefined ? `unrecognized custom endpoint incomplete reason "${String(reason)}"` : r.status !== undefined && r.status !== "incomplete" ? `custom endpoint reported terminal response status "${String(r.status)}"` : "custom endpoint reported the response incomplete without a reason",
|
|
26727
|
+
retryable: false
|
|
26728
|
+
};
|
|
26729
|
+
break;
|
|
26730
|
+
}
|
|
26630
26731
|
yield {
|
|
26631
26732
|
type: "end",
|
|
26632
26733
|
stopReason,
|
|
@@ -26638,7 +26739,8 @@ async function* decodeCustomResponses(messages) {
|
|
|
26638
26739
|
case "error": {
|
|
26639
26740
|
terminal = true;
|
|
26640
26741
|
const err = d.response?.error ?? d.error ?? {};
|
|
26641
|
-
const
|
|
26742
|
+
const raw = String(err.code ?? err.type);
|
|
26743
|
+
const code = (Object.hasOwn(RESPONSES_ERROR_CODE, raw) ? RESPONSES_ERROR_CODE[raw] : undefined) ?? "UPSTREAM";
|
|
26642
26744
|
yield {
|
|
26643
26745
|
type: "error",
|
|
26644
26746
|
code,
|
|
@@ -27091,6 +27193,15 @@ async function* decodeGrokResponses(messages) {
|
|
|
27091
27193
|
stopReason = "maxTokens";
|
|
27092
27194
|
else if (reason === "content_filter")
|
|
27093
27195
|
stopReason = "contentFilter";
|
|
27196
|
+
else if (reason !== undefined || msg.event === "response.incomplete" || r.status !== undefined && r.status !== "completed") {
|
|
27197
|
+
yield {
|
|
27198
|
+
type: "error",
|
|
27199
|
+
code: "UPSTREAM",
|
|
27200
|
+
message: reason !== undefined ? `unrecognized xAI incomplete reason "${String(reason)}"` : r.status !== undefined && r.status !== "incomplete" ? `xAI reported terminal response status "${String(r.status)}"` : "xAI reported the response incomplete without a reason",
|
|
27201
|
+
retryable: false
|
|
27202
|
+
};
|
|
27203
|
+
break;
|
|
27204
|
+
}
|
|
27094
27205
|
yield {
|
|
27095
27206
|
type: "end",
|
|
27096
27207
|
stopReason,
|
|
@@ -27102,7 +27213,8 @@ async function* decodeGrokResponses(messages) {
|
|
|
27102
27213
|
case "error": {
|
|
27103
27214
|
terminal = true;
|
|
27104
27215
|
const err = d.response?.error ?? d.error ?? {};
|
|
27105
|
-
const
|
|
27216
|
+
const raw = String(err.code ?? err.type);
|
|
27217
|
+
const code = (Object.hasOwn(ERROR_CODE, raw) ? ERROR_CODE[raw] : undefined) ?? "UPSTREAM";
|
|
27106
27218
|
yield {
|
|
27107
27219
|
type: "error",
|
|
27108
27220
|
code,
|
|
@@ -27518,7 +27630,18 @@ async function* decodeKiloChat(messages) {
|
|
|
27518
27630
|
}
|
|
27519
27631
|
}
|
|
27520
27632
|
if (typeof choice.finish_reason === "string") {
|
|
27521
|
-
|
|
27633
|
+
const reason = choice.finish_reason;
|
|
27634
|
+
const mapped = Object.hasOwn(FINISH, reason) ? FINISH[reason] : undefined;
|
|
27635
|
+
if (mapped === undefined) {
|
|
27636
|
+
yield {
|
|
27637
|
+
type: "error",
|
|
27638
|
+
code: "UPSTREAM",
|
|
27639
|
+
message: `unrecognized Kilo finish reason "${reason}"`,
|
|
27640
|
+
retryable: false
|
|
27641
|
+
};
|
|
27642
|
+
return;
|
|
27643
|
+
}
|
|
27644
|
+
stopReason = mapped;
|
|
27522
27645
|
}
|
|
27523
27646
|
}
|
|
27524
27647
|
if (done) {
|
|
@@ -27805,7 +27928,18 @@ async function* decodeChat(messages) {
|
|
|
27805
27928
|
}
|
|
27806
27929
|
}
|
|
27807
27930
|
if (typeof choice.finish_reason === "string") {
|
|
27808
|
-
|
|
27931
|
+
const reason = choice.finish_reason;
|
|
27932
|
+
const mapped = Object.hasOwn(FINISH2, reason) ? FINISH2[reason] : undefined;
|
|
27933
|
+
if (mapped === undefined) {
|
|
27934
|
+
yield {
|
|
27935
|
+
type: "error",
|
|
27936
|
+
code: "UPSTREAM",
|
|
27937
|
+
message: `unrecognized Kimi finish reason "${reason}"`,
|
|
27938
|
+
retryable: false
|
|
27939
|
+
};
|
|
27940
|
+
return;
|
|
27941
|
+
}
|
|
27942
|
+
stopReason = mapped;
|
|
27809
27943
|
}
|
|
27810
27944
|
}
|
|
27811
27945
|
if (done) {
|
|
@@ -27963,6 +28097,32 @@ var ERROR_CODE2 = {
|
|
|
27963
28097
|
context_length_exceeded: "BAD_REQUEST",
|
|
27964
28098
|
content_policy_violation: "CONTENT_FILTER"
|
|
27965
28099
|
};
|
|
28100
|
+
var KNOWN_EVENTS3 = new Set([
|
|
28101
|
+
"response.created",
|
|
28102
|
+
"response.queued",
|
|
28103
|
+
"response.in_progress",
|
|
28104
|
+
"response.output_item.added",
|
|
28105
|
+
"response.output_item.done",
|
|
28106
|
+
"response.content_part.added",
|
|
28107
|
+
"response.content_part.done",
|
|
28108
|
+
"response.output_text.delta",
|
|
28109
|
+
"response.output_text.done",
|
|
28110
|
+
"response.output_text.annotation.added",
|
|
28111
|
+
"response.refusal.delta",
|
|
28112
|
+
"response.refusal.done",
|
|
28113
|
+
"response.reasoning_summary_part.added",
|
|
28114
|
+
"response.reasoning_summary_part.done",
|
|
28115
|
+
"response.reasoning_summary_text.delta",
|
|
28116
|
+
"response.reasoning_summary_text.done",
|
|
28117
|
+
"response.reasoning_text.delta",
|
|
28118
|
+
"response.reasoning_text.done",
|
|
28119
|
+
"response.function_call_arguments.delta",
|
|
28120
|
+
"response.function_call_arguments.done",
|
|
28121
|
+
"response.completed",
|
|
28122
|
+
"response.incomplete",
|
|
28123
|
+
"response.failed",
|
|
28124
|
+
"error"
|
|
28125
|
+
]);
|
|
27966
28126
|
function json7(data) {
|
|
27967
28127
|
try {
|
|
27968
28128
|
const v = JSON.parse(data);
|
|
@@ -27987,6 +28147,17 @@ async function* decodeResponses(messages) {
|
|
|
27987
28147
|
let terminal = false;
|
|
27988
28148
|
const ownsBlock = new Set;
|
|
27989
28149
|
for await (const msg of messages) {
|
|
28150
|
+
if (msg.data === "[DONE]")
|
|
28151
|
+
continue;
|
|
28152
|
+
if (!KNOWN_EVENTS3.has(msg.event)) {
|
|
28153
|
+
yield {
|
|
28154
|
+
type: "error",
|
|
28155
|
+
code: "UPSTREAM",
|
|
28156
|
+
message: `unrecognized OpenAI stream event "${msg.event}"`,
|
|
28157
|
+
retryable: false
|
|
28158
|
+
};
|
|
28159
|
+
return;
|
|
28160
|
+
}
|
|
27990
28161
|
const d = json7(msg.data);
|
|
27991
28162
|
if (d === null)
|
|
27992
28163
|
continue;
|
|
@@ -28068,6 +28239,15 @@ async function* decodeResponses(messages) {
|
|
|
28068
28239
|
stopReason = "maxTokens";
|
|
28069
28240
|
else if (reason === "content_filter")
|
|
28070
28241
|
stopReason = "contentFilter";
|
|
28242
|
+
else if (reason !== undefined || msg.event === "response.incomplete" || r.status !== undefined && r.status !== "completed") {
|
|
28243
|
+
yield {
|
|
28244
|
+
type: "error",
|
|
28245
|
+
code: "UPSTREAM",
|
|
28246
|
+
message: reason !== undefined ? `unrecognized OpenAI incomplete reason "${String(reason)}"` : r.status !== undefined && r.status !== "incomplete" ? `OpenAI reported terminal response status "${String(r.status)}"` : "OpenAI reported the response incomplete without a reason",
|
|
28247
|
+
retryable: false
|
|
28248
|
+
};
|
|
28249
|
+
break;
|
|
28250
|
+
}
|
|
28071
28251
|
yield {
|
|
28072
28252
|
type: "end",
|
|
28073
28253
|
stopReason,
|
|
@@ -28079,7 +28259,8 @@ async function* decodeResponses(messages) {
|
|
|
28079
28259
|
case "error": {
|
|
28080
28260
|
terminal = true;
|
|
28081
28261
|
const err = d.response?.error ?? d.error ?? {};
|
|
28082
|
-
const
|
|
28262
|
+
const raw = String(err.code ?? err.type);
|
|
28263
|
+
const code = (Object.hasOwn(ERROR_CODE2, raw) ? ERROR_CODE2[raw] : undefined) ?? "UPSTREAM";
|
|
28083
28264
|
yield {
|
|
28084
28265
|
type: "error",
|
|
28085
28266
|
code,
|
|
@@ -44438,7 +44619,7 @@ class SlidingWindow {
|
|
|
44438
44619
|
aged++;
|
|
44439
44620
|
}
|
|
44440
44621
|
if (aged > 0)
|
|
44441
|
-
this.stamps
|
|
44622
|
+
this.stamps.splice(0, aged);
|
|
44442
44623
|
return this.stamps.length;
|
|
44443
44624
|
}
|
|
44444
44625
|
record(now) {
|
|
@@ -44533,6 +44714,7 @@ function retryAfterMs(violation, now) {
|
|
|
44533
44714
|
// apps/gateway/src/auth/rateLimit.ts
|
|
44534
44715
|
var LONG_WINDOWS = ["5h", "1w"];
|
|
44535
44716
|
var CACHE_TTL_MS = 30000;
|
|
44717
|
+
var CLEANUP_INTERVAL_MS = 1000;
|
|
44536
44718
|
var EAGER_FRACTION = 0.9;
|
|
44537
44719
|
var MAX_DEBITS = 1e4;
|
|
44538
44720
|
|
|
@@ -44604,6 +44786,7 @@ function trimDebits(debits, now) {
|
|
|
44604
44786
|
|
|
44605
44787
|
class ApiKeyRateLimiter {
|
|
44606
44788
|
keys = new Map;
|
|
44789
|
+
lastCleanup = Number.NEGATIVE_INFINITY;
|
|
44607
44790
|
store;
|
|
44608
44791
|
now;
|
|
44609
44792
|
logger;
|
|
@@ -44694,6 +44877,9 @@ class ApiKeyRateLimiter {
|
|
|
44694
44877
|
pendingDebits(keyId) {
|
|
44695
44878
|
return this.keys.get(keyId)?.debits.length ?? 0;
|
|
44696
44879
|
}
|
|
44880
|
+
liveKeys() {
|
|
44881
|
+
return this.keys.size;
|
|
44882
|
+
}
|
|
44697
44883
|
async refuse(keyId, decision, now, requestId) {
|
|
44698
44884
|
const violation = decision.violation;
|
|
44699
44885
|
if (violation === null)
|
|
@@ -44803,6 +44989,10 @@ class ApiKeyRateLimiter {
|
|
|
44803
44989
|
}
|
|
44804
44990
|
}
|
|
44805
44991
|
cleanup(now) {
|
|
44992
|
+
const since = now - this.lastCleanup;
|
|
44993
|
+
if (since >= 0 && since < CLEANUP_INTERVAL_MS)
|
|
44994
|
+
return;
|
|
44995
|
+
this.lastCleanup = now;
|
|
44806
44996
|
for (const [keyId, state] of this.keys) {
|
|
44807
44997
|
state.ring.count(now);
|
|
44808
44998
|
if (state.deciding > 0 || !state.ring.empty || state.inFlight > 0)
|
|
@@ -46340,6 +46530,9 @@ function extractToken(header) {
|
|
|
46340
46530
|
|
|
46341
46531
|
// apps/gateway/src/bodyCapture.ts
|
|
46342
46532
|
var MAX_CAPTURED_BODY_BYTES = MAX_ARTIFACT_BYTES;
|
|
46533
|
+
function textOf(entry) {
|
|
46534
|
+
return entry.responseChunks.join("");
|
|
46535
|
+
}
|
|
46343
46536
|
function asBody(text) {
|
|
46344
46537
|
if (text.length === 0)
|
|
46345
46538
|
return null;
|
|
@@ -46394,18 +46587,18 @@ function createBodyCollector(options) {
|
|
|
46394
46587
|
continue;
|
|
46395
46588
|
}
|
|
46396
46589
|
bytes += value.byteLength;
|
|
46397
|
-
entry.
|
|
46590
|
+
entry.responseChunks.push(decoder3.decode(value, { stream: true }));
|
|
46398
46591
|
if (bytes > MAX_CAPTURED_BODY_BYTES)
|
|
46399
46592
|
entry.truncated = true;
|
|
46400
46593
|
}
|
|
46401
|
-
entry.
|
|
46594
|
+
entry.responseChunks.push(decoder3.decode());
|
|
46402
46595
|
} catch {
|
|
46403
46596
|
entry.truncated = true;
|
|
46404
46597
|
} finally {
|
|
46405
46598
|
reader.releaseLock();
|
|
46406
46599
|
}
|
|
46407
46600
|
if (options.captureStreamChunks)
|
|
46408
|
-
entry.frames = framesOf(entry
|
|
46601
|
+
entry.frames = framesOf(textOf(entry));
|
|
46409
46602
|
};
|
|
46410
46603
|
const captureResponse = (res, entry) => {
|
|
46411
46604
|
let forAdapter;
|
|
@@ -46428,11 +46621,12 @@ function createBodyCollector(options) {
|
|
|
46428
46621
|
text: async () => {
|
|
46429
46622
|
const text = await res.text();
|
|
46430
46623
|
entry.responded = true;
|
|
46431
|
-
|
|
46432
|
-
|
|
46624
|
+
const kept = text.slice(0, MAX_CAPTURED_BODY_BYTES);
|
|
46625
|
+
entry.responseChunks = [kept];
|
|
46626
|
+
if (kept.length < text.length)
|
|
46433
46627
|
entry.truncated = true;
|
|
46434
46628
|
if (options.captureStreamChunks)
|
|
46435
|
-
entry.frames = framesOf(
|
|
46629
|
+
entry.frames = framesOf(kept);
|
|
46436
46630
|
return text;
|
|
46437
46631
|
}
|
|
46438
46632
|
};
|
|
@@ -46445,7 +46639,7 @@ function createBodyCollector(options) {
|
|
|
46445
46639
|
attempt: attempts.length + 1,
|
|
46446
46640
|
provider: req.provider,
|
|
46447
46641
|
request: req.body.length > MAX_CAPTURED_BODY_BYTES ? req.body.slice(0, MAX_CAPTURED_BODY_BYTES) : asBody(req.body),
|
|
46448
|
-
|
|
46642
|
+
responseChunks: [],
|
|
46449
46643
|
responded: false,
|
|
46450
46644
|
frames: null,
|
|
46451
46645
|
truncated: req.body.length > MAX_CAPTURED_BODY_BYTES
|
|
@@ -46460,7 +46654,7 @@ function createBodyCollector(options) {
|
|
|
46460
46654
|
attempt: entry.attempt,
|
|
46461
46655
|
provider: entry.provider,
|
|
46462
46656
|
request: entry.request,
|
|
46463
|
-
response: entry.responded ? asBody(entry
|
|
46657
|
+
response: entry.responded ? asBody(textOf(entry)) : null,
|
|
46464
46658
|
streamChunks: entry.frames,
|
|
46465
46659
|
truncated: entry.truncated
|
|
46466
46660
|
}));
|
|
@@ -50318,6 +50512,9 @@ function streamRoutes(deps) {
|
|
|
50318
50512
|
return;
|
|
50319
50513
|
}
|
|
50320
50514
|
if (frame2.type === "unsubscribe") {
|
|
50515
|
+
if (topicClass(frame2.topic) === "plugin" && deps.registry.has(id, frame2.topic)) {
|
|
50516
|
+
deps.channels.closed(id, [frame2.topic]);
|
|
50517
|
+
}
|
|
50321
50518
|
deps.registry.unsubscribe(id, frame2.topic);
|
|
50322
50519
|
send(ws, { ...head, type: "ack", topic: frame2.topic });
|
|
50323
50520
|
return;
|
|
@@ -50590,7 +50787,7 @@ function createSocketRegistry(deps = {}) {
|
|
|
50590
50787
|
break;
|
|
50591
50788
|
let status2;
|
|
50592
50789
|
try {
|
|
50593
|
-
status2 = connection.socket.send(
|
|
50790
|
+
status2 = connection.socket.send(frame2);
|
|
50594
50791
|
} catch {
|
|
50595
50792
|
return;
|
|
50596
50793
|
}
|
|
@@ -50599,6 +50796,13 @@ function createSocketRegistry(deps = {}) {
|
|
|
50599
50796
|
connection.queue.shift();
|
|
50600
50797
|
}
|
|
50601
50798
|
};
|
|
50799
|
+
const encode4 = (frame2) => {
|
|
50800
|
+
try {
|
|
50801
|
+
return JSON.stringify(frame2);
|
|
50802
|
+
} catch {
|
|
50803
|
+
return null;
|
|
50804
|
+
}
|
|
50805
|
+
};
|
|
50602
50806
|
const deliver = (connection, frame2) => {
|
|
50603
50807
|
if (connection.queue.length >= capacity) {
|
|
50604
50808
|
connection.queue.shift();
|
|
@@ -50746,16 +50950,22 @@ function createSocketRegistry(deps = {}) {
|
|
|
50746
50950
|
const subscribers = index.get(topic);
|
|
50747
50951
|
if (subscribers === undefined)
|
|
50748
50952
|
return;
|
|
50953
|
+
const payload = encode4(frame2);
|
|
50954
|
+
if (payload === null)
|
|
50955
|
+
return;
|
|
50749
50956
|
for (const id of subscribers) {
|
|
50750
50957
|
const connection = connections.get(id);
|
|
50751
50958
|
if (connection !== undefined)
|
|
50752
|
-
deliver(connection,
|
|
50959
|
+
deliver(connection, payload);
|
|
50753
50960
|
}
|
|
50754
50961
|
},
|
|
50755
50962
|
sendTo(id, frame2) {
|
|
50756
50963
|
const connection = connections.get(id);
|
|
50757
|
-
if (connection
|
|
50758
|
-
|
|
50964
|
+
if (connection === undefined)
|
|
50965
|
+
return;
|
|
50966
|
+
const payload = encode4(frame2);
|
|
50967
|
+
if (payload !== null)
|
|
50968
|
+
deliver(connection, payload);
|
|
50759
50969
|
},
|
|
50760
50970
|
closeAll(code, reason) {
|
|
50761
50971
|
for (const connection of [...connections.values()])
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{A as e,it as t,z as n}from"./Lamp-DN2EKL4m.js";import{a as r,i,r as a,t as o,v as s,y as c}from"./Panel-BCpZVY4U.js";import{_ as l,t as u}from"./Rack-B03tpeW-.js";import{a as d,i as f,r as p}from"./stream-
|
|
1
|
+
import{A as e,it as t,z as n}from"./Lamp-DN2EKL4m.js";import{a as r,i,r as a,t as o,v as s,y as c}from"./Panel-BCpZVY4U.js";import{_ as l,t as u}from"./Rack-B03tpeW-.js";import{a as d,i as f,r as p}from"./stream-BD4FhzLn.js";import{i as m}from"./Field-DI5YTYOX.js";import{useQueryClient as h}from"@tanstack/react-query";import{useLayoutEffect as g,useMemo as _,useRef as v,useState as y}from"react";import{jsx as b,jsxs as x}from"react/jsx-runtime";import S from"styled-components";var C={debug:10,info:20,warn:30,error:40};function w(e){return typeof e==`string`&&e in C}function T(e,t){return!w(t)||e.level===null||C[e.level]>=C[t]}function E(e){if(typeof e!=`object`||!e)return null;let{raw:t,at:n,level:r,msg:i}=e;return typeof t!=`string`||n!==null&&typeof n!=`number`||r!==null&&!w(r)||i!==null&&typeof i!=`string`?null:{raw:t,at:n,level:r,msg:i}}function D(e){if(typeof e!=`object`||!e)return null;let{lines:t}=e;if(!Array.isArray(t))return null;let n=[];for(let e of t){let t=E(e);if(t===null)return null;n.push(t)}return n}var O=[100,200,500],k=[{value:``,label:`All levels`},{value:`debug`,label:`Debug and above`},{value:`info`,label:`Info and above`},{value:`warn`,label:`Warnings and errors`},{value:`error`,label:`Errors only`}],A=S(c)`
|
|
2
2
|
gap: ${({theme:e})=>e.space(2)};
|
|
3
3
|
flex-wrap: wrap;
|
|
4
4
|
`,j=S(m)`
|
|
@@ -41,4 +41,4 @@ import{A as e,it as t,z as n}from"./Lamp-DN2EKL4m.js";import{a as r,i,r as a,t a
|
|
|
41
41
|
`,R=S.code`
|
|
42
42
|
font-family: ${({theme:e})=>e.font.mono};
|
|
43
43
|
word-break: break-all;
|
|
44
|
-
`;function z({read:e}){return e.source===`file`?x(L,{children:[`Reading `,b(R,{children:e.path}),`, named by `,b(R,{children:`OMNI_LOG_FILE`}),`. That variable says where the gateway's output is being captured; it does not redirect it.`]}):e.source===`journal`?x(L,{children:[`Reading the systemd journal for `,b(R,{children:`omnigateway.service`}),`. To read a file instead, redirect the gateway's output to one and point `,b(R,{children:`OMNI_LOG_FILE`}),` at the same path.`]}):null}var B=[],V={read:void 0,lines:B};function H(){let{cadence:o}=l(),c=h(),[m,S]=y(200),[C,w]=y(``),E=t(m,C,o(n,f)),L=E.data,[R,H]=y(V),W=R.read===L?R.lines:B,G=_(()=>[...L?.lines??[],...W].slice(-m),[L,W,m]),K=v(null),q=v(!0);return p(f,e=>{let t=e.kind===`frame`?D(e.payload):null;if(t===null){H({read:L,lines:B}),e.kind===`frame`&&d(c,f);return}let n=t.filter(e=>T(e,C));n.length!==0&&H(e=>({read:L,lines:[...e.read===L?e.lines:[],...n].slice(-m)}))}),g(()=>{let e=K.current;e!==null&&q.current&&G.length>0&&(e.scrollTop=e.scrollHeight)},[G]),x(M,{children:[b(u,{legend:`Console`,title:`Gateway output`,summary:E.isLoading?`Reading the gateway's own output…`:`${e(G.length)} lines of what this process is doing. Requests are in Logs; prompt bodies, tokens and keys are never written here.`,actions:x(A,{children:[b(j,{value:C,"aria-label":`Which levels to show`,onChange:e=>w(e.target.value),children:k.map(e=>b(`option`,{value:e.value,children:e.label},e.value))}),b(j,{value:m,"aria-label":`How many lines to fetch`,onChange:e=>S(Number(e.target.value)),children:O.map(e=>x(`option`,{value:e,children:[`last `,e]},e))})]})}),x(N,{legend:`Process output`,meta:L===void 0?void 0:b(s,{children:U(L)}),flush:!0,children:[L===void 0?null:b(z,{read:L}),b(P,{ref:K,"data-testid":`console-terminal`,onScroll:e=>{let t=e.currentTarget;q.current=t.scrollHeight-t.scrollTop-t.clientHeight<=8},children:E.isError?b(i,{error:E.error,onRetry:()=>void E.refetch()}):E.isLoading?b(`div`,{style:{padding:12},children:b(r,{rows:10})}):L!==void 0&&L.source===`none`?b(a,{legend:`Nothing is capturing this gateway`,message:"Its output is going to a terminal, so there is nothing to read back. To capture it, run the gateway under systemd with `omni service install`, or start it with `omni start`, which redirects output to a file and points OMNI_LOG_FILE at it."}):G.length===0?b(a,{legend:`Nothing to show`,message:C===``?`This log is empty. The gateway writes here when it boots, refreshes a token, or polls a quota.`:`No line in this window is at that level. Widen the filter to see everything.`}):b(F,{children:G.map((e,t)=>b(I,{$level:e.level,children:e.raw},`${e.at??0}-${t}`))})})]})]})}function U(e){return e.source===`file`?`log file`:e.source===`journal`?`systemd journal`:`not captured`}var W=H;export{W as component};
|
|
44
|
+
`;function z({read:e}){return e.source===`file`?x(L,{children:[`Reading `,b(R,{children:e.path}),`, named by `,b(R,{children:`OMNI_LOG_FILE`}),`. That variable says where the gateway's output is being captured; it does not redirect it.`]}):e.source===`journal`?x(L,{children:[`Reading the systemd journal for `,b(R,{children:`omnigateway.service`}),`. To read a file instead, redirect the gateway's output to one and point `,b(R,{children:`OMNI_LOG_FILE`}),` at the same path.`]}):null}var B=[],V={read:void 0,lines:B};function H(){let{cadence:o}=l(),c=h(),[m,S]=y(200),[C,w]=y(``),E=t(m,C,o(n,f)),L=E.data,[R,H]=y(V),W=R.read===L?R.lines:B,G=_(()=>[...L?.lines??[],...W].slice(-m),[L,W,m]),K=v(null),q=v(!0);return p(f,e=>{if(e.kind!==`frame`&&e.kind!==`gap`)return;let t=e.kind===`frame`?D(e.payload):null;if(t===null){H({read:L,lines:B}),e.kind===`frame`&&d(c,f);return}let n=t.filter(e=>T(e,C));n.length!==0&&H(e=>({read:L,lines:[...e.read===L?e.lines:[],...n].slice(-m)}))}),g(()=>{let e=K.current;e!==null&&q.current&&G.length>0&&(e.scrollTop=e.scrollHeight)},[G]),x(M,{children:[b(u,{legend:`Console`,title:`Gateway output`,summary:E.isLoading?`Reading the gateway's own output…`:`${e(G.length)} lines of what this process is doing. Requests are in Logs; prompt bodies, tokens and keys are never written here.`,actions:x(A,{children:[b(j,{value:C,"aria-label":`Which levels to show`,onChange:e=>w(e.target.value),children:k.map(e=>b(`option`,{value:e.value,children:e.label},e.value))}),b(j,{value:m,"aria-label":`How many lines to fetch`,onChange:e=>S(Number(e.target.value)),children:O.map(e=>x(`option`,{value:e,children:[`last `,e]},e))})]})}),x(N,{legend:`Process output`,meta:L===void 0?void 0:b(s,{children:U(L)}),flush:!0,children:[L===void 0?null:b(z,{read:L}),b(P,{ref:K,"data-testid":`console-terminal`,onScroll:e=>{let t=e.currentTarget;q.current=t.scrollHeight-t.scrollTop-t.clientHeight<=8},children:E.isError?b(i,{error:E.error,onRetry:()=>void E.refetch()}):E.isLoading?b(`div`,{style:{padding:12},children:b(r,{rows:10})}):L!==void 0&&L.source===`none`?b(a,{legend:`Nothing is capturing this gateway`,message:"Its output is going to a terminal, so there is nothing to read back. To capture it, run the gateway under systemd with `omni service install`, or start it with `omni start`, which redirects output to a file and points OMNI_LOG_FILE at it."}):G.length===0?b(a,{legend:`Nothing to show`,message:C===``?`This log is empty. The gateway writes here when it boots, refreshes a token, or polls a quota.`:`No line in this window is at that level. Widen the filter to see everything.`}):b(F,{children:G.map((e,t)=>b(I,{$level:e.level,children:e.raw},`${e.at??0}-${t}`))})})]})]})}function U(e){return e.source===`file`?`log file`:e.source===`journal`?`systemd journal`:`not captured`}var W=H;export{W as component};
|