Ticketnummer bis ins Router-Log durchreichen (42i/intern#1291)
Der Log wusste bisher WER gerufen hat (Key, Rolle), aber nicht WORAN gearbeitet
wurde. Damit liess sich "was kostet ein Vorgang" gar nicht bilden -- die
Voraussetzung fuer die Frage, ob die teuren Tickets die sind, die ein Mensch
wollte.
- server.ts liest den Header x-42i-ticket und legt ihn in den Log-Eintrag
- log.ts: Feld `ticket` in JSONL und SQLite; die Spalte wird per ALTER
nachgezogen (Bestandstabellen haben sie nicht), dazu ein Index darauf.
Das INSERT nennt jetzt Spaltennamen statt Positionen -- sonst haette die
neue Spalte die Reihenfolge zerschossen.
- opencode.json und der Container-Entrypoint schicken den Header aus
{env:AGENT_TICKET}; job.sh exportiert die Variable ohnehin seit 2026-09-02.
Wer keines mitschickt (Chat, Handbetrieb), steht als null im Log -- auch das
ist eine Auskunft.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+16
-2
@@ -10,6 +10,13 @@ import { Database } from "bun:sqlite";
|
||||
export type Eintrag = {
|
||||
ts: string;
|
||||
key: string;
|
||||
/**
|
||||
* Woran gearbeitet wurde, z.B. "live/live#1573" -- aus dem Header
|
||||
* x-42i-ticket. Der Key allein sagt nur, WER gerufen hat; ohne das Ticket
|
||||
* laesst sich "was kostet ein Vorgang" gar nicht bilden (42i/intern#1291).
|
||||
* null, wenn der Aufrufer keines mitschickt (Chat, Handbetrieb).
|
||||
*/
|
||||
ticket: string | null;
|
||||
alias: string;
|
||||
angefragt: string;
|
||||
model: string;
|
||||
@@ -37,14 +44,21 @@ export class Log {
|
||||
ts TEXT, key TEXT, alias TEXT, angefragt TEXT, model TEXT, upstream TEXT, effort TEXT, pfad TEXT,
|
||||
status INTEGER, ms INTEGER, stream INTEGER, prompt_tokens INTEGER, completion_tokens INTEGER,
|
||||
cached_tokens INTEGER, cost REAL, fehler TEXT)`);
|
||||
// Nachtraeglich ergaenzt (42i/intern#1291): Bestandstabellen haben die
|
||||
// Spalte nicht. ALTER schlaegt fehl, wenn sie schon da ist -- das ist der
|
||||
// Normalfall und kein Grund, den Start abzubrechen.
|
||||
try { this.db.run(`ALTER TABLE requests ADD COLUMN ticket TEXT`); } catch { /* Spalte existiert bereits */ }
|
||||
this.db.run(`CREATE INDEX IF NOT EXISTS requests_ts_key ON requests (ts, key)`);
|
||||
this.db.run(`CREATE INDEX IF NOT EXISTS requests_ticket ON requests (ticket)`);
|
||||
}
|
||||
schreiben(e: Eintrag): void {
|
||||
appendFileSync(this.jsonl, JSON.stringify(e) + "\n");
|
||||
this.db.run(
|
||||
`INSERT INTO requests VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`,
|
||||
`INSERT INTO requests (ts,key,alias,angefragt,model,upstream,effort,pfad,status,ms,stream,
|
||||
prompt_tokens,completion_tokens,cached_tokens,cost,fehler,ticket)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`,
|
||||
[e.ts, e.key, e.alias, e.angefragt, e.model, e.upstream, e.effort, e.pfad, e.status, e.ms, e.stream ? 1 : 0,
|
||||
e.prompt_tokens, e.completion_tokens, e.cached_tokens, e.cost, e.fehler ?? null],
|
||||
e.prompt_tokens, e.completion_tokens, e.cached_tokens, e.cost, e.fehler ?? null, e.ticket ?? null],
|
||||
);
|
||||
}
|
||||
/** Je Tag und Key: Anfragen, Tokens, Kosten. */
|
||||
|
||||
+2
-1
@@ -333,7 +333,8 @@ Bun.serve({
|
||||
const accept = req.headers.get("accept"); if (accept) headers.set("accept", accept);
|
||||
|
||||
const eintrag: Eintrag = {
|
||||
ts: jetzt(), key: keyName, alias: ziel.alias, angefragt, model: ziel.model, upstream: ziel.upstreamName, effort: ziel.effort,
|
||||
ts: jetzt(), key: keyName, ticket: req.headers.get("x-42i-ticket") || null,
|
||||
alias: ziel.alias, angefragt, model: ziel.model, upstream: ziel.upstreamName, effort: ziel.effort,
|
||||
pfad, status: 0, ms: 0, stream, prompt_tokens: null, completion_tokens: null, cached_tokens: null, cost: null,
|
||||
};
|
||||
const abschliessen = (usage?: unknown) => {
|
||||
|
||||
Reference in New Issue
Block a user