loki-mode 11.3.1 → 11.3.4
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/SKILL.md +4 -4
- package/VERSION +1 -1
- package/autonomy/lib/efficiency_cost.py +8 -0
- package/autonomy/lib/engine10-push.sh +22 -8
- package/autonomy/loki +69 -30
- package/bin/loki +30 -1
- package/completions/_loki +22 -0
- package/completions/loki.bash +17 -3
- package/dashboard/__init__.py +1 -1
- package/dashboard/server.py +22 -14
- package/docs/AGENT-CHANGE-RECEIPT.md +2 -2
- package/docs/CLI-REFERENCE.md +5 -1
- package/docs/INSTALLATION.md +1 -1
- package/docs/OTEL-COLLECTOR.md +24 -0
- package/docs/ROUTING-EVIDENCE.md +32 -0
- package/docs/environment-variables.md +1 -0
- package/docs/spec-first-intent.md +28 -0
- package/docs/v10/CLI-MODERN.md +6 -3
- package/docs/v10/DECISIONS.md +20 -0
- package/docs/v10/FAILURE-CLASSES.md +263 -1
- package/docs/v10/GUARDS.md +18 -0
- package/docs/v10/GUIDE.md +7 -5
- package/docs/v10/METRICS.md +12 -0
- package/docs/v10/OPERATING-MODEL.md +3 -3
- package/docs/v10/PROGRESS.md +12 -0
- package/docs/v11/INTOTO-AGENT-CHANGE-PREDICATE.md +77 -0
- package/docs/v11/MCP-2026-07-28.md +55 -0
- package/docs/v11/VERIFY-PR-SANDBOX.md +41 -0
- package/loki-ts/dist/loki.js +1130 -969
- package/mcp/__init__.py +1 -1
- package/mcp/v10_tools.py +29 -0
- package/package.json +9 -11
- package/packages/control-plane/dist/ask-tools-server.js +8 -2
- package/packages/control-plane/dist/server.js +15752 -13978
- package/packages/control-plane/drizzle/0006_token_sessions.sql +1 -0
- package/packages/control-plane/drizzle/meta/0006_snapshot.json +807 -0
- package/packages/control-plane/drizzle/meta/_journal.json +7 -0
- package/packages/control-plane/src/db/schema.ts +1 -0
- package/packages/control-plane/src/server/routes/cost.ts +4 -3
- package/packages/control-plane/src/server/runs.ts +3 -3
- package/packages/control-plane/ui/dist/assets/index-DbLzr87u.js +190 -0
- package/packages/control-plane/ui/dist/index.html +1 -1
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/providers/opencode.sh +2 -3
- package/src/observability/genai-spans.js +104 -0
- package/src/observability/otel-bridge.js +49 -1
- package/src/observability/otel.js +2 -2
- package/src/protocols/mcp-server.js +180 -5
- package/src/protocols/transport/sse.js +23 -2
- package/web-app/dist/assets/{AdminPage-CMkHNJbF.js → AdminPage-CKj0pDt0.js} +1 -1
- package/web-app/dist/assets/{Avatar-BJyjV7Zi.js → Avatar-BOV__pMM.js} +1 -1
- package/web-app/dist/assets/{Badge-D572l0uq.js → Badge-4a6mAYjU.js} +1 -1
- package/web-app/dist/assets/{Button-T4BnOZgl.js → Button-B3GM7oxm.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-Cj_GFsNn.js → CockpitPage-Cwge3_kH.js} +1 -1
- package/web-app/dist/assets/{ComparePage-A8m4ZXak.js → ComparePage-CBQUGKsm.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-hugCg5yg.js → ErrorBoundary-TM7lDjUJ.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-CuJKDC2G.js → EvidenceReceiptPanel-DUOseTYA.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-BYGKjarC.js → GitHubIssuesPanel-hK_uML6T.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-c7sFIJlf.js → GitHubPRsPanel-Bt0mug-u.js} +1 -1
- package/web-app/dist/assets/{HomePage-A1MIkG2P.js → HomePage-DcOogAai.js} +2 -2
- package/web-app/dist/assets/{LoginPage-8KQMRhtR.js → LoginPage-D41pjjhF.js} +1 -1
- package/web-app/dist/assets/{MagicPage-C05QW2Lx.js → MagicPage-iDcdAcL2.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-Oukv5hme.js → MetricsPage-Tt4sfFD1.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-DKIwsawz.js → NotFoundPage-DPQMausn.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-DwFRPLCG.js → ProjectPage-DdMz4frY.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-CgY4YYDX.js → ProjectsPage-Be0v4ace.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-BpfcSjUA.js → SettingsPage-90yIh-mE.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-BqBakC4K.js → ShowcasePage-D5x5eczl.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-CZLu5VB0.js → SystemSettingsPage-UWeWT8KX.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-D55S1jKz.js → TeamsPage-BtofFlme.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-D3SydvxN.js → TemplatesPage-DwB8Va2Z.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-hNg8G1-e.js → TerminalOutput-CGIgTmby.js} +1 -1
- package/web-app/dist/assets/{activity-D2C0VagO.js → activity-BZ77CO72.js} +1 -1
- package/web-app/dist/assets/{bell-CMvYi36w.js → bell-Bzpqv6un.js} +1 -1
- package/web-app/dist/assets/{bot-BvtQ6lmo.js → bot-yXo1B_-f.js} +1 -1
- package/web-app/dist/assets/{check-B13xkXed.js → check-BSxGjsta.js} +1 -1
- package/web-app/dist/assets/{chevron-left-emu6r49E.js → chevron-left-CqTRVUB5.js} +1 -1
- package/web-app/dist/assets/{circle-alert-CExlwjuy.js → circle-alert-88gdjY71.js} +1 -1
- package/web-app/dist/assets/{clock-D7Uas3oL.js → clock-XdFXoaJi.js} +1 -1
- package/web-app/dist/assets/{cloud-CkB4S86C.js → cloud-Tx1sJrXz.js} +1 -1
- package/web-app/dist/assets/{code-xml-SL9IIWIn.js → code-xml-DaH9CKWy.js} +1 -1
- package/web-app/dist/assets/{database-BQFkd7t1.js → database-BpvOmzij.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-qHmnNYsU.js → dollar-sign-VC2UX2UE.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-C2YUDP0K.js → file-code-corner--TF3VpoT.js} +1 -1
- package/web-app/dist/assets/{file-plus-C_ooIkDe.js → file-plus-DZpwU9pY.js} +1 -1
- package/web-app/dist/assets/{globe-CQ-GL485.js → globe-tbpeHRPV.js} +1 -1
- package/web-app/dist/assets/{hammer-U05L_D7V.js → hammer-CKLXn4vL.js} +1 -1
- package/web-app/dist/assets/{index-CooHd7I-.js → index-DnCsWpCh.js} +3 -3
- package/web-app/dist/assets/{layers-Buo17rjW.js → layers-B0fkGsk8.js} +1 -1
- package/web-app/dist/assets/{loader-circle-15vK3oV1.js → loader-circle-czscMzmQ.js} +1 -1
- package/web-app/dist/assets/{lock-BeXLebuJ.js → lock-CTtO6vc8.js} +1 -1
- package/web-app/dist/assets/{package-MVh_6-6R.js → package-DZeSY0-g.js} +1 -1
- package/web-app/dist/assets/{plus-Dh_nd9vS.js → plus-mE12CJVN.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-C9cBJEAT.js → refresh-cw-9DSznasU.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-D3PAtzST.js → rotate-ccw-DcHI0M43.js} +1 -1
- package/web-app/dist/assets/{scroll-text-DZCoXQjo.js → scroll-text-BWLthSw-.js} +1 -1
- package/web-app/dist/assets/{server-OCOLI5J_.js → server-_I247LrS.js} +1 -1
- package/web-app/dist/assets/{shield-alert-oVhmf1_h.js → shield-alert-XRJYD_6c.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-B-kbX4vN.js → thumbs-up-CxuTD3eO.js} +1 -1
- package/web-app/dist/assets/{trash-2-EL6moveW.js → trash-2-DuGxuVt8.js} +1 -1
- package/web-app/dist/assets/{trending-down-Cl3kjpsx.js → trending-down-Cg_zGt__.js} +1 -1
- package/web-app/dist/assets/{trending-up-DST7I6M2.js → trending-up-DpUJzIrV.js} +1 -1
- package/web-app/dist/assets/{upload-CUOT780G.js → upload-Db7YZ4zR.js} +1 -1
- package/web-app/dist/assets/{usePolling-Djmt90eb.js → usePolling-BGRYm-vq.js} +1 -1
- package/web-app/dist/assets/{user-BRBohA6J.js → user-CxHrowEP.js} +1 -1
- package/web-app/dist/index.html +1 -1
- package/packages/control-plane/ui/dist/assets/index-DcBJXjCJ.js +0 -190
|
@@ -40,6 +40,7 @@ export const runs = sqliteTable("runs", {
|
|
|
40
40
|
partialUsd: real("partial_usd").notNull(),
|
|
41
41
|
measuredSessions: integer("measured_sessions").notNull(),
|
|
42
42
|
totalSessions: integer("total_sessions").notNull(),
|
|
43
|
+
tokenSessions: integer("token_sessions"), // FC-44: cost events that carried usage; null on rows ingested before it existed
|
|
43
44
|
inputTokens: integer("input_tokens").notNull(),
|
|
44
45
|
outputTokens: integer("output_tokens").notNull(),
|
|
45
46
|
wallS: real("wall_s"),
|
|
@@ -14,8 +14,8 @@ export const DEFAULT_API_KEY_CAP_USD = 100;
|
|
|
14
14
|
|
|
15
15
|
const NONE = "unknown";
|
|
16
16
|
type Run = typeof runs.$inferSelect;
|
|
17
|
-
type Acc = { key: Record<string, string>; runs: number; measured_runs: number; partial_runs: number; unmeasured_runs: number; measured_usd: number; partial_usd: number; input_tokens: number; output_tokens: number };
|
|
18
|
-
const mk = (key: Record<string, string>): Acc => ({ key, runs: 0, measured_runs: 0, partial_runs: 0, unmeasured_runs: 0, measured_usd: 0, partial_usd: 0, input_tokens: 0, output_tokens: 0 });
|
|
17
|
+
type Acc = { key: Record<string, string>; runs: number; measured_runs: number; partial_runs: number; unmeasured_runs: number; measured_usd: number; partial_usd: number; input_tokens: number; output_tokens: number; tk: number; tn: number };
|
|
18
|
+
const mk = (key: Record<string, string>): Acc => ({ key, runs: 0, measured_runs: 0, partial_runs: 0, unmeasured_runs: 0, measured_usd: 0, partial_usd: 0, input_tokens: 0, output_tokens: 0, tk: 0, tn: 0 });
|
|
19
19
|
const add = (a: Acc, r: Run) => {
|
|
20
20
|
a.runs++;
|
|
21
21
|
if (r.costUsd !== null) { a.measured_runs++; a.measured_usd += r.costUsd; }
|
|
@@ -23,11 +23,12 @@ const add = (a: Acc, r: Run) => {
|
|
|
23
23
|
else a.unmeasured_runs++;
|
|
24
24
|
a.input_tokens += r.inputTokens;
|
|
25
25
|
a.output_tokens += r.outputTokens;
|
|
26
|
+
if (r.tokenSessions !== null) { a.tk += r.tokenSessions; a.tn += r.totalSessions; } // FC-44: sessions that carried usage, of all cost events
|
|
26
27
|
};
|
|
27
28
|
const dimVal = (d: CostDim, r: Run): string =>
|
|
28
29
|
d === "day" ? (r.startedAt ? r.startedAt.slice(0, 10) : NONE) : d === "model" ? (r.model ?? NONE) : d === "provider" ? (r.provider ?? NONE) : (r.originRepo ?? NONE);
|
|
29
30
|
const round = (n: number) => Math.round(n * 1e6) / 1e6;
|
|
30
|
-
const out = (a: Acc) => ({ ...a.key, runs: a.runs, measured_runs: a.measured_runs, partial_runs: a.partial_runs, unmeasured_runs: a.unmeasured_runs, measured_usd: round(a.measured_usd), partial_usd: round(a.partial_usd), input_tokens: a.input_tokens, output_tokens: a.output_tokens });
|
|
31
|
+
const out = (a: Acc) => ({ ...a.key, runs: a.runs, measured_runs: a.measured_runs, partial_runs: a.partial_runs, unmeasured_runs: a.unmeasured_runs, measured_usd: round(a.measured_usd), partial_usd: round(a.partial_usd), input_tokens: a.input_tokens, output_tokens: a.output_tokens, ...(a.tk < a.tn ? { token_sessions: a.tk, token_sessions_total: a.tn } : {}) });
|
|
31
32
|
|
|
32
33
|
export function mount(ctx: RouteCtx): void {
|
|
33
34
|
// B8: per-repo breakdown. total_usd sums measured runs only (never invents a zero); avg_usd is over measured runs; verified = plain attested success display verdict.
|
|
@@ -33,8 +33,8 @@ export function rebuildRun(db: Db, sourceId: string, runId: string): void {
|
|
|
33
33
|
startedAt: f.run.started?.ts ?? evs[0]?.ts ?? null, endedAt: f.run.completed?.ts ?? null,
|
|
34
34
|
verdict: f.run.verdict,
|
|
35
35
|
prUrl: str(done.pr_url) ?? str(pr?.url), prDraft: typeof pr?.draft === "boolean" ? Number(pr.draft) : null,
|
|
36
|
-
costUsd: f.cost.usd, partialUsd: pc.usd, measuredSessions: pc.measured, totalSessions: pc.total,
|
|
37
|
-
inputTokens: f.cost.inputTokens, outputTokens: f.cost.outputTokens,
|
|
36
|
+
costUsd: f.cost.usd, partialUsd: pc.usd, measuredSessions: pc.measured, totalSessions: pc.total, tokenSessions: tampered ? null : evs.filter((e) => e.type === "cost" && typeof e.data.input_tokens === "number").length,
|
|
37
|
+
inputTokens: f.cost.inputTokens + f.cost.cacheReadTokens + f.cost.cacheCreationTokens, outputTokens: f.cost.outputTokens,
|
|
38
38
|
wallS: typeof done.wall_s === "number" ? done.wall_s : null,
|
|
39
39
|
lastSeq: f.lastSeq, lastEventAt: evs[evs.length - 1]?.ts ?? null, tampered: Number(tampered),
|
|
40
40
|
attested: Number(integ.attested), sigChecked: Number(integ.sig_checked), integrityKeyFp: keys.fingerprint ?? "", integrityReasons: JSON.stringify(integ.reasons),
|
|
@@ -49,7 +49,7 @@ const parseRun = (r: typeof runs.$inferSelect) => ({
|
|
|
49
49
|
source_id: r.sourceId, run_id: r.runId, origin_repo: r.originRepo, issue_ref: r.issueRef, task_source: r.taskSource,
|
|
50
50
|
group_id: r.groupId, unit_id: r.unitId, provider: r.provider, model: r.model, started_at: r.startedAt, ended_at: r.endedAt, verdict: r.verdict,
|
|
51
51
|
pr_url: r.prUrl, pr_draft: r.prDraft === null ? null : r.prDraft === 1,
|
|
52
|
-
cost_usd: r.costUsd, partial_usd: r.partialUsd, measured_sessions: r.measuredSessions, total_sessions: r.totalSessions,
|
|
52
|
+
cost_usd: r.costUsd, partial_usd: r.partialUsd, measured_sessions: r.measuredSessions, total_sessions: r.totalSessions, token_sessions: r.tokenSessions,
|
|
53
53
|
input_tokens: r.inputTokens, output_tokens: r.outputTokens, wall_s: r.wallS, last_seq: r.lastSeq,
|
|
54
54
|
last_event_at: r.lastEventAt, tampered: r.tampered === 1, conflict: r.conflict === 1,
|
|
55
55
|
attested: r.attested === 1, sig_checked: r.sigChecked === 1, integrity_reasons: reasonsOf(r.integrityReasons),
|