omnigateway 0.8.0 → 0.9.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 +25 -4
- package/bin/omni.js +112 -22
- package/gateway.js +103 -21
- package/package.json +1 -1
- package/public/assets/{Chip-DG-mqRx0.js → Chip-shturdCv.js} +1 -1
- package/public/assets/{CopyValue-CItB094V.js → CopyValue-BGt9RRTL.js} +1 -1
- package/public/assets/{Field-DK5zaBVA.js → Field-DcNu4yw-.js} +1 -1
- package/public/assets/Lamp-CVGUT2YK.js +25 -0
- package/public/assets/{Panel-CYQvfI3L.js → Panel-BlNr9j6-.js} +3 -1
- package/public/assets/{Rack-xBT_6EtM.js → Rack-BbZyyu2u.js} +5 -5
- package/public/assets/{Readout-D6-aurU8.js → Readout-D8Ofl3Gz.js} +1 -1
- package/public/assets/{RequestTable-CM9mPiMF.js → RequestTable-huSAoNZg.js} +1 -1
- package/public/assets/{SummaryDeck-C3ZwZ3ng.js → SummaryDeck-BPo2bMSC.js} +1 -1
- package/public/assets/{Toggle-CmXXn6F3.js → Toggle-C84xs_YB.js} +1 -1
- package/public/assets/{TokenBreakdown-COJ643vg.js → TokenBreakdown-CmzXuENj.js} +1 -1
- package/public/assets/{WindowChart-BrLf4KCu.js → WindowChart-BZzVrxYk.js} +1 -1
- package/public/assets/{_app-BWNEo1e-.js → _app-CWXzHdhc.js} +1 -1
- package/public/assets/_app.accounts-DMmtkwnl.js +59 -0
- package/public/assets/_app.console-BBz3kCPV.js +44 -0
- package/public/assets/_app.database-ZvtMVgsh.js +24 -0
- package/public/assets/{_app.index-CB3UFRwF.js → _app.index-DKouD-rz.js} +5 -5
- package/public/assets/{_app.keys-B89CMo3x.js → _app.keys-BG9-zfh6.js} +5 -5
- package/public/assets/{_app.logs-CNAnRW07.js → _app.logs-DjinYGYS.js} +2 -2
- package/public/assets/{_app.models-DpRcGhag.js → _app.models-BCfQVuoT.js} +5 -5
- package/public/assets/_app.plugins._pluginId-B9k5eqAt.js +2 -0
- package/public/assets/{_app.plugins._pluginId-sYDTZ9Px.js → _app.plugins._pluginId-Dm48f3wz.js} +1 -1
- package/public/assets/{_app.settings-BV085FpM.js → _app.settings-C42ylcNP.js} +4 -4
- package/public/assets/{_app.usage-CGuOdYun.js → _app.usage-DfPM6eQ-.js} +3 -3
- package/public/assets/{chevron-right-BeVtzzum.js → chevron-right-HI_fK6Gw.js} +1 -1
- package/public/assets/client-TUf0nuim.js +39 -0
- package/public/assets/index-C66Zn0tX.js +13 -0
- package/public/assets/login-DWgivEPK.js +2 -0
- package/public/assets/{login-BpvnkW6i.js → login-w-hVstKf.js} +2 -2
- package/public/assets/plus-BCf2TPqz.js +1 -0
- package/public/assets/{preload-helper-8jyVfd2a.js → preload-helper-Unv7FI91.js} +1 -1
- package/public/assets/{shared-B2Lmnazz.js → shared-XRnr7At9.js} +1 -1
- package/public/assets/{stream-VJMOV03S.js → stream-3PafhwhZ.js} +1 -1
- package/public/assets/{trash-2-CbjLfrko.js → trash-2-Bq4GaXzx.js} +1 -1
- package/public/index.html +8 -8
- package/public/assets/Lamp-Cxp-OxUq.js +0 -25
- package/public/assets/_app.accounts-B-OYO2Yi.js +0 -59
- package/public/assets/_app.console-BOZ1wncA.js +0 -44
- package/public/assets/_app.database-B5oHZPbu.js +0 -24
- package/public/assets/_app.plugins._pluginId-LzBq-Zjj.js +0 -2
- package/public/assets/client-Mf5f5R9Z.js +0 -39
- package/public/assets/index-3lpol4cr.js +0 -13
- package/public/assets/login-CwYbEKWH.js +0 -2
- package/public/assets/plus-nHMFjQ2I.js +0 -1
package/README.md
CHANGED
|
@@ -388,6 +388,7 @@ Use `--db <path>` to point one command somewhere else.
|
|
|
388
388
|
| `omni db backup` / `snapshots` | take a snapshot, and list the ones retention has kept |
|
|
389
389
|
| `omni db restore <id>` | put a snapshot back; shows a live-vs-snapshot count table, then asks. `--dry-run` shows the table and stops |
|
|
390
390
|
| `omni db vacuum` | rewrite the database, reclaiming the pages deletion left free |
|
|
391
|
+
| `omni db clear-bodies` | delete every captured request and response body; the requests stay logged |
|
|
391
392
|
|
|
392
393
|
Two worth knowing:
|
|
393
394
|
|
|
@@ -516,6 +517,15 @@ bun apps/gateway/src/index.ts >> /var/log/omni.log 2>&1
|
|
|
516
517
|
`omni start` does both for the gateway it supervises, and under systemd the journal needs no
|
|
517
518
|
setup.
|
|
518
519
|
|
|
520
|
+
In a fleet, capture is per process. Each replica can capture its own — tee its stdout to a file
|
|
521
|
+
inside the container and point `OMNI_LOG_FILE` at the same path — and the Console screen then
|
|
522
|
+
merges every process's tail and lets you pick one. That is worth having for an incident on a
|
|
523
|
+
running pod, and it is not a log stack: the file dies with the container, nothing rotates it, and
|
|
524
|
+
the screen reads one process at a time. Ship stdout to a collector for anything beyond that —
|
|
525
|
+
Elasticsearch and Kibana, Loki and Grafana, or whatever already reads your containers — where the
|
|
526
|
+
lines outlive the process that wrote them and can be searched across all of them at once. The
|
|
527
|
+
Console screen says so itself when it finds a fleet capturing nothing.
|
|
528
|
+
|
|
519
529
|
Everything else lives in the database rather than the environment, so it can be
|
|
520
530
|
changed without a restart: the six routing weights, `maxAttempts`,
|
|
521
531
|
`requestDeadlineMs`, the circuit breaker's `breakerThreshold` and
|
|
@@ -641,9 +651,12 @@ format, structural bounds, and masking rules.
|
|
|
641
651
|
## Snapshots and restore
|
|
642
652
|
|
|
643
653
|
The console's Database screen reports what this installation occupies — the
|
|
644
|
-
database file, its write-ahead log, the captured-body tree,
|
|
645
|
-
compaction would give back
|
|
646
|
-
figures.
|
|
654
|
+
database file, its write-ahead log, the captured-body tree, the free pages a
|
|
655
|
+
compaction would give back, and every table by size — and takes snapshots.
|
|
656
|
+
`omni db stats` prints the same figures. On Postgres both show the server's own
|
|
657
|
+
size, the `request_bodies` table and the per-table listing instead; there is no
|
|
658
|
+
file, so nothing here compacts, snapshots or restores it — `pg_dump` is the
|
|
659
|
+
backup.
|
|
647
660
|
|
|
648
661
|
**What a snapshot is.** One self-contained SQLite file, written into a
|
|
649
662
|
`snapshots/` directory beside the database. The write-ahead log is folded in, so
|
|
@@ -704,6 +717,12 @@ for the rewrite, so a busy gateway stalls on its writes until it finishes — bu
|
|
|
704
717
|
nothing is lost by running it live, and it reports what it actually gave back to
|
|
705
718
|
the filesystem.
|
|
706
719
|
|
|
720
|
+
**Clearing bodies.** `omni db clear-bodies`, or the Database screen's *Clear
|
|
721
|
+
bodies*, deletes every captured prompt and completion on either engine — the
|
|
722
|
+
files beside a SQLite database, the `request_bodies` rows on Postgres. The
|
|
723
|
+
requests stay in the log with their bodies marked pruned. There is no undo:
|
|
724
|
+
bodies are never in a snapshot.
|
|
725
|
+
|
|
707
726
|
## Docker
|
|
708
727
|
|
|
709
728
|
```bash
|
|
@@ -737,7 +756,9 @@ and the workflow commits that version into `k8s/kustomization.yaml` on `main`, w
|
|
|
737
756
|
CD syncs. Rolling back is editing `newTag` by hand.
|
|
738
757
|
|
|
739
758
|
Plugins in a fleet are baked into the image so every replica holds the same
|
|
740
|
-
set: `COPY plugins/ /data/plugins/` in a derived Dockerfile.
|
|
759
|
+
set: `COPY plugins/ /data/plugins/` in a derived Dockerfile. The image is
|
|
760
|
+
public, so no pull secret is configured; a private fork adds
|
|
761
|
+
`imagePullSecrets` to the Deployment.
|
|
741
762
|
|
|
742
763
|
Give the container a restart policy — `--restart unless-stopped` — if you want a
|
|
743
764
|
restart request to bring it back. A container cannot read its own policy, so
|
package/bin/omni.js
CHANGED
|
@@ -16281,6 +16281,23 @@ function createMaintenanceRepo(sql, nodeId) {
|
|
|
16281
16281
|
schemaVersion: row?.version ?? 0
|
|
16282
16282
|
};
|
|
16283
16283
|
},
|
|
16284
|
+
async tables() {
|
|
16285
|
+
const rows = await sql.unsafe(`SELECT c.relname AS name,
|
|
16286
|
+
pg_total_relation_size(c.oid) AS bytes,
|
|
16287
|
+
GREATEST(c.reltuples, 0)::bigint AS rows,
|
|
16288
|
+
COALESCE(s.n_dead_tup, 0) AS dead_rows
|
|
16289
|
+
FROM pg_class c
|
|
16290
|
+
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
16291
|
+
LEFT JOIN pg_stat_user_tables s ON s.relid = c.oid
|
|
16292
|
+
WHERE c.relkind = 'r' AND n.nspname = current_schema()
|
|
16293
|
+
ORDER BY bytes DESC, name`);
|
|
16294
|
+
return rows.map((row) => ({
|
|
16295
|
+
name: row.name,
|
|
16296
|
+
bytes: num(row.bytes),
|
|
16297
|
+
rows: num(row.rows),
|
|
16298
|
+
deadRows: num(row.dead_rows)
|
|
16299
|
+
}));
|
|
16300
|
+
},
|
|
16284
16301
|
vacuum: async () => unsupported(),
|
|
16285
16302
|
snapshotTo: async () => unsupported(),
|
|
16286
16303
|
inspect: async () => unsupported()
|
|
@@ -17219,6 +17236,7 @@ async function createPostgresStore(opts) {
|
|
|
17219
17236
|
});
|
|
17220
17237
|
};
|
|
17221
17238
|
return {
|
|
17239
|
+
engine: "postgres",
|
|
17222
17240
|
databasePath: redacted(opts.url),
|
|
17223
17241
|
credentials: createCredentialRepo(sql, opts.encryptionKey, emit2),
|
|
17224
17242
|
config: createConfigRepo(sql, emit2),
|
|
@@ -18401,6 +18419,15 @@ function createMaintenanceRepo2(db, nodeId) {
|
|
|
18401
18419
|
schemaVersion: version2?.version ?? 0
|
|
18402
18420
|
};
|
|
18403
18421
|
},
|
|
18422
|
+
async tables() {
|
|
18423
|
+
return db.query(`SELECT m.tbl_name AS name,
|
|
18424
|
+
SUM(s.pgsize) AS bytes,
|
|
18425
|
+
SUM(CASE WHEN s.pagetype = 'leaf' AND s.name = m.tbl_name THEN s.ncell ELSE 0 END) AS rows
|
|
18426
|
+
FROM dbstat s JOIN sqlite_master m ON m.name = s.name
|
|
18427
|
+
WHERE m.tbl_name NOT LIKE 'sqlite_%'
|
|
18428
|
+
GROUP BY m.tbl_name
|
|
18429
|
+
ORDER BY bytes DESC, name`).all().map((row) => ({ ...row, deadRows: null }));
|
|
18430
|
+
},
|
|
18404
18431
|
async vacuum() {
|
|
18405
18432
|
db.run("VACUUM");
|
|
18406
18433
|
db.run("PRAGMA wal_checkpoint(TRUNCATE)");
|
|
@@ -18872,6 +18899,7 @@ async function createStore(opts) {
|
|
|
18872
18899
|
live = false;
|
|
18873
18900
|
};
|
|
18874
18901
|
return {
|
|
18902
|
+
engine: "sqlite",
|
|
18875
18903
|
databasePath: opts.path,
|
|
18876
18904
|
credentials: {
|
|
18877
18905
|
list: () => handle.credentials.list(),
|
|
@@ -18936,6 +18964,7 @@ async function createStore(opts) {
|
|
|
18936
18964
|
},
|
|
18937
18965
|
maintenance: {
|
|
18938
18966
|
stats: () => handle.maintenance.stats(),
|
|
18967
|
+
tables: () => handle.maintenance.tables(),
|
|
18939
18968
|
heartbeat: (now) => handle.maintenance.heartbeat(now),
|
|
18940
18969
|
nodes: (now) => handle.maintenance.nodes(now),
|
|
18941
18970
|
vacuum: () => handle.maintenance.vacuum(),
|
|
@@ -20975,13 +21004,13 @@ function encodeSystemTurn(content, cloak) {
|
|
|
20975
21004
|
return content.map((block) => encodeBlock(block, cloak));
|
|
20976
21005
|
}
|
|
20977
21006
|
function systemCacheControl(req) {
|
|
20978
|
-
const
|
|
20979
|
-
const
|
|
20980
|
-
const
|
|
20981
|
-
const
|
|
21007
|
+
const markedSystemBlocks = req.messages.flatMap((message) => message.role === "system" ? message.content.filter((block) => cacheControlOf(block) !== undefined) : []);
|
|
21008
|
+
const trailing = req.messages.at(-1);
|
|
21009
|
+
const marked = trailing?.role === "system" ? trailing.content.findLast((block) => cacheControlOf(block) !== undefined) : undefined;
|
|
21010
|
+
const retarget = marked === undefined ? undefined : cacheControlOf(marked);
|
|
20982
21011
|
return {
|
|
20983
|
-
...
|
|
20984
|
-
lost: markedSystemBlocks.length > (
|
|
21012
|
+
...retarget === undefined ? {} : { retarget },
|
|
21013
|
+
lost: markedSystemBlocks.length > (retarget === undefined ? 0 : 1)
|
|
20985
21014
|
};
|
|
20986
21015
|
}
|
|
20987
21016
|
function encodeTool(t, cloak) {
|
|
@@ -21143,14 +21172,26 @@ function toWire(req, model, opts) {
|
|
|
21143
21172
|
return [{ role: m.role, content: encodeSystemTurn(m.content, cloak) }];
|
|
21144
21173
|
}),
|
|
21145
21174
|
max_tokens: req.maxTokens ?? 4096,
|
|
21146
|
-
stream: req.stream
|
|
21147
|
-
|
|
21148
|
-
|
|
21149
|
-
|
|
21150
|
-
|
|
21175
|
+
stream: req.stream
|
|
21176
|
+
};
|
|
21177
|
+
if (systemCache.retarget !== undefined) {
|
|
21178
|
+
const trailing = body.messages.at(-1);
|
|
21179
|
+
if (isRecord(trailing) && Array.isArray(trailing.content)) {
|
|
21180
|
+
for (const block of trailing.content) {
|
|
21181
|
+
if (isRecord(block))
|
|
21182
|
+
delete block.cache_control;
|
|
21151
21183
|
}
|
|
21152
21184
|
}
|
|
21153
|
-
|
|
21185
|
+
if (!hasVendorCacheControl(req)) {
|
|
21186
|
+
const target = lastCacheableHistoryBlock(body.messages.slice(0, -1));
|
|
21187
|
+
if (target === undefined) {
|
|
21188
|
+
note2("anthropic:system-turn-cache-control-dropped");
|
|
21189
|
+
} else if (target.cache_control === undefined) {
|
|
21190
|
+
Object.assign(target, wireCacheControl(systemCache.retarget));
|
|
21191
|
+
note2("anthropic:system-turn-cache-control-retargeted");
|
|
21192
|
+
}
|
|
21193
|
+
}
|
|
21194
|
+
}
|
|
21154
21195
|
if (system !== undefined && system.length > 0)
|
|
21155
21196
|
body.system = system;
|
|
21156
21197
|
if (req.temperature !== undefined)
|
|
@@ -25398,6 +25439,11 @@ async function restoreSnapshot(deps, id) {
|
|
|
25398
25439
|
return withExclusive("a restore", () => swapIn(deps, { path, consume: false }));
|
|
25399
25440
|
}
|
|
25400
25441
|
var MAX_IMPORT_BYTES = 2 * 1024 * 1024 * 1024;
|
|
25442
|
+
async function clearBodies(deps) {
|
|
25443
|
+
const removed = await deps.store.bodies.prune(deps.now());
|
|
25444
|
+
const orphans = await deps.store.bodies.sweepOrphans();
|
|
25445
|
+
return { removed, orphans };
|
|
25446
|
+
}
|
|
25401
25447
|
async function vacuum(deps) {
|
|
25402
25448
|
return withExclusive("a vacuum", async () => {
|
|
25403
25449
|
const before = deps.fs.stat(deps.store.databasePath)?.size ?? 0;
|
|
@@ -25412,18 +25458,37 @@ async function vacuum(deps) {
|
|
|
25412
25458
|
}
|
|
25413
25459
|
async function getDatabaseOverview(deps) {
|
|
25414
25460
|
const live = deps.store.databasePath;
|
|
25415
|
-
const stats = await
|
|
25416
|
-
|
|
25461
|
+
const [stats, tables, settings] = await Promise.all([
|
|
25462
|
+
deps.store.maintenance.stats(),
|
|
25463
|
+
deps.store.maintenance.tables(),
|
|
25464
|
+
deps.store.config.getSettings()
|
|
25465
|
+
]);
|
|
25466
|
+
const shared = {
|
|
25467
|
+
engine: deps.store.engine,
|
|
25468
|
+
location: live,
|
|
25469
|
+
stats,
|
|
25470
|
+
logicalBytes: stats.pageSize * stats.pageCount,
|
|
25471
|
+
freePageBytes: stats.pageSize * stats.freelistCount,
|
|
25472
|
+
retention: retentionOf(settings),
|
|
25473
|
+
tables
|
|
25474
|
+
};
|
|
25475
|
+
if (deps.store.engine === "postgres") {
|
|
25476
|
+
return {
|
|
25477
|
+
...shared,
|
|
25478
|
+
fileBytes: 0,
|
|
25479
|
+
walBytes: 0,
|
|
25480
|
+
bodiesBytes: tables.find((table2) => table2.name === "request_bodies")?.bytes ?? 0,
|
|
25481
|
+
freeDiskBytes: null,
|
|
25482
|
+
snapshots: { count: 0, totalBytes: 0, latestAt: null }
|
|
25483
|
+
};
|
|
25484
|
+
}
|
|
25417
25485
|
const snapshots = listSnapshots(deps);
|
|
25418
25486
|
return {
|
|
25419
|
-
|
|
25487
|
+
...shared,
|
|
25420
25488
|
fileBytes: deps.fs.stat(live)?.size ?? 0,
|
|
25421
25489
|
walBytes: deps.fs.stat(`${live}-wal`)?.size ?? 0,
|
|
25422
25490
|
bodiesBytes: deps.fs.dirBytes(bodiesDirFor(live)),
|
|
25423
|
-
logicalBytes: stats.pageSize * stats.pageCount,
|
|
25424
|
-
freePageBytes: stats.pageSize * stats.freelistCount,
|
|
25425
25491
|
freeDiskBytes: deps.fs.freeBytes(dirname2(live)),
|
|
25426
|
-
retention: retentionOf(settings),
|
|
25427
25492
|
snapshots: {
|
|
25428
25493
|
count: snapshots.length,
|
|
25429
25494
|
totalBytes: snapshots.reduce((sum2, snapshot) => sum2 + snapshot.sizeBytes, 0),
|
|
@@ -28447,7 +28512,13 @@ var dbStats = {
|
|
|
28447
28512
|
async run(_args, env2) {
|
|
28448
28513
|
const { ctx, writer } = env2;
|
|
28449
28514
|
const overview = await getDatabaseOverview(await database(env2));
|
|
28450
|
-
|
|
28515
|
+
const tables = table([{ header: "TABLE" }, { header: "SIZE", align: "right" }, { header: "ROWS", align: "right" }], overview.tables.map((t) => [t.name, formatBytes(t.bytes), String(t.rows)]));
|
|
28516
|
+
const summary = overview.engine === "postgres" ? fields([
|
|
28517
|
+
["database", overview.location],
|
|
28518
|
+
["size", formatBytes(overview.logicalBytes)],
|
|
28519
|
+
["captured bodies", `${formatBytes(overview.bodiesBytes)} (request_bodies table)`],
|
|
28520
|
+
["schema version", String(overview.stats.schemaVersion)]
|
|
28521
|
+
]) : fields([
|
|
28451
28522
|
["database", ctx.databasePath],
|
|
28452
28523
|
["size", formatBytes(overview.fileBytes)],
|
|
28453
28524
|
["write-ahead log", formatBytes(overview.walBytes)],
|
|
@@ -28466,7 +28537,10 @@ var dbStats = {
|
|
|
28466
28537
|
"free disk",
|
|
28467
28538
|
overview.freeDiskBytes === null ? "unknown" : formatBytes(overview.freeDiskBytes)
|
|
28468
28539
|
]
|
|
28469
|
-
])
|
|
28540
|
+
]);
|
|
28541
|
+
emit(ctx, writer, overview, () => `${summary}
|
|
28542
|
+
|
|
28543
|
+
${tables}`);
|
|
28470
28544
|
}
|
|
28471
28545
|
};
|
|
28472
28546
|
var dbSnapshots = {
|
|
@@ -28523,6 +28597,21 @@ var dbVacuum = {
|
|
|
28523
28597
|
]));
|
|
28524
28598
|
}
|
|
28525
28599
|
};
|
|
28600
|
+
var dbClearBodies = {
|
|
28601
|
+
usage: "db clear-bodies",
|
|
28602
|
+
summary: "Delete every captured request and response body; the requests stay logged",
|
|
28603
|
+
async run(_args, env2) {
|
|
28604
|
+
const { ctx, writer, prompt } = env2;
|
|
28605
|
+
if (!await prompt.confirm("delete every captured body? there is no snapshot of them")) {
|
|
28606
|
+
throw new CliError("cancelled");
|
|
28607
|
+
}
|
|
28608
|
+
const result = await clearBodies(await database(env2));
|
|
28609
|
+
emit(ctx, writer, result, () => fields([
|
|
28610
|
+
["removed", String(result.removed)],
|
|
28611
|
+
["orphaned files removed", String(result.orphans)]
|
|
28612
|
+
]));
|
|
28613
|
+
}
|
|
28614
|
+
};
|
|
28526
28615
|
function previewTable(preview) {
|
|
28527
28616
|
const live = preview.live;
|
|
28528
28617
|
const names = [...new Set([...Object.keys(preview.snapshot), ...Object.keys(live ?? {})])].sort();
|
|
@@ -29300,7 +29389,7 @@ function createServiceDeps(input) {
|
|
|
29300
29389
|
}
|
|
29301
29390
|
|
|
29302
29391
|
// apps/cli/src/version.ts
|
|
29303
|
-
var VERSION = "0.
|
|
29392
|
+
var VERSION = "0.9.0";
|
|
29304
29393
|
|
|
29305
29394
|
// apps/cli/src/commands/service.ts
|
|
29306
29395
|
function gatewayArgv(root) {
|
|
@@ -29960,7 +30049,8 @@ var COMMANDS = {
|
|
|
29960
30049
|
"db snapshots": dbSnapshots,
|
|
29961
30050
|
"db backup": dbBackup,
|
|
29962
30051
|
"db restore": dbRestore,
|
|
29963
|
-
"db vacuum": dbVacuum
|
|
30052
|
+
"db vacuum": dbVacuum,
|
|
30053
|
+
"db clear-bodies": dbClearBodies
|
|
29964
30054
|
};
|
|
29965
30055
|
var VALUED_GLOBALS = new Set(["--root", "--db"]);
|
|
29966
30056
|
function resolveCommand(argv) {
|
package/gateway.js
CHANGED
|
@@ -21710,6 +21710,23 @@ function createMaintenanceRepo(sql, nodeId) {
|
|
|
21710
21710
|
schemaVersion: row?.version ?? 0
|
|
21711
21711
|
};
|
|
21712
21712
|
},
|
|
21713
|
+
async tables() {
|
|
21714
|
+
const rows = await sql.unsafe(`SELECT c.relname AS name,
|
|
21715
|
+
pg_total_relation_size(c.oid) AS bytes,
|
|
21716
|
+
GREATEST(c.reltuples, 0)::bigint AS rows,
|
|
21717
|
+
COALESCE(s.n_dead_tup, 0) AS dead_rows
|
|
21718
|
+
FROM pg_class c
|
|
21719
|
+
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
21720
|
+
LEFT JOIN pg_stat_user_tables s ON s.relid = c.oid
|
|
21721
|
+
WHERE c.relkind = 'r' AND n.nspname = current_schema()
|
|
21722
|
+
ORDER BY bytes DESC, name`);
|
|
21723
|
+
return rows.map((row) => ({
|
|
21724
|
+
name: row.name,
|
|
21725
|
+
bytes: num(row.bytes),
|
|
21726
|
+
rows: num(row.rows),
|
|
21727
|
+
deadRows: num(row.dead_rows)
|
|
21728
|
+
}));
|
|
21729
|
+
},
|
|
21713
21730
|
vacuum: async () => unsupported(),
|
|
21714
21731
|
snapshotTo: async () => unsupported(),
|
|
21715
21732
|
inspect: async () => unsupported()
|
|
@@ -22648,6 +22665,7 @@ async function createPostgresStore(opts) {
|
|
|
22648
22665
|
});
|
|
22649
22666
|
};
|
|
22650
22667
|
return {
|
|
22668
|
+
engine: "postgres",
|
|
22651
22669
|
databasePath: redacted(opts.url),
|
|
22652
22670
|
credentials: createCredentialRepo(sql, opts.encryptionKey, emit),
|
|
22653
22671
|
config: createConfigRepo(sql, emit),
|
|
@@ -23830,6 +23848,15 @@ function createMaintenanceRepo2(db, nodeId) {
|
|
|
23830
23848
|
schemaVersion: version2?.version ?? 0
|
|
23831
23849
|
};
|
|
23832
23850
|
},
|
|
23851
|
+
async tables() {
|
|
23852
|
+
return db.query(`SELECT m.tbl_name AS name,
|
|
23853
|
+
SUM(s.pgsize) AS bytes,
|
|
23854
|
+
SUM(CASE WHEN s.pagetype = 'leaf' AND s.name = m.tbl_name THEN s.ncell ELSE 0 END) AS rows
|
|
23855
|
+
FROM dbstat s JOIN sqlite_master m ON m.name = s.name
|
|
23856
|
+
WHERE m.tbl_name NOT LIKE 'sqlite_%'
|
|
23857
|
+
GROUP BY m.tbl_name
|
|
23858
|
+
ORDER BY bytes DESC, name`).all().map((row) => ({ ...row, deadRows: null }));
|
|
23859
|
+
},
|
|
23833
23860
|
async vacuum() {
|
|
23834
23861
|
db.run("VACUUM");
|
|
23835
23862
|
db.run("PRAGMA wal_checkpoint(TRUNCATE)");
|
|
@@ -24301,6 +24328,7 @@ async function createStore(opts) {
|
|
|
24301
24328
|
live = false;
|
|
24302
24329
|
};
|
|
24303
24330
|
return {
|
|
24331
|
+
engine: "sqlite",
|
|
24304
24332
|
databasePath: opts.path,
|
|
24305
24333
|
credentials: {
|
|
24306
24334
|
list: () => handle.credentials.list(),
|
|
@@ -24365,6 +24393,7 @@ async function createStore(opts) {
|
|
|
24365
24393
|
},
|
|
24366
24394
|
maintenance: {
|
|
24367
24395
|
stats: () => handle.maintenance.stats(),
|
|
24396
|
+
tables: () => handle.maintenance.tables(),
|
|
24368
24397
|
heartbeat: (now) => handle.maintenance.heartbeat(now),
|
|
24369
24398
|
nodes: (now) => handle.maintenance.nodes(now),
|
|
24370
24399
|
vacuum: () => handle.maintenance.vacuum(),
|
|
@@ -26534,13 +26563,13 @@ function encodeSystemTurn(content, cloak) {
|
|
|
26534
26563
|
return content.map((block) => encodeBlock(block, cloak));
|
|
26535
26564
|
}
|
|
26536
26565
|
function systemCacheControl(req) {
|
|
26537
|
-
const
|
|
26538
|
-
const
|
|
26539
|
-
const
|
|
26540
|
-
const
|
|
26566
|
+
const markedSystemBlocks = req.messages.flatMap((message) => message.role === "system" ? message.content.filter((block) => cacheControlOf(block) !== undefined) : []);
|
|
26567
|
+
const trailing = req.messages.at(-1);
|
|
26568
|
+
const marked = trailing?.role === "system" ? trailing.content.findLast((block) => cacheControlOf(block) !== undefined) : undefined;
|
|
26569
|
+
const retarget = marked === undefined ? undefined : cacheControlOf(marked);
|
|
26541
26570
|
return {
|
|
26542
|
-
...
|
|
26543
|
-
lost: markedSystemBlocks.length > (
|
|
26571
|
+
...retarget === undefined ? {} : { retarget },
|
|
26572
|
+
lost: markedSystemBlocks.length > (retarget === undefined ? 0 : 1)
|
|
26544
26573
|
};
|
|
26545
26574
|
}
|
|
26546
26575
|
function encodeTool(t, cloak) {
|
|
@@ -26702,14 +26731,26 @@ function toWire(req, model, opts) {
|
|
|
26702
26731
|
return [{ role: m.role, content: encodeSystemTurn(m.content, cloak) }];
|
|
26703
26732
|
}),
|
|
26704
26733
|
max_tokens: req.maxTokens ?? 4096,
|
|
26705
|
-
stream: req.stream
|
|
26706
|
-
|
|
26707
|
-
|
|
26708
|
-
|
|
26709
|
-
|
|
26734
|
+
stream: req.stream
|
|
26735
|
+
};
|
|
26736
|
+
if (systemCache.retarget !== undefined) {
|
|
26737
|
+
const trailing = body.messages.at(-1);
|
|
26738
|
+
if (isRecord(trailing) && Array.isArray(trailing.content)) {
|
|
26739
|
+
for (const block of trailing.content) {
|
|
26740
|
+
if (isRecord(block))
|
|
26741
|
+
delete block.cache_control;
|
|
26710
26742
|
}
|
|
26711
26743
|
}
|
|
26712
|
-
|
|
26744
|
+
if (!hasVendorCacheControl(req)) {
|
|
26745
|
+
const target = lastCacheableHistoryBlock(body.messages.slice(0, -1));
|
|
26746
|
+
if (target === undefined) {
|
|
26747
|
+
note("anthropic:system-turn-cache-control-dropped");
|
|
26748
|
+
} else if (target.cache_control === undefined) {
|
|
26749
|
+
Object.assign(target, wireCacheControl(systemCache.retarget));
|
|
26750
|
+
note("anthropic:system-turn-cache-control-retargeted");
|
|
26751
|
+
}
|
|
26752
|
+
}
|
|
26753
|
+
}
|
|
26713
26754
|
if (system !== undefined && system.length > 0)
|
|
26714
26755
|
body.system = system;
|
|
26715
26756
|
if (req.temperature !== undefined)
|
|
@@ -31010,6 +31051,11 @@ async function importSnapshot(deps, input) {
|
|
|
31010
31051
|
}
|
|
31011
31052
|
});
|
|
31012
31053
|
}
|
|
31054
|
+
async function clearBodies(deps) {
|
|
31055
|
+
const removed = await deps.store.bodies.prune(deps.now());
|
|
31056
|
+
const orphans = await deps.store.bodies.sweepOrphans();
|
|
31057
|
+
return { removed, orphans };
|
|
31058
|
+
}
|
|
31013
31059
|
async function vacuum(deps) {
|
|
31014
31060
|
return withExclusive("a vacuum", async () => {
|
|
31015
31061
|
const before = deps.fs.stat(deps.store.databasePath)?.size ?? 0;
|
|
@@ -31024,18 +31070,37 @@ async function vacuum(deps) {
|
|
|
31024
31070
|
}
|
|
31025
31071
|
async function getDatabaseOverview(deps) {
|
|
31026
31072
|
const live = deps.store.databasePath;
|
|
31027
|
-
const stats = await
|
|
31028
|
-
|
|
31073
|
+
const [stats, tables, settings] = await Promise.all([
|
|
31074
|
+
deps.store.maintenance.stats(),
|
|
31075
|
+
deps.store.maintenance.tables(),
|
|
31076
|
+
deps.store.config.getSettings()
|
|
31077
|
+
]);
|
|
31078
|
+
const shared = {
|
|
31079
|
+
engine: deps.store.engine,
|
|
31080
|
+
location: live,
|
|
31081
|
+
stats,
|
|
31082
|
+
logicalBytes: stats.pageSize * stats.pageCount,
|
|
31083
|
+
freePageBytes: stats.pageSize * stats.freelistCount,
|
|
31084
|
+
retention: retentionOf(settings),
|
|
31085
|
+
tables
|
|
31086
|
+
};
|
|
31087
|
+
if (deps.store.engine === "postgres") {
|
|
31088
|
+
return {
|
|
31089
|
+
...shared,
|
|
31090
|
+
fileBytes: 0,
|
|
31091
|
+
walBytes: 0,
|
|
31092
|
+
bodiesBytes: tables.find((table) => table.name === "request_bodies")?.bytes ?? 0,
|
|
31093
|
+
freeDiskBytes: null,
|
|
31094
|
+
snapshots: { count: 0, totalBytes: 0, latestAt: null }
|
|
31095
|
+
};
|
|
31096
|
+
}
|
|
31029
31097
|
const snapshots = listSnapshots(deps);
|
|
31030
31098
|
return {
|
|
31031
|
-
|
|
31099
|
+
...shared,
|
|
31032
31100
|
fileBytes: deps.fs.stat(live)?.size ?? 0,
|
|
31033
31101
|
walBytes: deps.fs.stat(`${live}-wal`)?.size ?? 0,
|
|
31034
31102
|
bodiesBytes: deps.fs.dirBytes(bodiesDirFor(live)),
|
|
31035
|
-
logicalBytes: stats.pageSize * stats.pageCount,
|
|
31036
|
-
freePageBytes: stats.pageSize * stats.freelistCount,
|
|
31037
31103
|
freeDiskBytes: deps.fs.freeBytes(dirname2(live)),
|
|
31038
|
-
retention: retentionOf(settings),
|
|
31039
31104
|
snapshots: {
|
|
31040
31105
|
count: snapshots.length,
|
|
31041
31106
|
totalBytes: snapshots.reduce((sum2, snapshot) => sum2 + snapshot.sizeBytes, 0),
|
|
@@ -48520,15 +48585,27 @@ function adminRoutes(deps) {
|
|
|
48520
48585
|
const live = await deps.store.maintenance.nodes(deps.now());
|
|
48521
48586
|
const reads = await Promise.allSettled(live.map((entry) => fleet.read(entry.id, consoleQuery).then((read) => ({ nodeId: entry.id, read }))));
|
|
48522
48587
|
const lines = [];
|
|
48523
|
-
|
|
48524
|
-
|
|
48588
|
+
let captured = false;
|
|
48589
|
+
const unreachable2 = [];
|
|
48590
|
+
for (const [index, outcome] of reads.entries()) {
|
|
48591
|
+
if (outcome.status !== "fulfilled") {
|
|
48592
|
+
unreachable2.push(live[index]?.id ?? "");
|
|
48525
48593
|
continue;
|
|
48594
|
+
}
|
|
48595
|
+
if (outcome.value.read.source !== "none")
|
|
48596
|
+
captured = true;
|
|
48526
48597
|
for (const line of outcome.value.read.lines) {
|
|
48527
48598
|
lines.push({ ...line, nodeId: outcome.value.nodeId });
|
|
48528
48599
|
}
|
|
48529
48600
|
}
|
|
48601
|
+
if (unreachable2.length === reads.length) {
|
|
48602
|
+
throw new GatewayError("TIMEOUT", "no process in the fleet answered a console read");
|
|
48603
|
+
}
|
|
48604
|
+
const reach = unreachable2.length === 0 ? {} : { unreachable: unreachable2 };
|
|
48605
|
+
if (!captured)
|
|
48606
|
+
return { source: "none", lines: [], ...reach };
|
|
48530
48607
|
lines.sort((a, b) => (a.at ?? Number.POSITIVE_INFINITY) - (b.at ?? Number.POSITIVE_INFINITY));
|
|
48531
|
-
return { source: "fleet", lines: lines.slice(-consoleQuery.lines) };
|
|
48608
|
+
return { source: "fleet", lines: lines.slice(-consoleQuery.lines), ...reach };
|
|
48532
48609
|
}).get("/api/nodes", async ({ request: request2 }) => {
|
|
48533
48610
|
await requireReader(request2, deps.admin);
|
|
48534
48611
|
const nodes = await deps.store.maintenance.nodes(deps.now());
|
|
@@ -48701,6 +48778,11 @@ function databaseRoutes(deps) {
|
|
|
48701
48778
|
durationMs: result.durationMs
|
|
48702
48779
|
});
|
|
48703
48780
|
return { ok: true, ...result };
|
|
48781
|
+
}).delete("/api/database/bodies", async ({ request: request2 }) => {
|
|
48782
|
+
await requireAdmin(request2, deps.admin);
|
|
48783
|
+
const result = await clearBodies(database);
|
|
48784
|
+
logger2.info("captured bodies cleared", { count: result.removed });
|
|
48785
|
+
return { ok: true, ...result };
|
|
48704
48786
|
}).get("/api/database/snapshots", async ({ request: request2 }) => {
|
|
48705
48787
|
await requireAdmin(request2, deps.admin);
|
|
48706
48788
|
return { snapshots: listSnapshots(database) };
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{m as e}from"./Rack-
|
|
1
|
+
import{m as e}from"./Rack-BbZyyu2u.js";import{jsx as t}from"react/jsx-runtime";import n from"styled-components";var r={neutral:{fg:`var(--ink-dim)`,bg:`transparent`},ok:{fg:`var(--ok)`,bg:`var(--ok-wash)`},warn:{fg:`var(--warn)`,bg:`var(--warn-wash)`},down:{fg:`var(--down)`,bg:`var(--down-wash)`},accent:{fg:`var(--accent)`,bg:`var(--accent-wash)`}},i=n.span`
|
|
2
2
|
display: inline-flex;
|
|
3
3
|
align-items: center;
|
|
4
4
|
gap: 4px;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{C as e,O as t}from"./Panel-
|
|
1
|
+
import{C as e,O as t}from"./Panel-BlNr9j6-.js";import{b as n}from"./Rack-BbZyyu2u.js";import{useCallback as r,useEffect as i,useRef as a,useState as o}from"react";import{jsx as s,jsxs as c}from"react/jsx-runtime";import l from"styled-components";var u=n(`check`,[[`path`,{d:`M20 6 9 17l-5-5`,key:`1gmf2c`}]]),d=n(`copy`,[[`rect`,{width:`14`,height:`14`,x:`8`,y:`8`,rx:`2`,ry:`2`,key:`17jyea`}],[`path`,{d:`M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2`,key:`zix9uf`}]]);function f(e){if(e===null||typeof getSelection!=`function`)return!1;let t=getSelection();if(t===null)return!1;try{let n=document.createRange();return n.selectNodeContents(e),t.removeAllRanges(),t.addRange(n),!0}catch{return!1}}async function p(e,t){if(typeof navigator<`u`&&navigator.clipboard!==void 0)try{return await navigator.clipboard.writeText(e),`copied`}catch{}let n=f(t??null);if(n&&typeof document.execCommand==`function`)try{if(document.execCommand(`copy`))return`copied`}catch{}return n?`selected`:`failed`}var m=l.div`
|
|
2
2
|
display: flex;
|
|
3
3
|
align-items: stretch;
|
|
4
4
|
gap: 0;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{_ as e}from"./Panel-
|
|
1
|
+
import{_ as e}from"./Panel-BlNr9j6-.js";import{useId as t}from"react";import{jsx as n,jsxs as r}from"react/jsx-runtime";import i from"styled-components";var a=`
|
|
2
2
|
width: 100%;
|
|
3
3
|
border-radius: 3px;
|
|
4
4
|
transition: border-color 120ms ease;
|