@songsid/agend 2.3.2-beta.1 → 2.3.2-beta.10
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/THIRD_PARTY_NOTICES.md +40 -0
- package/dist/agent-cli.js +21 -2
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent-endpoint.js +5 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/antigravity-usage-scan.d.ts +58 -0
- package/dist/antigravity-usage-scan.js +257 -0
- package/dist/antigravity-usage-scan.js.map +1 -0
- package/dist/antigravity-usage-worker.d.ts +1 -0
- package/dist/antigravity-usage-worker.js +10 -0
- package/dist/antigravity-usage-worker.js.map +1 -0
- package/dist/auth-api.js +4 -0
- package/dist/auth-api.js.map +1 -1
- package/dist/backend/kiro-identity.d.ts +64 -0
- package/dist/backend/kiro-identity.js +101 -0
- package/dist/backend/kiro-identity.js.map +1 -1
- package/dist/backend/kiro-retired-model.d.ts +62 -0
- package/dist/backend/kiro-retired-model.js +160 -0
- package/dist/backend/kiro-retired-model.js.map +1 -0
- package/dist/backend/kiro.d.ts +71 -2
- package/dist/backend/kiro.js +352 -11
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/types.d.ts +59 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/backend-signin-guide.d.ts +1 -0
- package/dist/backend-signin-guide.js +9 -0
- package/dist/backend-signin-guide.js.map +1 -0
- package/dist/backend-signin-pending.d.ts +10 -0
- package/dist/backend-signin-pending.js +44 -0
- package/dist/backend-signin-pending.js.map +1 -0
- package/dist/browser-backend-signins.d.ts +56 -0
- package/dist/browser-backend-signins.js +189 -0
- package/dist/browser-backend-signins.js.map +1 -0
- package/dist/cache-ledger.d.ts +38 -2
- package/dist/cache-ledger.js +133 -8
- package/dist/cache-ledger.js.map +1 -1
- package/dist/cache-prices.d.ts +2 -1
- package/dist/cache-prices.js +5 -2
- package/dist/cache-prices.js.map +1 -1
- package/dist/cache-service.d.ts +68 -0
- package/dist/cache-service.js +355 -13
- package/dist/cache-service.js.map +1 -1
- package/dist/channel/adapters/discord.d.ts +11 -0
- package/dist/channel/adapters/discord.js +71 -14
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/mcp-tools.js +29 -2
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/tool-router.js +2 -1
- package/dist/channel/tool-router.js.map +1 -1
- package/dist/classic-channel-manager.d.ts +11 -0
- package/dist/classic-channel-manager.js +39 -1
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli.js +21 -2
- package/dist/cli.js.map +1 -1
- package/dist/config-validator.d.ts +7 -1
- package/dist/config-validator.js +53 -10
- package/dist/config-validator.js.map +1 -1
- package/dist/config.d.ts +19 -0
- package/dist/config.js +31 -1
- package/dist/config.js.map +1 -1
- package/dist/cpu-quota.d.ts +23 -0
- package/dist/cpu-quota.js +86 -0
- package/dist/cpu-quota.js.map +1 -0
- package/dist/daemon.d.ts +23 -0
- package/dist/daemon.js +106 -7
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard-permissions.d.ts +20 -6
- package/dist/dashboard-permissions.js +58 -9
- package/dist/dashboard-permissions.js.map +1 -1
- package/dist/doctor.js +2 -1
- package/dist/doctor.js.map +1 -1
- package/dist/fleet-manager.d.ts +72 -0
- package/dist/fleet-manager.js +507 -89
- package/dist/fleet-manager.js.map +1 -1
- package/dist/forged-envelope-scan.d.ts +9 -0
- package/dist/forged-envelope-scan.js +30 -5
- package/dist/forged-envelope-scan.js.map +1 -1
- package/dist/general-knowledge/skills/credential-profiles/SKILL.md +5 -2
- package/dist/general-knowledge/skills/kiro-engine-migration/SKILL.md +14 -1
- package/dist/general-knowledge/skills/web-appearance/SKILL.canvas-worker-off.md +24 -1
- package/dist/general-knowledge/skills/web-appearance/SKILL.md +24 -1
- package/dist/general-knowledge/skills/web-dashboard/SKILL.canvas-worker-off.md +37 -9
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +44 -11
- package/dist/instance-config-impact.js +10 -5
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +19 -0
- package/dist/instance-lifecycle.js +55 -12
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/kiro-db-reader.d.ts +5 -0
- package/dist/kiro-db-reader.js +18 -0
- package/dist/kiro-db-reader.js.map +1 -1
- package/dist/kiro-engine-status.d.ts +2 -0
- package/dist/kiro-engine-status.js +9 -0
- package/dist/kiro-engine-status.js.map +1 -1
- package/dist/kiro-migrate.d.ts +49 -0
- package/dist/kiro-migrate.js +105 -0
- package/dist/kiro-migrate.js.map +1 -0
- package/dist/kiro-transcript-lane.d.ts +2 -0
- package/dist/kiro-transcript-lane.js.map +1 -1
- package/dist/kiro-transcript-worker.js +1 -0
- package/dist/kiro-transcript-worker.js.map +1 -1
- package/dist/kiro-tui-forensic.d.ts +7 -0
- package/dist/kiro-tui-forensic.js +110 -0
- package/dist/kiro-tui-forensic.js.map +1 -0
- package/dist/kiro-usage-run.d.ts +7 -0
- package/dist/kiro-usage-run.js +39 -0
- package/dist/kiro-usage-run.js.map +1 -0
- package/dist/kiro-usage-scan.d.ts +49 -0
- package/dist/kiro-usage-scan.js +223 -0
- package/dist/kiro-usage-scan.js.map +1 -0
- package/dist/kiro-usage-worker.d.ts +1 -0
- package/dist/kiro-usage-worker.js +10 -0
- package/dist/kiro-usage-worker.js.map +1 -0
- package/dist/kiro-usage.d.ts +58 -0
- package/dist/kiro-usage.js +310 -0
- package/dist/kiro-usage.js.map +1 -0
- package/dist/locale.js +88 -8
- package/dist/locale.js.map +1 -1
- package/dist/log-service.js +1 -1
- package/dist/log-service.js.map +1 -1
- package/dist/login-url.d.ts +4 -0
- package/dist/login-url.js +22 -0
- package/dist/login-url.js.map +1 -0
- package/dist/needs-you-hub.d.ts +2 -1
- package/dist/needs-you-hub.js +1 -1
- package/dist/needs-you-hub.js.map +1 -1
- package/dist/needs-you.d.ts +8 -2
- package/dist/needs-you.js +6 -0
- package/dist/needs-you.js.map +1 -1
- package/dist/notice-delivery.d.ts +16 -0
- package/dist/notice-delivery.js +35 -0
- package/dist/notice-delivery.js.map +1 -0
- package/dist/office-share-page.d.ts +16 -0
- package/dist/office-share-page.js +85 -0
- package/dist/office-share-page.js.map +1 -0
- package/dist/office-share-service.d.ts +91 -0
- package/dist/office-share-service.js +176 -0
- package/dist/office-share-service.js.map +1 -0
- package/dist/office-share.d.ts +258 -0
- package/dist/office-share.js +549 -0
- package/dist/office-share.js.map +1 -0
- package/dist/opencode-usage-scan.d.ts +28 -0
- package/dist/opencode-usage-scan.js +92 -0
- package/dist/opencode-usage-scan.js.map +1 -0
- package/dist/opencode-usage-worker.d.ts +1 -0
- package/dist/opencode-usage-worker.js +10 -0
- package/dist/opencode-usage-worker.js.map +1 -0
- package/dist/outbound-handlers.js +22 -2
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +26 -2
- package/dist/outbound-schemas.js +27 -2
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/public-web-gateway.js +7 -1
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/quickstart-api.js +13 -2
- package/dist/quickstart-api.js.map +1 -1
- package/dist/quickstart.js +2 -1
- package/dist/quickstart.js.map +1 -1
- package/dist/remote-card-answer.d.ts +83 -0
- package/dist/remote-card-answer.js +208 -0
- package/dist/remote-card-answer.js.map +1 -0
- package/dist/reply-triggers.d.ts +2 -0
- package/dist/reply-triggers.js +3 -0
- package/dist/reply-triggers.js.map +1 -0
- package/dist/settings-api.d.ts +2 -0
- package/dist/settings-api.js +41 -16
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-change.js +17 -14
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-effect.js +7 -1
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-instance-patch.js +4 -1
- package/dist/settings-instance-patch.js.map +1 -1
- package/dist/setup-form.d.ts +1 -1
- package/dist/setup-form.js +55 -6
- package/dist/setup-form.js.map +1 -1
- package/dist/setup-host.d.ts +9 -0
- package/dist/setup-host.js +127 -6
- package/dist/setup-host.js.map +1 -1
- package/dist/setup-signin-assets.d.ts +2 -0
- package/dist/setup-signin-assets.js +6 -0
- package/dist/setup-signin-assets.js.map +1 -0
- package/dist/setup-wizard.js +2 -0
- package/dist/setup-wizard.js.map +1 -1
- package/dist/structured-signin-transport.d.ts +8 -0
- package/dist/structured-signin-transport.js +79 -0
- package/dist/structured-signin-transport.js.map +1 -0
- package/dist/structured-signin.d.ts +131 -0
- package/dist/structured-signin.js +388 -0
- package/dist/structured-signin.js.map +1 -0
- package/dist/tool-permissions.js +12 -0
- package/dist/tool-permissions.js.map +1 -1
- package/dist/topic-commands.js +6 -2
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-sources.d.ts +26 -2
- package/dist/transcript-sources.js +103 -40
- package/dist/transcript-sources.js.map +1 -1
- package/dist/turn-reply-guard.d.ts +1 -1
- package/dist/turn-reply-guard.js +1 -1
- package/dist/turn-reply-guard.js.map +1 -1
- package/dist/types.d.ts +28 -8
- package/dist/ui/backend-signin.js +63 -10
- package/dist/ui/chat-strings.js +2 -2
- package/dist/ui/fleet-office-editor.js +14 -9
- package/dist/ui/fleet-office-layout.js +70 -32
- package/dist/ui/fleet-office-model.js +6 -3
- package/dist/ui/fleet-office-overview.js +167 -0
- package/dist/ui/fleet-office-pack.d.ts +7 -2
- package/dist/ui/fleet-office-pack.js +119 -15
- package/dist/ui/fleet-office-skin.js +98 -23
- package/dist/ui/fleet-office-store.js +39 -5
- package/dist/ui/fleet-office-view.js +5 -4
- package/dist/ui/fleet-office-zones.js +172 -12
- package/dist/ui/fleet-office.js +547 -186
- package/dist/ui/fleet-usage.js +19 -15
- package/dist/ui/office-share-dialog.js +145 -0
- package/dist/ui/office-share-page.js +164 -0
- package/dist/ui/panel-chat.js +8 -1
- package/dist/ui/panel-log.js +2 -2
- package/dist/ui/panel-needs.js +4 -4
- package/dist/ui/panel-settings.js +37 -11
- package/dist/ui/settings-dialogs.js +8 -1
- package/dist/ui/settings-guests.js +17 -7
- package/dist/ui/settings-model.js +14 -6
- package/dist/ui/settings-registry.js +4 -0
- package/dist/ui/settings-strings.js +16 -2
- package/dist/ui/shared/app-i18n.js +4 -2
- package/dist/ui/shared/app-shell.js +14 -6
- package/dist/ui/shared/app-stream.js +2 -1
- package/dist/ui/shared/app.css +67 -2
- package/dist/ui/shared/office/cozy.png +0 -0
- package/dist/ui/shared/side-panel.js +95 -0
- package/dist/ui/structured-signin.js +115 -0
- package/dist/usage-report.d.ts +20 -0
- package/dist/usage-report.js +54 -17
- package/dist/usage-report.js.map +1 -1
- package/dist/usage-rollup.d.ts +9 -1
- package/dist/usage-rollup.js +20 -4
- package/dist/usage-rollup.js.map +1 -1
- package/dist/web-api.d.ts +18 -0
- package/dist/web-api.js +201 -0
- package/dist/web-api.js.map +1 -1
- package/dist/web-auth.js +1 -1
- package/dist/web-auth.js.map +1 -1
- package/dist/web-backend-login.d.ts +1 -7
- package/dist/web-backend-login.js +2 -24
- package/dist/web-backend-login.js.map +1 -1
- package/dist/web-office-acts.d.ts +173 -0
- package/dist/web-office-acts.js +285 -0
- package/dist/web-office-acts.js.map +1 -0
- package/dist/web-office-skins.d.ts +3 -2
- package/dist/web-office-skins.js +3 -2
- package/dist/web-office-skins.js.map +1 -1
- package/dist/web-office-store.js +40 -7
- package/dist/web-office-store.js.map +1 -1
- package/dist/web-settings-patch.d.ts +2 -1
- package/dist/web-settings-patch.js +4 -1
- package/dist/web-settings-patch.js.map +1 -1
- package/dist/working-recovery.d.ts +2 -2
- package/dist/working-recovery.js +43 -8
- package/dist/working-recovery.js.map +1 -1
- package/dist/working-state-journal.d.ts +2 -0
- package/dist/working-state-journal.js +16 -1
- package/dist/working-state-journal.js.map +1 -1
- package/package.json +3 -2
- package/templates/windows-shortcuts.ps1 +155 -140
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #2122 §10 step 2: one bounded read of Kiro's three stores for the usage ledger, run in a worker thread
|
|
3
|
+
* (kiro-usage-worker.ts) so the fleet loop never parses a conversation (a classic row holds the whole history: tens of
|
|
4
|
+
* MB). Synchronous and self-contained so a test can run it in-process.
|
|
5
|
+
*
|
|
6
|
+
* - Which sources: each Kiro instance's conversations — classic rows whose `key` is its working directory, TUI sessions
|
|
7
|
+
* whose `cwd` is, and V3 sessions in its working directory's bucket. Only sources changed since the cutoff.
|
|
8
|
+
* - Incremental: a source is read again only when it changed (its signature: the row's `updated_at`, a file's
|
|
9
|
+
* inode:size:mtime), and only turns after the last one counted (`after`) come back.
|
|
10
|
+
* - Never: a write to Kiro's stores (the database is opened read-only; each read is one statement, so Kiro's own writer
|
|
11
|
+
* waits at most for that), a child process, a network call.
|
|
12
|
+
* - Bounded: past `maxBytes` read, a changed source is left for the next pass (counted as behind).
|
|
13
|
+
*/
|
|
14
|
+
import Database from "better-sqlite3";
|
|
15
|
+
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
16
|
+
import { join } from "node:path";
|
|
17
|
+
import { kasBucket } from "./backend/kiro-kas-store.js";
|
|
18
|
+
import { kiroClassicRequestTimes, kiroClassicTurns, kiroKasTurns, kiroTuiTurns } from "./kiro-usage.js";
|
|
19
|
+
const gone = (err) => err?.code === "ENOENT";
|
|
20
|
+
const sigOf = (path) => {
|
|
21
|
+
const st = statSync(path);
|
|
22
|
+
return { sig: `${st.ino}:${st.size}:${st.mtimeMs}`, size: st.size, mtimeMs: st.mtimeMs };
|
|
23
|
+
};
|
|
24
|
+
const lines = (path) => { try {
|
|
25
|
+
return readFileSync(path, "utf8").split("\n");
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
if (gone(err))
|
|
29
|
+
return [];
|
|
30
|
+
throw err;
|
|
31
|
+
} };
|
|
32
|
+
export function scanKiroUsage(input) {
|
|
33
|
+
let budget = input.maxBytes, behindBytes = 0, behindSources = 0;
|
|
34
|
+
const dbs = new Map();
|
|
35
|
+
const tuiIndex = Object.create(null);
|
|
36
|
+
const out = [];
|
|
37
|
+
const openDb = (path) => {
|
|
38
|
+
if (dbs.has(path))
|
|
39
|
+
return dbs.get(path);
|
|
40
|
+
let db = null;
|
|
41
|
+
// Not there (no classic conversation yet, or no Kiro at all): nothing to read. There and unopenable: a failure.
|
|
42
|
+
if (existsSync(path)) {
|
|
43
|
+
db = new Database(path, { readonly: true, fileMustExist: true });
|
|
44
|
+
db.pragma("query_only = ON");
|
|
45
|
+
}
|
|
46
|
+
dbs.set(path, db);
|
|
47
|
+
return db;
|
|
48
|
+
};
|
|
49
|
+
// A classic conversation's request times, for the dedup of a session that carried it into another engine.
|
|
50
|
+
const classicTimes = (db, id) => {
|
|
51
|
+
if (!db)
|
|
52
|
+
return [];
|
|
53
|
+
const row = db.prepare("SELECT value FROM conversations_v2 WHERE conversation_id = ?").get(id);
|
|
54
|
+
if (!row?.value)
|
|
55
|
+
return [];
|
|
56
|
+
try {
|
|
57
|
+
return kiroClassicRequestTimes(JSON.parse(row.value));
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
/** Read one changed source within the budget, or count it as behind. */
|
|
64
|
+
const within = (bytes) => {
|
|
65
|
+
if (budget <= 0) {
|
|
66
|
+
behindBytes += bytes;
|
|
67
|
+
behindSources++;
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
budget -= Math.max(bytes, 1);
|
|
71
|
+
return true;
|
|
72
|
+
};
|
|
73
|
+
// TUI sessions: one listing for everyone; a file's cwd is learned once per version of it.
|
|
74
|
+
let tuiNames = [];
|
|
75
|
+
let tuiFailed = false;
|
|
76
|
+
const tuiDir = join(input.kiroHome, "sessions", "cli");
|
|
77
|
+
try {
|
|
78
|
+
tuiNames = readdirSync(tuiDir).filter(n => n.endsWith(".json"));
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
if (!gone(err))
|
|
82
|
+
tuiFailed = true;
|
|
83
|
+
}
|
|
84
|
+
const tuiFiles = [];
|
|
85
|
+
for (const n of tuiNames) {
|
|
86
|
+
const path = join(tuiDir, n);
|
|
87
|
+
try {
|
|
88
|
+
const s = sigOf(path);
|
|
89
|
+
if (s.mtimeMs < input.cutoff)
|
|
90
|
+
continue;
|
|
91
|
+
const known = input.tuiIndex[path];
|
|
92
|
+
let cwd = known?.sig === s.sig ? known.cwd : undefined;
|
|
93
|
+
if (cwd === undefined) {
|
|
94
|
+
const text = readFileSync(path, "utf8"); // a read that fails is a failure (below), not an empty store
|
|
95
|
+
try {
|
|
96
|
+
const v = JSON.parse(text);
|
|
97
|
+
cwd = typeof v.cwd === "string" ? v.cwd : null;
|
|
98
|
+
}
|
|
99
|
+
// Being rewritten: read again next pass. Until then whose it is can't be known, so no instance's scan is
|
|
100
|
+
// complete (no coverage, and no cursor is pruned — Prism #2605).
|
|
101
|
+
catch {
|
|
102
|
+
tuiFailed = true;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
tuiIndex[path] = { sig: s.sig, cwd };
|
|
107
|
+
tuiFiles.push({ path, sig: s.sig, size: s.size, cwd });
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
if (!gone(err))
|
|
111
|
+
tuiFailed = true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
for (const inst of input.instances) {
|
|
116
|
+
const res = { name: inst.name, updates: [], live: [], failed: tuiFailed };
|
|
117
|
+
const cwds = new Set(inst.cwds);
|
|
118
|
+
const afterOf = (key) => Math.max(inst.cursors[key]?.after ?? -Infinity, input.cutoff);
|
|
119
|
+
const push = (key, sig, turns) => res.updates.push({ key, sig, after: turns.reduce((m, t) => Math.max(m, t.t), afterOf(key)), turns });
|
|
120
|
+
// Classic: its working directory's rows.
|
|
121
|
+
let db = null;
|
|
122
|
+
try {
|
|
123
|
+
db = openDb(inst.dbPath);
|
|
124
|
+
const rows = db ? db.prepare("SELECT conversation_id AS id, key, updated_at AS u, octet_length(value) AS n FROM conversations_v2 WHERE updated_at >= ?").all(input.cutoff) : [];
|
|
125
|
+
for (const r of rows) {
|
|
126
|
+
if (!cwds.has(r.key))
|
|
127
|
+
continue;
|
|
128
|
+
const key = `classic:${r.id}`, sig = String(r.u);
|
|
129
|
+
res.live.push(key);
|
|
130
|
+
if (inst.cursors[key]?.sig === sig || !within(r.n))
|
|
131
|
+
continue;
|
|
132
|
+
const row = db.prepare("SELECT value FROM conversations_v2 WHERE key = ? AND conversation_id = ?").get(r.key, r.id);
|
|
133
|
+
if (!row?.value)
|
|
134
|
+
continue;
|
|
135
|
+
let v;
|
|
136
|
+
try {
|
|
137
|
+
v = JSON.parse(row.value);
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
push(key, sig, kiroClassicTurns(v, afterOf(key)));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
res.failed = true;
|
|
147
|
+
}
|
|
148
|
+
// TUI: the sessions whose cwd is its working directory.
|
|
149
|
+
for (const f of tuiFiles) {
|
|
150
|
+
if (f.cwd === null || !cwds.has(f.cwd))
|
|
151
|
+
continue;
|
|
152
|
+
const key = `tui:${f.path}`;
|
|
153
|
+
res.live.push(key);
|
|
154
|
+
if (inst.cursors[key]?.sig === f.sig)
|
|
155
|
+
continue;
|
|
156
|
+
const sidecar = f.path.replace(/\.json$/, ".jsonl");
|
|
157
|
+
let size = f.size;
|
|
158
|
+
try {
|
|
159
|
+
size += statSync(sidecar).size;
|
|
160
|
+
}
|
|
161
|
+
catch { /* none yet */ }
|
|
162
|
+
if (!within(size))
|
|
163
|
+
continue;
|
|
164
|
+
try {
|
|
165
|
+
const session = JSON.parse(readFileSync(f.path, "utf8"));
|
|
166
|
+
const id = typeof session.session_id === "string" ? session.session_id : "";
|
|
167
|
+
push(key, f.sig, kiroTuiTurns(session, lines(sidecar), afterOf(key), id ? classicTimes(db, id) : []));
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
if (!gone(err))
|
|
171
|
+
res.failed = true;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// V3: its working directory's bucket.
|
|
175
|
+
for (const dir of new Set(inst.cwds.map(c => join(input.kiroHome, "sessions", kasBucket(c))))) {
|
|
176
|
+
let names = [];
|
|
177
|
+
try {
|
|
178
|
+
names = readdirSync(dir).filter(n => !n.startsWith("."));
|
|
179
|
+
}
|
|
180
|
+
catch (err) {
|
|
181
|
+
if (!gone(err))
|
|
182
|
+
res.failed = true;
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
for (const n of names) {
|
|
186
|
+
const sessionPath = join(dir, n, "session.json"), messagesPath = join(dir, n, "messages.jsonl");
|
|
187
|
+
try {
|
|
188
|
+
const a = sigOf(sessionPath);
|
|
189
|
+
let m = { sig: "-", size: 0, mtimeMs: 0 };
|
|
190
|
+
try {
|
|
191
|
+
m = sigOf(messagesPath);
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
if (!gone(err))
|
|
195
|
+
throw err;
|
|
196
|
+
}
|
|
197
|
+
if (Math.max(a.mtimeMs, m.mtimeMs) < input.cutoff)
|
|
198
|
+
continue;
|
|
199
|
+
const key = `kas:${join(dir, n)}`, sig = `${a.sig}|${m.sig}`;
|
|
200
|
+
res.live.push(key);
|
|
201
|
+
if (inst.cursors[key]?.sig === sig || !within(a.size + m.size))
|
|
202
|
+
continue;
|
|
203
|
+
const session = JSON.parse(readFileSync(sessionPath, "utf8"));
|
|
204
|
+
// A converted session's id is `cli_<classic id>_<suffix>`: its source's requests are counted there.
|
|
205
|
+
const source = /^cli_(.+)_[^_]+$/.exec(n)?.[1];
|
|
206
|
+
push(key, sig, kiroKasTurns(session, lines(messagesPath), afterOf(key), source ? classicTimes(db, source) : []));
|
|
207
|
+
}
|
|
208
|
+
catch (err) {
|
|
209
|
+
if (!gone(err))
|
|
210
|
+
res.failed = true;
|
|
211
|
+
} // being rewritten (SyntaxError) included: next pass
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
out.push(res);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
finally {
|
|
218
|
+
for (const db of dbs.values())
|
|
219
|
+
db?.close();
|
|
220
|
+
}
|
|
221
|
+
return { instances: out, tuiIndex, readBytes: input.maxBytes - budget, behindBytes, behindSources };
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=kiro-usage-scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kiro-usage-scan.js","sourceRoot":"","sources":["../src/kiro-usage-scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** #2122: the Kiro usage scan's thread (kiro-usage-scan.ts): one scan per worker, its answer posted back. */
|
|
2
|
+
import { parentPort, workerData } from "node:worker_threads";
|
|
3
|
+
import { scanKiroUsage } from "./kiro-usage-scan.js";
|
|
4
|
+
try {
|
|
5
|
+
parentPort?.postMessage({ ok: true, out: scanKiroUsage(workerData) });
|
|
6
|
+
}
|
|
7
|
+
catch (err) {
|
|
8
|
+
parentPort?.postMessage({ ok: false, error: String(err) });
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=kiro-usage-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kiro-usage-worker.js","sourceRoot":"","sources":["../src/kiro-usage-worker.ts"],"names":[],"mappings":"AAAA,6GAA6G;AAC7G,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAsB,MAAM,sBAAsB,CAAC;AAEzE,IAAI,CAAC;IAAC,UAAU,EAAE,WAAW,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,aAAa,CAAC,UAA2B,CAAC,EAAE,CAAC,CAAC;AAAC,CAAC;AAC/F,OAAO,GAAG,EAAE,CAAC;IAAC,UAAU,EAAE,WAAW,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAAC,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #2122 §10 step 2: Kiro's usage, ESTIMATED. Kiro records no token counts (design §10.1: every `request_metadata` token
|
|
3
|
+
* field is null in the classic store, every `*_token_count` 0 in the TUI one, and V3 has no such field), so each turn is
|
|
4
|
+
* estimated from its text size the way tokscale does — the same basis as the user's tokscale-based reports (the user's
|
|
5
|
+
* decision, option B). Kiro keeps a conversation in one of three stores, by engine:
|
|
6
|
+
* - classic (legacy UI, engine v1): `<XDG_DATA_HOME>/kiro-cli/data.sqlite3`, table `conversations_v2` — kiroClassicTurns;
|
|
7
|
+
* - TUI (engine v2): `<KIRO_HOME>/sessions/cli/<id>.json` with its `<id>.jsonl` — kiroTuiTurns;
|
|
8
|
+
* - V3 (KAS): `<KIRO_HOME>/sessions/<bucket>/sess_<id>/{session.json, messages.jsonl}` — kiroKasTurns.
|
|
9
|
+
* The estimate:
|
|
10
|
+
* - fresh input: ceil(bytes / 4) of the prompt (its recorded `user_prompt_length`, else the prompt text) plus the tool
|
|
11
|
+
* results the turn sent;
|
|
12
|
+
* - output: ceil(bytes / 4) of the response (`response_size`, TUI `assistant_response_length`, else its text);
|
|
13
|
+
* - cache read: the context the turn resent, `floor(window × context_usage_percentage / 100) − fresh input` (never below
|
|
14
|
+
* 0); the window is the conversation's `context_window_tokens` (classic: none → no cache read; TUI: none → 200,000;
|
|
15
|
+
* V3 records none: 200,000);
|
|
16
|
+
* - cache write and reasoning: 0. A real count, should Kiro ever record one above 0, is taken instead.
|
|
17
|
+
* Credits are not read: the user's plan is not billed in them (design §10.2).
|
|
18
|
+
*
|
|
19
|
+
* The estimation formula and field mapping follow tokscale (github.com/junhoyeo/tokscale,
|
|
20
|
+
* crates/tokscale-core/src/sessions/kiro.rs at 669fdaeec54502a30468adbfa97789bb7ee2b762), MIT License,
|
|
21
|
+
* Copyright (c) 2025 Junho Yeo — see THIRD_PARTY_NOTICES.md. The code is AgEnD's own. Pure: no I/O.
|
|
22
|
+
*/
|
|
23
|
+
import type { Turn } from "./cache-ledger.js";
|
|
24
|
+
/** The window when a TUI or V3 session records none (tokscale's DEFAULT_CONTEXT_WINDOW). */
|
|
25
|
+
export declare const KIRO_DEFAULT_WINDOW = 200000;
|
|
26
|
+
export interface KiroClassicTurn extends Turn {
|
|
27
|
+
index: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The estimated turns of one classic conversation (`conversations_v2.value`, parsed) whose request started after
|
|
31
|
+
* `after` (ms). One turn per `history[]` entry with `request_metadata`; an entry estimated at nothing is skipped.
|
|
32
|
+
*/
|
|
33
|
+
export declare function kiroClassicTurns(conversation: unknown, after: number): KiroClassicTurn[];
|
|
34
|
+
/** The request start times a classic conversation recorded (for the cross-store dedup below). */
|
|
35
|
+
export declare function kiroClassicRequestTimes(conversation: unknown): number[];
|
|
36
|
+
export interface KiroTuiTurn extends Turn {
|
|
37
|
+
index: number;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The estimated turns of one TUI session — its `<id>.json` (parsed) and the lines of its `<id>.jsonl` — that started
|
|
41
|
+
* after `after` (ms). Only the messages a turn's `message_ids` name count toward it: the sidecar also carries the
|
|
42
|
+
* messages a conversation brought over from the classic engine.
|
|
43
|
+
*
|
|
44
|
+
* Dedup across stores (design §10.1): a conversation can have turns in both engines under one id. A TUI turn whose
|
|
45
|
+
* window [end − turn_duration, end] holds a request of the same conversation's classic record (`classicTimes`) is that
|
|
46
|
+
* request's, counted from the classic store: it is dropped here.
|
|
47
|
+
*/
|
|
48
|
+
export declare function kiroTuiTurns(session: unknown, jsonlLines: Iterable<string>, after: number, classicTimes?: readonly number[]): KiroTuiTurn[];
|
|
49
|
+
/**
|
|
50
|
+
* The estimated turns of one V3 (KAS) session — its `session.json` (parsed) and the lines of its `messages.jsonl` — that
|
|
51
|
+
* started after `after` (ms). A turn runs to its `turn_end`: its `user` text and `tool_result` text are its fresh input,
|
|
52
|
+
* its `assistant` text its output, and its last `contextUsage` its context. The window is 200,000 (V3 records none).
|
|
53
|
+
*
|
|
54
|
+
* A session converted from another engine (`ensure-session`: a new id, the history copied in) holds turns that store
|
|
55
|
+
* already counted: a turn that ended before the session was created (`createdAt`) is not counted again, nor one whose
|
|
56
|
+
* window holds a request of its source's classic record (`classicTimes`).
|
|
57
|
+
*/
|
|
58
|
+
export declare function kiroKasTurns(session: unknown, jsonlLines: Iterable<string>, after: number, classicTimes?: readonly number[]): Turn[];
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/** The window when a TUI or V3 session records none (tokscale's DEFAULT_CONTEXT_WINDOW). */
|
|
2
|
+
export const KIRO_DEFAULT_WINDOW = 200_000;
|
|
3
|
+
const obj = (v) => (v && typeof v === "object" && !Array.isArray(v) ? v : null);
|
|
4
|
+
const at = (v, ...path) => { let c = v; for (const k of path)
|
|
5
|
+
c = obj(c)?.[k]; return c; };
|
|
6
|
+
/** A count as recorded; anything that is not a finite number is absent. */
|
|
7
|
+
const count = (v) => (typeof v === "number" && Number.isFinite(v) ? v : null);
|
|
8
|
+
const positive = (v) => { const n = count(v); return n !== null && n > 0 ? n : null; };
|
|
9
|
+
const estimate = (bytes) => Math.ceil(Math.max(0, bytes) / 4);
|
|
10
|
+
const bytes = (s) => Buffer.byteLength(s, "utf8");
|
|
11
|
+
const chars = (s) => { let n = 0; for (const _ of s)
|
|
12
|
+
n++; return n; };
|
|
13
|
+
const modelOf = (info) => {
|
|
14
|
+
const m = at(info, "model_id");
|
|
15
|
+
return typeof m === "string" && m.trim() ? m : "unknown";
|
|
16
|
+
};
|
|
17
|
+
const turn = (t, model, input, read, output, requests = 1) => ({ t, model, prompt: input + read, uncached: input, read, write5m: 0, write1h: 0, write: null, output, ...(requests > 1 ? { requests } : {}) });
|
|
18
|
+
/** The classic store's tool results: the bytes of every `Text`/`text` string inside, else of the whole JSON. */
|
|
19
|
+
function classicToolResultBytes(value) {
|
|
20
|
+
const walk = (v) => {
|
|
21
|
+
if (Array.isArray(v))
|
|
22
|
+
return v.reduce((n, x) => n + walk(x), 0);
|
|
23
|
+
const o = obj(v);
|
|
24
|
+
if (!o)
|
|
25
|
+
return 0;
|
|
26
|
+
let n = 0;
|
|
27
|
+
for (const [k, x] of Object.entries(o))
|
|
28
|
+
n += (k === "Text" || k === "text") && typeof x === "string" ? bytes(x) : walk(x);
|
|
29
|
+
return n;
|
|
30
|
+
};
|
|
31
|
+
const found = walk(value);
|
|
32
|
+
return found > 0 ? found : bytes(JSON.stringify(value) ?? "");
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The estimated turns of one classic conversation (`conversations_v2.value`, parsed) whose request started after
|
|
36
|
+
* `after` (ms). One turn per `history[]` entry with `request_metadata`; an entry estimated at nothing is skipped.
|
|
37
|
+
*/
|
|
38
|
+
export function kiroClassicTurns(conversation, after) {
|
|
39
|
+
const model = modelOf(at(conversation, "model_info"));
|
|
40
|
+
const window = count(at(conversation, "model_info", "context_window_tokens")) ?? 0;
|
|
41
|
+
const history = at(conversation, "history");
|
|
42
|
+
if (!Array.isArray(history))
|
|
43
|
+
return [];
|
|
44
|
+
const out = [];
|
|
45
|
+
history.forEach((entry, index) => {
|
|
46
|
+
const meta = obj(at(entry, "request_metadata"));
|
|
47
|
+
if (!meta)
|
|
48
|
+
return;
|
|
49
|
+
const t = positive(meta.request_start_timestamp_ms) ?? positive(meta.stream_end_timestamp_ms) ?? 0;
|
|
50
|
+
if (!(t > after))
|
|
51
|
+
return;
|
|
52
|
+
const nested = obj(meta.token_usage) ?? obj(meta.usage);
|
|
53
|
+
const real = (...keys) => { for (const k of keys) {
|
|
54
|
+
const v = positive(meta[k]) ?? positive(nested?.[k]);
|
|
55
|
+
if (v !== null)
|
|
56
|
+
return v;
|
|
57
|
+
} return null; };
|
|
58
|
+
const realInput = real("input_tokens", "uncached_input_tokens", "input_token_count");
|
|
59
|
+
const realOutput = real("output_tokens", "output_token_count");
|
|
60
|
+
const realRead = real("cache_read_input_tokens", "cache_read_tokens", "cache_read");
|
|
61
|
+
const content = at(entry, "user", "content");
|
|
62
|
+
const promptText = at(content, "Prompt", "prompt");
|
|
63
|
+
const promptBytes = positive(meta.user_prompt_length) ?? (typeof promptText === "string" ? bytes(promptText) : 0);
|
|
64
|
+
const toolBytes = obj(content) && "ToolUseResults" in obj(content) ? classicToolResultBytes(obj(content).ToolUseResults) : 0;
|
|
65
|
+
const fresh = estimate(promptBytes + toolBytes);
|
|
66
|
+
const pct = count(meta.context_usage_percentage) ?? 0;
|
|
67
|
+
const context = window > 0 && pct > 0 ? Math.floor(window * pct / 100) : 0;
|
|
68
|
+
const input = realInput ?? fresh;
|
|
69
|
+
const read = realRead ?? (realInput === null ? Math.max(context - fresh, 0) : 0);
|
|
70
|
+
const output = realOutput ?? estimate(count(meta.response_size) ?? 0);
|
|
71
|
+
if (input + output === 0)
|
|
72
|
+
return;
|
|
73
|
+
const requests = positive(meta.request_count) ?? positive(meta.user_turn_request_count) ?? positive(meta.total_request_count) ?? 1;
|
|
74
|
+
out.push({ ...turn(t, model, input, read, output, requests), index });
|
|
75
|
+
});
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
/** The request start times a classic conversation recorded (for the cross-store dedup below). */
|
|
79
|
+
export function kiroClassicRequestTimes(conversation) {
|
|
80
|
+
const history = at(conversation, "history");
|
|
81
|
+
if (!Array.isArray(history))
|
|
82
|
+
return [];
|
|
83
|
+
const out = [];
|
|
84
|
+
for (const e of history) {
|
|
85
|
+
const t = positive(at(e, "request_metadata", "request_start_timestamp_ms"));
|
|
86
|
+
if (t !== null)
|
|
87
|
+
out.push(t);
|
|
88
|
+
}
|
|
89
|
+
return out;
|
|
90
|
+
}
|
|
91
|
+
/** A TUI or V3 timestamp: an RFC 3339 string, or a number in seconds (below 1e12) or milliseconds. */
|
|
92
|
+
function v3Time(v) {
|
|
93
|
+
if (typeof v === "string") {
|
|
94
|
+
const t = Date.parse(v);
|
|
95
|
+
return Number.isFinite(t) && t > 0 ? t : null;
|
|
96
|
+
}
|
|
97
|
+
const n = count(v);
|
|
98
|
+
if (n === null || n <= 0)
|
|
99
|
+
return null;
|
|
100
|
+
return Math.abs(n) < 1e12 ? Math.round(n * 1000) : n;
|
|
101
|
+
}
|
|
102
|
+
const secsOf = (d) => {
|
|
103
|
+
const s = count(at(d, "secs")), ns = count(at(d, "nanos"));
|
|
104
|
+
return s === null ? null : s + (ns ?? 0) / 1e9;
|
|
105
|
+
};
|
|
106
|
+
/** TUI tool results (a `ToolResults` line's `data.content`): the text of each toolResult's content data. */
|
|
107
|
+
function v3ToolResultBytes(content) {
|
|
108
|
+
if (!Array.isArray(content))
|
|
109
|
+
return 0;
|
|
110
|
+
let n = 0;
|
|
111
|
+
for (const part of content) {
|
|
112
|
+
if (at(part, "kind") !== "toolResult")
|
|
113
|
+
continue;
|
|
114
|
+
const inner = at(part, "data", "content");
|
|
115
|
+
if (!Array.isArray(inner))
|
|
116
|
+
continue;
|
|
117
|
+
for (const x of inner) {
|
|
118
|
+
const d = obj(x)?.data;
|
|
119
|
+
if (d === undefined)
|
|
120
|
+
continue;
|
|
121
|
+
n += typeof d === "string" ? bytes(d) : bytes(JSON.stringify(d) ?? "");
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return n;
|
|
125
|
+
}
|
|
126
|
+
const textChars = (content) => {
|
|
127
|
+
if (!Array.isArray(content))
|
|
128
|
+
return 0;
|
|
129
|
+
let n = 0;
|
|
130
|
+
for (const p of content) {
|
|
131
|
+
const k = at(p, "kind"), d = at(p, "data");
|
|
132
|
+
if ((k === undefined || k === null || k === "text") && typeof d === "string")
|
|
133
|
+
n += chars(d);
|
|
134
|
+
}
|
|
135
|
+
return n;
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* The estimated turns of one TUI session — its `<id>.json` (parsed) and the lines of its `<id>.jsonl` — that started
|
|
139
|
+
* after `after` (ms). Only the messages a turn's `message_ids` name count toward it: the sidecar also carries the
|
|
140
|
+
* messages a conversation brought over from the classic engine.
|
|
141
|
+
*
|
|
142
|
+
* Dedup across stores (design §10.1): a conversation can have turns in both engines under one id. A TUI turn whose
|
|
143
|
+
* window [end − turn_duration, end] holds a request of the same conversation's classic record (`classicTimes`) is that
|
|
144
|
+
* request's, counted from the classic store: it is dropped here.
|
|
145
|
+
*/
|
|
146
|
+
export function kiroTuiTurns(session, jsonlLines, after, classicTimes = []) {
|
|
147
|
+
const info = at(session, "session_state", "rts_model_state", "model_info");
|
|
148
|
+
const model = modelOf(info);
|
|
149
|
+
const window = positive(at(info, "context_window_tokens")) ?? KIRO_DEFAULT_WINDOW;
|
|
150
|
+
const turns = at(session, "session_state", "conversation_metadata", "user_turn_metadatas");
|
|
151
|
+
if (!Array.isArray(turns) || !turns.length)
|
|
152
|
+
return [];
|
|
153
|
+
const byId = new Map();
|
|
154
|
+
let pendingPrompt = null, pendingTools = 0;
|
|
155
|
+
for (const line of jsonlLines) {
|
|
156
|
+
let e;
|
|
157
|
+
try {
|
|
158
|
+
e = JSON.parse(line);
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
const kind = at(e, "kind");
|
|
164
|
+
if (kind === "ToolResults") {
|
|
165
|
+
pendingTools += v3ToolResultBytes(at(e, "data", "content"));
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const id = at(e, "data", "message_id");
|
|
169
|
+
if (typeof id !== "string")
|
|
170
|
+
continue;
|
|
171
|
+
const c = textChars(at(e, "data", "content"));
|
|
172
|
+
if (kind === "Prompt")
|
|
173
|
+
pendingPrompt = { chars: c, at: v3Time(at(e, "data", "meta", "timestamp")) };
|
|
174
|
+
else if (kind === "AssistantMessage") {
|
|
175
|
+
const m = byId.get(id) ?? { prompt: 0, assistant: 0, tools: 0, promptAt: null };
|
|
176
|
+
if (pendingPrompt) {
|
|
177
|
+
m.prompt += pendingPrompt.chars;
|
|
178
|
+
m.promptAt ??= pendingPrompt.at;
|
|
179
|
+
pendingPrompt = null;
|
|
180
|
+
}
|
|
181
|
+
m.assistant += c;
|
|
182
|
+
m.tools += pendingTools;
|
|
183
|
+
pendingTools = 0;
|
|
184
|
+
byId.set(id, m);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
const out = [];
|
|
188
|
+
turns.forEach((tm, index) => {
|
|
189
|
+
let prompt = 0, assistant = 0, tools = 0, promptAt = null;
|
|
190
|
+
const ids = at(tm, "message_ids");
|
|
191
|
+
for (const id of Array.isArray(ids) ? ids : []) {
|
|
192
|
+
const m = typeof id === "string" ? byId.get(id) : undefined;
|
|
193
|
+
if (!m)
|
|
194
|
+
continue;
|
|
195
|
+
prompt += m.prompt;
|
|
196
|
+
assistant += m.assistant;
|
|
197
|
+
tools += m.tools;
|
|
198
|
+
promptAt ??= m.promptAt;
|
|
199
|
+
}
|
|
200
|
+
const end = v3Time(at(tm, "end_timestamp"));
|
|
201
|
+
const t = promptAt ?? end;
|
|
202
|
+
if (t === null || !(t > after))
|
|
203
|
+
return;
|
|
204
|
+
if (end !== null && classicTimes.length) {
|
|
205
|
+
const secs = secsOf(at(tm, "turn_duration"));
|
|
206
|
+
const start = secs === null ? (promptAt ?? end) : end - secs * 1000;
|
|
207
|
+
if (classicTimes.some(c => c >= start && c <= end))
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const realInput = positive(at(tm, "input_token_count")), realOutput = positive(at(tm, "output_token_count"));
|
|
211
|
+
const realRead = positive(at(tm, "cache_read_input_token_count"));
|
|
212
|
+
const fresh = estimate((positive(at(tm, "user_prompt_length")) ?? prompt) + tools);
|
|
213
|
+
const input = realInput ?? fresh;
|
|
214
|
+
const pct = count(at(tm, "context_usage_percentage")) ?? 0;
|
|
215
|
+
const read = realRead ?? Math.max((pct > 0 ? Math.floor(window * pct / 100) : 0) - input, 0);
|
|
216
|
+
const responseBytes = positive(at(tm, "assistant_response_length"));
|
|
217
|
+
const output = realOutput ?? estimate(responseBytes ?? assistant);
|
|
218
|
+
if (input + output === 0)
|
|
219
|
+
return;
|
|
220
|
+
out.push({ ...turn(t, model, input, read, output, positive(at(tm, "total_request_count")) ?? 1), index });
|
|
221
|
+
});
|
|
222
|
+
return out;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* The estimated turns of one V3 (KAS) session — its `session.json` (parsed) and the lines of its `messages.jsonl` — that
|
|
226
|
+
* started after `after` (ms). A turn runs to its `turn_end`: its `user` text and `tool_result` text are its fresh input,
|
|
227
|
+
* its `assistant` text its output, and its last `contextUsage` its context. The window is 200,000 (V3 records none).
|
|
228
|
+
*
|
|
229
|
+
* A session converted from another engine (`ensure-session`: a new id, the history copied in) holds turns that store
|
|
230
|
+
* already counted: a turn that ended before the session was created (`createdAt`) is not counted again, nor one whose
|
|
231
|
+
* window holds a request of its source's classic record (`classicTimes`).
|
|
232
|
+
*/
|
|
233
|
+
export function kiroKasTurns(session, jsonlLines, after, classicTimes = []) {
|
|
234
|
+
const model = typeof at(session, "modelId") === "string" && String(at(session, "modelId")).trim() ? String(at(session, "modelId")) : "unknown";
|
|
235
|
+
const created = v3Time(at(session, "createdAt"));
|
|
236
|
+
const turns = [];
|
|
237
|
+
let cur = null;
|
|
238
|
+
const fresh = () => ({ prompt: 0, assistant: 0, tools: 0, pct: 0, promptAt: null, endAt: null, elapsed: null, requests: 0 });
|
|
239
|
+
const close = () => { if (cur && (cur.prompt || cur.assistant || cur.tools))
|
|
240
|
+
turns.push(cur); cur = null; };
|
|
241
|
+
for (const line of jsonlLines) {
|
|
242
|
+
let e;
|
|
243
|
+
try {
|
|
244
|
+
e = JSON.parse(line);
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
const p = obj(at(e, "payload"));
|
|
250
|
+
if (!p || typeof p.type !== "string")
|
|
251
|
+
continue;
|
|
252
|
+
const ts = v3Time(at(e, "timestamp"));
|
|
253
|
+
const text = typeof p.content === "string" ? chars(p.content) : 0;
|
|
254
|
+
switch (p.type) {
|
|
255
|
+
case "user":
|
|
256
|
+
cur ??= fresh();
|
|
257
|
+
cur.prompt += text;
|
|
258
|
+
cur.promptAt ??= ts;
|
|
259
|
+
break;
|
|
260
|
+
case "assistant":
|
|
261
|
+
if (cur)
|
|
262
|
+
cur.assistant += text;
|
|
263
|
+
break;
|
|
264
|
+
case "tool_result":
|
|
265
|
+
cur ??= fresh();
|
|
266
|
+
cur.tools += text;
|
|
267
|
+
break;
|
|
268
|
+
case "session_metadata": {
|
|
269
|
+
const pct = count(at(p, "value", "usagePercentage"));
|
|
270
|
+
if (p.key === "contextUsage" && cur && pct !== null)
|
|
271
|
+
cur.pct = pct;
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
case "usage_summary": {
|
|
275
|
+
const el = count(p.elapsedTime);
|
|
276
|
+
if (cur && el !== null)
|
|
277
|
+
cur.elapsed = el;
|
|
278
|
+
if (cur && Array.isArray(p.requestIds))
|
|
279
|
+
cur.requests = p.requestIds.length;
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
282
|
+
case "turn_end":
|
|
283
|
+
if (cur)
|
|
284
|
+
cur.endAt = ts;
|
|
285
|
+
close();
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
// A turn still being written (no turn_end yet) is not counted now: counted unfinished, the rest of it would come after
|
|
290
|
+
// the cursor's `after` and never be added. It is counted, whole, once it ends.
|
|
291
|
+
const out = [];
|
|
292
|
+
for (const t of turns) {
|
|
293
|
+
const at0 = t.promptAt ?? t.endAt;
|
|
294
|
+
if (at0 === null || !(at0 > after))
|
|
295
|
+
continue;
|
|
296
|
+
if (created !== null && t.endAt !== null && t.endAt < created)
|
|
297
|
+
continue;
|
|
298
|
+
const end = t.endAt ?? at0, start = t.promptAt ?? (t.elapsed !== null ? end - t.elapsed : end);
|
|
299
|
+
if (classicTimes.some(c => c >= start && c <= end))
|
|
300
|
+
continue;
|
|
301
|
+
const input = estimate(t.prompt + t.tools);
|
|
302
|
+
const read = Math.max((t.pct > 0 ? Math.floor(KIRO_DEFAULT_WINDOW * t.pct / 100) : 0) - input, 0);
|
|
303
|
+
const output = estimate(t.assistant);
|
|
304
|
+
if (input + output === 0)
|
|
305
|
+
continue;
|
|
306
|
+
out.push(turn(at0, model, input, read, output, Math.max(1, t.requests)));
|
|
307
|
+
}
|
|
308
|
+
return out;
|
|
309
|
+
}
|
|
310
|
+
//# sourceMappingURL=kiro-usage.js.map
|