pi-mega-compact 0.16.0 → 0.16.2

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.
Files changed (80) hide show
  1. package/dist/extensions/dashboard-server/api-contracts/endpoints/registry.js +7 -0
  2. package/dist/extensions/dashboard-server/api-contracts/model-thresholds.js +1 -0
  3. package/dist/extensions/dashboard-server/routes-model-thresholds.js +167 -0
  4. package/dist/extensions/dashboard-server/routes.js +3 -2
  5. package/dist/extensions/dashboard-server/server.js +6 -2
  6. package/dist/extensions/mega-events/context-handler.js +37 -11
  7. package/dist/src/store/sqlite/model-snapshots.js +21 -0
  8. package/dist/src/store/sqlite/model-thresholds.js +93 -0
  9. package/dist/src/store/sqlite/schema/core.js +10 -0
  10. package/dist/src/store/sqlite.js +1 -0
  11. package/dist/src/vector-search.js +1 -1
  12. package/extensions/dashboard-client/dist/assets/{AreaChart-CrmTcE7w.js → AreaChart-Y_X0Bbjd.js} +2 -2
  13. package/extensions/dashboard-client/dist/assets/{AreaChart-CrmTcE7w.js.map → AreaChart-Y_X0Bbjd.js.map} +1 -1
  14. package/extensions/dashboard-client/dist/assets/{BarChart-Cf8DTaXS.js → BarChart-B9XDb-Ob.js} +2 -2
  15. package/extensions/dashboard-client/dist/assets/{BarChart-Cf8DTaXS.js.map → BarChart-B9XDb-Ob.js.map} +1 -1
  16. package/extensions/dashboard-client/dist/assets/{CacheTab-Ce0MES6p.js → CacheTab-BUGVb1G1.js} +2 -2
  17. package/extensions/dashboard-client/dist/assets/{CacheTab-Ce0MES6p.js.map → CacheTab-BUGVb1G1.js.map} +1 -1
  18. package/extensions/dashboard-client/dist/assets/{EventsTab-DbaUuA58.js → EventsTab-dOqLYTsy.js} +2 -2
  19. package/extensions/dashboard-client/dist/assets/{EventsTab-DbaUuA58.js.map → EventsTab-dOqLYTsy.js.map} +1 -1
  20. package/extensions/dashboard-client/dist/assets/{HealthTab-BmEXkcfL.js → HealthTab-c2vezKg1.js} +2 -2
  21. package/extensions/dashboard-client/dist/assets/{HealthTab-BmEXkcfL.js.map → HealthTab-c2vezKg1.js.map} +1 -1
  22. package/extensions/dashboard-client/dist/assets/{MaintenanceTab-n2JQrMy7.js → MaintenanceTab-bQYHIcdx.js} +2 -2
  23. package/extensions/dashboard-client/dist/assets/{MaintenanceTab-n2JQrMy7.js.map → MaintenanceTab-bQYHIcdx.js.map} +1 -1
  24. package/extensions/dashboard-client/dist/assets/MemoryMapTab-2L8pH6y2.js +2 -0
  25. package/extensions/dashboard-client/dist/assets/{MemoryMapTab-Dvu7vkOm.js.map → MemoryMapTab-2L8pH6y2.js.map} +1 -1
  26. package/extensions/dashboard-client/dist/assets/{MetricsTab-Q0g32AmP.js → MetricsTab-CzUx1jpo.js} +2 -2
  27. package/extensions/dashboard-client/dist/assets/{MetricsTab-Q0g32AmP.js.map → MetricsTab-CzUx1jpo.js.map} +1 -1
  28. package/extensions/dashboard-client/dist/assets/{OverviewTab-iKiEcOLL.js → OverviewTab-eCNoaclv.js} +2 -2
  29. package/extensions/dashboard-client/dist/assets/{OverviewTab-iKiEcOLL.js.map → OverviewTab-eCNoaclv.js.map} +1 -1
  30. package/extensions/dashboard-client/dist/assets/{ReposTab-DWpnv77y.js → ReposTab-tb0IW3NF.js} +2 -2
  31. package/extensions/dashboard-client/dist/assets/{ReposTab-DWpnv77y.js.map → ReposTab-tb0IW3NF.js.map} +1 -1
  32. package/extensions/dashboard-client/dist/assets/{SessionsTab-G0YxR1vG.js → SessionsTab-C-IoLw5h.js} +2 -2
  33. package/extensions/dashboard-client/dist/assets/{SessionsTab-G0YxR1vG.js.map → SessionsTab-C-IoLw5h.js.map} +1 -1
  34. package/extensions/dashboard-client/dist/assets/SetupTab-BvmFi8gf.js +2 -0
  35. package/extensions/dashboard-client/dist/assets/SetupTab-BvmFi8gf.js.map +1 -0
  36. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-1_LCFiJp.js → TimeSavedCard-DBH-cOlA.js} +2 -2
  37. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-1_LCFiJp.js.map → TimeSavedCard-DBH-cOlA.js.map} +1 -1
  38. package/extensions/dashboard-client/dist/assets/{TurnsTab-pqOkjE4L.js → TurnsTab-DBMgmvnX.js} +3 -3
  39. package/extensions/dashboard-client/dist/assets/{TurnsTab-pqOkjE4L.js.map → TurnsTab-DBMgmvnX.js.map} +1 -1
  40. package/extensions/dashboard-client/dist/assets/WikiTab-1LcQrXk3.js +2 -0
  41. package/extensions/dashboard-client/dist/assets/{WikiTab-99sKE4nB.js.map → WikiTab-1LcQrXk3.js.map} +1 -1
  42. package/extensions/dashboard-client/dist/assets/button-DtEsZTUE.js +2 -0
  43. package/extensions/dashboard-client/dist/assets/{button-YcV2VQEP.js.map → button-DtEsZTUE.js.map} +1 -1
  44. package/extensions/dashboard-client/dist/assets/{card-Bwxzo50p.js → card-DcfTmw-4.js} +2 -2
  45. package/extensions/dashboard-client/dist/assets/{card-Bwxzo50p.js.map → card-DcfTmw-4.js.map} +1 -1
  46. package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-C6hlfMYG.js → generateCategoricalChart-BsIxUDyw.js} +2 -2
  47. package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-C6hlfMYG.js.map → generateCategoricalChart-BsIxUDyw.js.map} +1 -1
  48. package/extensions/dashboard-client/dist/assets/{index-DRa2d4TF.js → index-B93cewiX.js} +14 -14
  49. package/extensions/dashboard-client/dist/assets/index-B93cewiX.js.map +1 -0
  50. package/extensions/dashboard-client/dist/assets/index-C_tCbOI0.css +1 -0
  51. package/extensions/dashboard-client/dist/assets/{switch-rU-lor0v.js → switch-Bowd7jCD.js} +2 -2
  52. package/extensions/dashboard-client/dist/assets/{switch-rU-lor0v.js.map → switch-Bowd7jCD.js.map} +1 -1
  53. package/extensions/dashboard-client/dist/assets/{toggle-h-9B4w9X.js → toggle-Bo7kJZ4u.js} +2 -2
  54. package/extensions/dashboard-client/dist/assets/{toggle-h-9B4w9X.js.map → toggle-Bo7kJZ4u.js.map} +1 -1
  55. package/extensions/dashboard-client/dist/assets/{useSSE-BxJORWx8.js → useSSE-zNhb0c3u.js} +2 -2
  56. package/extensions/dashboard-client/dist/assets/{useSSE-BxJORWx8.js.map → useSSE-zNhb0c3u.js.map} +1 -1
  57. package/extensions/dashboard-client/dist/index.html +2 -2
  58. package/extensions/dashboard-client/src/api/client.ts +38 -13
  59. package/extensions/dashboard-client/src/tabs/SetupTab/ThresholdsPanel.tsx +334 -0
  60. package/extensions/dashboard-client/src/tabs/SetupTab.tsx +9 -1
  61. package/extensions/dashboard-server/api-contracts/endpoints/registry.ts +50 -17
  62. package/extensions/dashboard-server/api-contracts/index.ts +28 -3
  63. package/extensions/dashboard-server/api-contracts/model-thresholds.ts +76 -0
  64. package/extensions/dashboard-server/routes-model-thresholds.ts +222 -0
  65. package/extensions/dashboard-server/routes.ts +11 -2
  66. package/extensions/dashboard-server/server.ts +5 -1
  67. package/extensions/mega-events/context-handler.ts +106 -69
  68. package/package.json +1 -1
  69. package/src/store/sqlite/model-snapshots.ts +99 -62
  70. package/src/store/sqlite/model-thresholds.ts +168 -0
  71. package/src/store/sqlite/schema/core.ts +10 -0
  72. package/src/store/sqlite.ts +1 -0
  73. package/src/vector-search.ts +1 -1
  74. package/extensions/dashboard-client/dist/assets/MemoryMapTab-Dvu7vkOm.js +0 -2
  75. package/extensions/dashboard-client/dist/assets/SetupTab-C-y6H-F-.js +0 -2
  76. package/extensions/dashboard-client/dist/assets/SetupTab-C-y6H-F-.js.map +0 -1
  77. package/extensions/dashboard-client/dist/assets/WikiTab-99sKE4nB.js +0 -2
  78. package/extensions/dashboard-client/dist/assets/button-YcV2VQEP.js +0 -2
  79. package/extensions/dashboard-client/dist/assets/index-DRa2d4TF.js.map +0 -1
  80. package/extensions/dashboard-client/dist/assets/index-za_gmEmQ.css +0 -1
@@ -6,78 +6,115 @@ import { openStore } from "./utils.js";
6
6
 
7
7
  /** A captured model/provider snapshot (for cost estimation + dashboard). */
8
8
  export interface ModelSnapshot {
9
- provider: string;
10
- providerName: string | null;
11
- modelId: string;
12
- modelName: string | null;
13
- inputRate: number; // USD per input token
14
- outputRate: number; // USD per output token
15
- contextWindow: number;
16
- maxTokens: number;
17
- reasoning: boolean;
18
- capturedAt: number;
9
+ provider: string;
10
+ providerName: string | null;
11
+ modelId: string;
12
+ modelName: string | null;
13
+ inputRate: number; // USD per input token
14
+ outputRate: number; // USD per output token
15
+ contextWindow: number;
16
+ maxTokens: number;
17
+ reasoning: boolean;
18
+ capturedAt: number;
19
19
  }
20
20
 
21
21
  /** Persist the active model/provider for a repo (latest row wins per repo). */
22
22
  export function recordModelSnapshot(
23
- repoRoot: string,
24
- snap: Omit<ModelSnapshot, "capturedAt">,
25
- stateDir: string = getStateDir(),
23
+ repoRoot: string,
24
+ snap: Omit<ModelSnapshot, "capturedAt">,
25
+ stateDir: string = getStateDir(),
26
26
  ): void {
27
- const db = openStore(stateDir);
28
- db.prepare(
29
- `INSERT INTO model_snapshots
27
+ const db = openStore(stateDir);
28
+ db.prepare(
29
+ `INSERT INTO model_snapshots
30
30
  (repo_root, provider, provider_name, model_id, model_name, input_rate,
31
31
  output_rate, context_window, max_tokens, reasoning, captured_at)
32
32
  VALUES (@repo_root, @provider, @provider_name, @model_id, @model_name,
33
33
  @input_rate, @output_rate, @context_window, @max_tokens, @reasoning, @captured_at)`,
34
- ).run({
35
- repo_root: repoRoot,
36
- provider: snap.provider,
37
- provider_name: snap.providerName,
38
- model_id: snap.modelId,
39
- model_name: snap.modelName,
40
- input_rate: snap.inputRate,
41
- output_rate: snap.outputRate,
42
- context_window: snap.contextWindow,
43
- max_tokens: snap.maxTokens,
44
- reasoning: snap.reasoning ? 1 : 0,
45
- captured_at: Date.now(),
46
- });
34
+ ).run({
35
+ repo_root: repoRoot,
36
+ provider: snap.provider,
37
+ provider_name: snap.providerName,
38
+ model_id: snap.modelId,
39
+ model_name: snap.modelName,
40
+ input_rate: snap.inputRate,
41
+ output_rate: snap.outputRate,
42
+ context_window: snap.contextWindow,
43
+ max_tokens: snap.maxTokens,
44
+ reasoning: snap.reasoning ? 1 : 0,
45
+ captured_at: Date.now(),
46
+ });
47
47
  }
48
48
 
49
49
  /** Most recent model/provider snapshot for a repo, or undefined. */
50
- export function latestModelSnapshot(stateDir: string = getStateDir()): ModelSnapshot | undefined {
51
- const db = openStore(stateDir);
52
- const row = db
53
- .prepare(
54
- `SELECT * FROM model_snapshots ORDER BY captured_at DESC LIMIT 1`,
55
- )
56
- .get() as
57
- | {
58
- provider: string;
59
- provider_name: string | null;
60
- model_id: string;
61
- model_name: string | null;
62
- input_rate: number;
63
- output_rate: number;
64
- context_window: number;
65
- max_tokens: number;
66
- reasoning: number;
67
- captured_at: number;
68
- }
69
- | undefined;
70
- if (!row) return undefined;
71
- return {
72
- provider: row.provider,
73
- providerName: row.provider_name,
74
- modelId: row.model_id,
75
- modelName: row.model_name,
76
- inputRate: row.input_rate,
77
- outputRate: row.output_rate,
78
- contextWindow: row.context_window,
79
- maxTokens: row.max_tokens,
80
- reasoning: row.reasoning === 1,
81
- capturedAt: row.captured_at,
82
- };
50
+ export function latestModelSnapshot(
51
+ stateDir: string = getStateDir(),
52
+ ): ModelSnapshot | undefined {
53
+ const db = openStore(stateDir);
54
+ const row = db
55
+ .prepare(`SELECT * FROM model_snapshots ORDER BY captured_at DESC LIMIT 1`)
56
+ .get() as
57
+ | {
58
+ repo_root: string;
59
+ provider: string;
60
+ provider_name: string | null;
61
+ model_id: string;
62
+ model_name: string | null;
63
+ input_rate: number;
64
+ output_rate: number;
65
+ context_window: number;
66
+ max_tokens: number;
67
+ reasoning: number;
68
+ captured_at: number;
69
+ }
70
+ | undefined;
71
+ if (!row) return undefined;
72
+ return {
73
+ provider: row.provider,
74
+ providerName: row.provider_name,
75
+ modelId: row.model_id,
76
+ modelName: row.model_name,
77
+ inputRate: row.input_rate,
78
+ outputRate: row.output_rate,
79
+ contextWindow: row.context_window,
80
+ maxTokens: row.max_tokens,
81
+ reasoning: row.reasoning === 1,
82
+ capturedAt: row.captured_at,
83
+ };
84
+ }
85
+
86
+ /** All model snapshots (for the dashboard Thresholds table — deduped by
87
+ * caller). Returns NULL columns as-is; callers should default missing
88
+ * context_window/max_tokens to 0. */
89
+ export function listModelSnapshots(
90
+ stateDir: string = getStateDir(),
91
+ ): ModelSnapshot[] {
92
+ const db = openStore(stateDir);
93
+ const rows = db
94
+ .prepare(`SELECT * FROM model_snapshots ORDER BY captured_at DESC`)
95
+ .all() as Array<{
96
+ repo_root: string;
97
+ provider: string;
98
+ provider_name: string | null;
99
+ model_id: string;
100
+ model_name: string | null;
101
+ input_rate: number;
102
+ output_rate: number;
103
+ context_window: number;
104
+ max_tokens: number;
105
+ reasoning: number;
106
+ captured_at: number;
107
+ }>;
108
+ return rows.map((row) => ({
109
+ provider: row.provider,
110
+ providerName: row.provider_name,
111
+ modelId: row.model_id,
112
+ modelName: row.model_name,
113
+ inputRate: row.input_rate,
114
+ outputRate: row.output_rate,
115
+ contextWindow: row.context_window,
116
+ maxTokens: row.max_tokens,
117
+ reasoning: row.reasoning === 1,
118
+ capturedAt: row.captured_at,
119
+ }));
83
120
  }
@@ -0,0 +1,168 @@
1
+ /**
2
+ * model-thresholds.ts — `model_thresholds` table (per-model compaction
3
+ * thresholds, S52 / v0.16.1).
4
+ *
5
+ * Users wanted (2026-08-03 incident follow-up) to tune the compaction safety
6
+ * margin + fire point PER MODEL — different providers'/models' context
7
+ * windows range 8K to 1M+, so one global % is wrong. This table stores the
8
+ * override; absence of a row means "use env/default" (the existing
9
+ * MEGACOMPACT_TIER + the fix-2 default 5% safety margin).
10
+ *
11
+ * Guardrails: PREVENT-001 (null-safe JSON never touches this), PREVENT-002
12
+ * (parameterized — no string concat into SQL), PREVENT-011 (no `any`).
13
+ */
14
+ import type { DatabaseSync } from "node:sqlite";
15
+ import { getStateDir } from "../../store.js";
16
+ import { openStore } from "./utils.js";
17
+
18
+ /** A per-model compaction threshold override. */
19
+ export interface ModelThreshold {
20
+ modelId: string;
21
+ /** 0-20: % of context window reserved AFTER summary + maxOutput as a
22
+ * safety buffer against turn-growth-between-gates. 0% = aggressive
23
+ * (risks "too long even after compaction" errors); 20% = conservative. */
24
+ safetyMarginPct: number;
25
+ /** 10-90: % of context window at which compaction FIRES. Lower = compact
26
+ * earlier (more headroom); higher = compact later (more context before
27
+ * compaction). Default 70 (matches the high tier in config/dedup.ts). */
28
+ firePointPct: number;
29
+ updatedAt: number | null;
30
+ }
31
+
32
+ /** Default safety margin (%) when no per-model override exists. */
33
+ export const DEFAULT_SAFETY_MARGIN_PCT = 5;
34
+ /** Default fire point (%) when no per-model + no env override exists. */
35
+ export const DEFAULT_FIRE_POINT_PCT = 70;
36
+ export const MIN_SAFETY_MARGIN_PCT = 0;
37
+ export const MAX_SAFETY_MARGIN_PCT = 20;
38
+ export const MIN_FIRE_POINT_PCT = 10;
39
+ export const MAX_FIRE_POINT_PCT = 90;
40
+
41
+ function rowToThreshold(r: Record<string, unknown>): ModelThreshold {
42
+ return {
43
+ modelId: r.model_id as string,
44
+ safetyMarginPct: r.safety_margin_pct as number,
45
+ firePointPct: r.fire_point_pct as number,
46
+ updatedAt: (r.updated_at as number) ?? null,
47
+ };
48
+ }
49
+
50
+ /** Get the per-model threshold override, or null when none exists. */
51
+ export function getModelThreshold(
52
+ modelId: string,
53
+ stateDir: string = getStateDir(),
54
+ ): ModelThreshold | null {
55
+ const db = openStore(stateDir);
56
+ const row = db
57
+ .prepare(
58
+ "SELECT model_id, safety_margin_pct, fire_point_pct, updated_at FROM model_thresholds WHERE model_id = ?",
59
+ )
60
+ .get(modelId) as Record<string, unknown> | undefined;
61
+ return row ? rowToThreshold(row) : null;
62
+ }
63
+
64
+ /** List ALL stored per-model thresholds (for the dashboard table). */
65
+ export function listModelThresholds(
66
+ stateDir: string = getStateDir(),
67
+ ): ModelThreshold[] {
68
+ const db = openStore(stateDir);
69
+ const rows = db
70
+ .prepare(
71
+ "SELECT model_id, safety_margin_pct, fire_point_pct, updated_at FROM model_thresholds ORDER BY updated_at DESC",
72
+ )
73
+ .all() as Record<string, unknown>[];
74
+ return rows.map(rowToThreshold);
75
+ }
76
+
77
+ /** Validate a threshold value range. Throws on out-of-bounds. */
78
+ export function assertValidPct(
79
+ pct: number,
80
+ min: number,
81
+ max: number,
82
+ label: string,
83
+ ): void {
84
+ if (!Number.isFinite(pct)) {
85
+ throw new Error(`${label} must be a finite number, got ${pct}`);
86
+ }
87
+ if (pct < min || pct > max) {
88
+ throw new Error(`${label} must be in [${min}, ${max}], got ${pct}`);
89
+ }
90
+ }
91
+
92
+ /** Upsert a per-model threshold. Validates ranges (0-20, 10-90). */
93
+ export function putModelThreshold(
94
+ modelId: string,
95
+ safetyMarginPct: number,
96
+ firePointPct: number,
97
+ stateDir: string = getStateDir(),
98
+ ): ModelThreshold {
99
+ if (!modelId || typeof modelId !== "string") {
100
+ throw new Error("modelId is required");
101
+ }
102
+ assertValidPct(
103
+ safetyMarginPct,
104
+ MIN_SAFETY_MARGIN_PCT,
105
+ MAX_SAFETY_MARGIN_PCT,
106
+ "safetyMarginPct",
107
+ );
108
+ assertValidPct(
109
+ firePointPct,
110
+ MIN_FIRE_POINT_PCT,
111
+ MAX_FIRE_POINT_PCT,
112
+ "firePointPct",
113
+ );
114
+ const db: DatabaseSync = openStore(stateDir);
115
+ const now = Date.now();
116
+ db.prepare(
117
+ `INSERT INTO model_thresholds (model_id, safety_margin_pct, fire_point_pct, updated_at)
118
+ VALUES (?, ?, ?, ?)
119
+ ON CONFLICT(model_id) DO UPDATE SET
120
+ safety_margin_pct = excluded.safety_margin_pct,
121
+ fire_point_pct = excluded.fire_point_pct,
122
+ updated_at = excluded.updated_at`,
123
+ ).run(modelId, safetyMarginPct, firePointPct, now);
124
+ return {
125
+ modelId,
126
+ safetyMarginPct,
127
+ firePointPct,
128
+ updatedAt: now,
129
+ };
130
+ }
131
+
132
+ /** Delete a per-model threshold (revert to env/defaults). */
133
+ export function deleteModelThreshold(
134
+ modelId: string,
135
+ stateDir: string = getStateDir(),
136
+ ): boolean {
137
+ const db = openStore(stateDir);
138
+ const r = db
139
+ .prepare("DELETE FROM model_thresholds WHERE model_id = ?")
140
+ .run(modelId);
141
+ return (r.changes ?? 0) > 0;
142
+ }
143
+
144
+ /**
145
+ * Resolve the EFFECTIVE threshold value for a model: per-model override if
146
+ * present, otherwise the fallback. Used by context-handler.ts to pick the
147
+ * safety margin + fire point without each call duplicating the lookup.
148
+ */
149
+ export function resolveModelThreshold(
150
+ modelId: string | null | undefined,
151
+ opts: {
152
+ safetyMarginFallback: number;
153
+ firePointFallback: number;
154
+ stateDir?: string;
155
+ },
156
+ ): { safetyMarginPct: number; firePointPct: number } {
157
+ const fallback = {
158
+ safetyMarginPct: opts.safetyMarginFallback,
159
+ firePointPct: opts.firePointFallback,
160
+ };
161
+ if (!modelId) return fallback;
162
+ const row = getModelThreshold(modelId, opts.stateDir ?? getStateDir());
163
+ if (!row) return fallback;
164
+ return {
165
+ safetyMarginPct: row.safetyMarginPct,
166
+ firePointPct: row.firePointPct,
167
+ };
168
+ }
@@ -159,6 +159,16 @@ export const CORE_DDL = `
159
159
  );
160
160
  CREATE INDEX IF NOT EXISTS idx_model_repo ON model_snapshots(repo_root);
161
161
 
162
+ -- Per-model compaction thresholds (S52 / v0.16.1). User-tunable % values
163
+ -- that override the env tier defaults + the fix-2 safety margin. One row
164
+ -- per model_id; NULL fallback to env/defaults when no row exists.
165
+ CREATE TABLE IF NOT EXISTS model_thresholds (
166
+ model_id TEXT PRIMARY KEY,
167
+ safety_margin_pct REAL NOT NULL, -- 0-20: reserve after summary+maxOutput
168
+ fire_point_pct REAL NOT NULL, -- 10-90: % of window where compaction fires
169
+ updated_at INTEGER
170
+ );
171
+
162
172
  -- Lessons learned (future recall/browse feature seed).
163
173
  CREATE TABLE IF NOT EXISTS lessons (
164
174
  id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -16,6 +16,7 @@ export * from "./sqlite/checkpoints.js";
16
16
  export * from "./sqlite/session-state.js";
17
17
  export * from "./sqlite/stats.js";
18
18
  export * from "./sqlite/model-snapshots.js";
19
+ export * from "./sqlite/model-thresholds.js";
19
20
  export * from "./sqlite/raptor.js";
20
21
  export * from "./sqlite/raw-transcript.js";
21
22
  export * from "./sqlite/dedup-mirror.js";
@@ -62,7 +62,7 @@ function raptorSearchHits(
62
62
  const stateDir = store.stateDir;
63
63
  const cfg = store.cfg;
64
64
  const embedder = store.embedder;
65
- const record = store.record;
65
+ const record = store.record.bind(store);
66
66
 
67
67
  // S25 gate (a): honor shadow mode at SERVE time. When RAPTOR_SHADOW_MODE=true,
68
68
  // the tree is built + persisted but NOT merged into recall (transition/eval).
@@ -1,2 +0,0 @@
1
- import{j as e,r as u,Z as V,$ as z}from"./index-DRa2d4TF.js";import{T as P}from"./toggle-h-9B4w9X.js";const S={checkpoint:"#6366f1",turn:"#58a6ff","turn-content":"#22c55e",memory:"#f59e0b"},U={checkpoint:"Checkpoint",turn:"Turn","turn-content":"Turn Content",memory:"Memory"};function Y(t,s){return`M 0,-${s} L ${t},0 L 0,${s} L -${t},0 Z`}function Q(t){return!t||t==="active"?1:.5}function Z(t,s,l,h,n,p,c){const x=p?S[h]??"#6366f1":"#d1d5db",i=n?"#ef4444":"none",m=Q(c);switch(h){case"checkpoint":return e.jsx("circle",{cx:t,cy:s,r:n?l+3:l,fill:x,opacity:m,stroke:i,strokeWidth:n?2:0});case"turn":return e.jsx("circle",{cx:t,cy:s,r:n?l+3:l,fill:"none",stroke:x,strokeWidth:2.5,opacity:m});case"turn-content":return e.jsxs("g",{children:[e.jsx("circle",{cx:t,cy:s,r:n?l+3:l,fill:"none",stroke:x,strokeWidth:2.5,opacity:m}),e.jsx("circle",{cx:t,cy:s,r:Math.max(3,l*.3),fill:x,opacity:m})]});case"memory":const d=l*.85,g=l*.85;return e.jsx("path",{d:Y(d,g),transform:`translate(${t}, ${s})`,fill:x,opacity:m,stroke:i,strokeWidth:n?2:0})}}const X=5e3,O=.005,D=.01,_=.9,J=.1,L=50;function K(t){const s=t.nodes.map((n,p)=>{const c=2*Math.PI*p/Math.max(t.nodes.length,1),x=200;return{...n,pos:{x:Math.cos(c)*x+300,y:Math.sin(c)*x+200},vx:0,vy:0,pinned:!1}}),l=new Map;s.forEach((n,p)=>l.set(n.id,p));const h=t.edges.map(n=>{const p=l.get(n.source),c=l.get(n.target);return p===void 0||c===void 0||p===c?null:{source:p,target:c,weight:n.weight,type:n.type}}).filter(n=>n!==null);return{nodes:s,edges:h}}function ee(t){const{nodes:s,edges:l}=t,h=s.length;if(h!==0)for(let n=0;n<h;n++){if(s[n].pinned)continue;let p=0,c=0;for(let i=0;i<h;i++){if(n===i)continue;const m=s[n].pos.x-s[i].pos.x,d=s[n].pos.y-s[i].pos.y,g=m*m+d*d||1,v=X/g,y=Math.sqrt(g);p+=m/y*v,c+=d/y*v}for(const i of l){let m;if(i.source===n)m=i.target;else if(i.target===n)m=i.source;else continue;const d=s[m].pos.x-s[n].pos.x,g=s[m].pos.y-s[n].pos.y;p+=d*O*i.weight,c+=g*O*i.weight}p-=s[n].pos.x*D,c-=s[n].pos.y*D,s[n].vx=(s[n].vx+p)*_,s[n].vy=(s[n].vy+c)*_;const x=Math.sqrt(s[n].vx*s[n].vx+s[n].vy*s[n].vy);x>L&&(s[n].vx=s[n].vx/x*L,s[n].vy=s[n].vy/x*L),x>J&&(s[n].pos.x+=s[n].vx,s[n].pos.y+=s[n].vy)}}const te=300,re=.3,k=900,w=600,f=40;function M(t){switch(t){case"temporal":return"#6366f1";case"semantic":return"#22c55e";case"raptor_parent":return"#f59e0b"}}const N=({color:t,shape:s,label:l})=>{const h={display:"inline-block",width:"10px",height:"10px",verticalAlign:"middle",marginRight:"3px",borderRadius:s.startsWith("hollow")||s==="filled-circle"?"50%":void 0};let n;return s==="line"?e.jsx("span",{style:{color:t,marginRight:"6px"},children:l}):(s==="filled-circle"?n=e.jsx("span",{style:{...h,backgroundColor:t}}):s==="hollow-circle"?n=e.jsx("span",{style:{...h,border:`2px solid ${t}`,backgroundColor:"transparent"}}):s==="hollow-ring"?n=e.jsx("span",{style:{...h,border:`2px solid ${t}`,backgroundColor:"transparent",position:"relative"},children:e.jsx("span",{style:{display:"block",width:"4px",height:"4px",borderRadius:"50%",backgroundColor:t,margin:"2px auto"}})}):n=e.jsx("span",{style:{...h,clipPath:"polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)",backgroundColor:t}}),e.jsxs(e.Fragment,{children:[e.jsxs("span",{className:"memory-map-legend-item",children:[n,l]})," "]}))},se=()=>{const[t,s]=u.useState(null),[l,h]=u.useState(!0),[n,p]=u.useState(null),[c,x]=u.useState(null),[i,m]=u.useState(""),[d]=u.useState(""),[g,v]=u.useState(0),y=u.useRef(null),T=u.useRef(0);u.useEffect(()=>{let r=!1;const o=new URLSearchParams;return d&&o.set("sessionId",d),o.set("threshold","0.7"),o.set("maxEdgesPerNode","4"),h(!0),p(null),fetch(`/api/memory-map?${o.toString()}`).then(a=>{if(!a.ok)throw new Error(`HTTP ${a.status}`);return a.json()}).then(a=>{r||(s(a),y.current=K(a),v(1),h(!1))}).catch(a=>{r||(p(a instanceof Error?a.message:"Unknown error"),h(!1))}),()=>{r=!0,cancelAnimationFrame(T.current)}},[d]),u.useEffect(()=>{if(!y.current||g===0)return;const r=y.current;let o=0;const a=()=>{o>=te||(ee(r),o++,v(o),T.current=requestAnimationFrame(a))};return T.current=requestAnimationFrame(a),()=>cancelAnimationFrame(T.current)},[g]);const F=u.useCallback((r,o)=>{const a=y.current;a&&(a.nodes[o].pinned=!a.nodes[o].pinned,a.nodes[o].pinned||(a.nodes[o].vx=0,a.nodes[o].vy=0),x(b=>b?.id===r.id?null:r),v(b=>b+1))},[]),A=u.useMemo(()=>{const r=y.current;if(!r||!i)return null;const o=i.toLowerCase();return new Set(r.nodes.map((a,b)=>a.summaryTruncated.toLowerCase().includes(o)||a.label.toLowerCase().includes(o)?b:-1).filter(a=>a>=0))},[i]),C=u.useMemo(()=>{const r=t?.validation;return r?r.gatesPassed<r.gatesRun?{level:"red",label:"Gate failure"}:r.warnings.length>0?{level:"yellow",label:`${r.warnings.length} warning(s)`}:{level:"green",label:"Healthy"}:{level:"yellow",label:"No validation"}},[t?.validation]),W={green:"#22c55e",yellow:"#eab308",red:"#ef4444"},H=u.useMemo(()=>{const r=t?.validation;if(!r)return`${t?.metadata.totalNodes??0} nodes`;const o=[];return r.sources.checkpoint>0&&o.push(`${r.sources.checkpoint} checkpoints`),r.sources.turn>0&&o.push(`${r.sources.turn} turns`),r.sources.turnContent>0&&o.push(`${r.sources.turnContent} turn-content`),r.sources.memory>0&&o.push(`${r.sources.memory} memories`),o.length===0&&o.push(`${t?.metadata.totalNodes??0} nodes`),o.join(" · ")},[t?.validation,t?.metadata.totalNodes]),I=u.useMemo(()=>{const r=t?.validation;if(!r)return"";const o=[];return o.push(r.sources.checkpoint>0?"✓ checkpoints":"✗ checkpoints"),o.push(r.sources.turn>0?"✓ turns":"✗ turns"),o.push(r.sources.turnContent>0?"✓ turn-content":"✗ turn-content"),o.push(r.sources.memory>0?"✓ memories":"✗ memories"),o.join(" | ")},[t?.validation]),B=u.useMemo(()=>{const r=t?.validation;return r?r.sources.checkpoint===0&&r.sources.turn===0&&r.sources.turnContent===0&&r.sources.memory===0:t?.metadata.totalNodes===0},[t?.validation,t?.metadata.totalNodes]);if(l)return e.jsx("div",{className:"rounded-lg border border-border bg-bg-card p-6 text-center text-sm text-muted-foreground",children:"Loading memory graph..."});if(n)return e.jsxs("div",{className:"rounded-lg border border-border bg-bg-card p-6 text-center text-sm",children:[e.jsxs("p",{className:"text-red-400",children:["Failed to load memory map: ",n]}),e.jsx("button",{className:"mt-3 rounded-md border border-border px-3 py-1.5 text-sm transition-colors hover:bg-bg-elevated hover:text-foreground",onClick:()=>v(r=>r+1),children:"Retry"})]});if(!t||!y.current||B)return e.jsx("div",{className:"rounded-lg border border-border bg-bg-card p-6 text-sm text-muted-foreground",children:e.jsx("p",{children:"Memories appear after your first compaction. The graph shows checkpoints (compaction summaries) linked by semantic similarity and time. Run a longer session or lower the compaction tier to see it sooner."})});const j=y.current;return e.jsxs("div",{className:"flex flex-col gap-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("input",{type:"text",placeholder:"Search memories...",value:i,onInput:r=>m(r.target.value),className:"w-56 rounded-md border border-border bg-bg-elevated/50 px-3 py-2 text-sm outline-none transition-colors focus:border-primary"}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[e.jsx("span",{children:H})," · ",e.jsxs("span",{children:[t.edges.length," edges"]})]}),e.jsx("span",{className:"ml-auto rounded-full px-2 py-1 text-[11px] font-semibold text-white",style:{backgroundColor:W[C.level]??"#6b7280"},title:`Validation: ${C.label}`,children:C.level==="green"?"Healthy":C.level==="yellow"?"Warnings":"Critical"})]}),I?e.jsx("div",{className:"text-[11px] text-muted-foreground",children:I}):null,e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-1 rounded-lg border border-border/60 bg-bg-card px-3 py-2 text-xs",children:[e.jsx("span",{className:"font-semibold text-muted-foreground",children:"Nodes:"}),e.jsx(N,{type:"node",color:S.checkpoint,shape:"filled-circle",label:"Checkpoint"}),e.jsx(N,{type:"node",color:S.turn,shape:"hollow-circle",label:"Turn"}),e.jsx(N,{type:"node",color:S["turn-content"],shape:"hollow-ring",label:"Turn Content"}),e.jsx(N,{type:"node",color:S.memory,shape:"diamond",label:"Memory"}),e.jsx("span",{className:"font-semibold text-muted-foreground",children:"Edges:"}),e.jsx(N,{type:"edge",color:M("semantic"),shape:"line",label:"Semantic"}),e.jsx(N,{type:"edge",color:M("temporal"),shape:"line",label:"Temporal"}),e.jsx(N,{type:"edge",color:M("raptor_parent"),shape:"line",label:"Raptor"})]}),e.jsxs("svg",{width:k,height:w,viewBox:`0 0 ${k} ${w}`,className:"memory-map-svg",children:[j.edges.map((r,o)=>{const a=j.nodes[r.source],b=j.nodes[r.target],R=M(r.type),E=Math.max(1,r.weight*2.5);return e.jsx("line",{x1:f+a.pos.x/(j.nodes.length||1)*(k-2*f),y1:f+a.pos.y/(j.nodes.length||1)*(w-2*f),x2:f+b.pos.x/(j.nodes.length||1)*(k-2*f),y2:f+b.pos.y/(j.nodes.length||1)*(w-2*f),stroke:R,strokeWidth:E,opacity:re},`edge-${o}`)}),j.nodes.map((r,o)=>{const a=f+r.pos.x/(j.nodes.length||1)*(k-2*f),b=f+r.pos.y/(j.nodes.length||1)*(w-2*f),R=Math.min(20,8+r.tokenEstimate/500),E=A?A.has(o):!0,G=c?.id===r.id,q=r.label.length>20?r.label.slice(0,18)+"...":r.label;return e.jsxs("g",{className:"memory-map-node-group",onClick:()=>F(r,o),style:{cursor:"pointer"},children:[Z(a,b,R,r.nodeType,G,E,r.dedupStatus),e.jsx("text",{x:a,y:b+R+12,textAnchor:"middle",fontSize:"9px",fill:"#374151",className:"memory-map-label",children:q})]},`node-${o}`)})]}),c?e.jsxs("div",{className:"rounded-lg border border-border/60 bg-bg-card p-4 text-sm",children:[e.jsxs("h3",{className:"font-heading text-base font-semibold",children:[e.jsx("span",{className:"mr-1.5 text-xs font-normal text-muted-foreground",children:U[c.nodeType]}),c.label]}),e.jsx("p",{className:"mt-1",children:c.summaryTruncated}),c.topicSummary?e.jsxs("p",{className:"mt-1",children:["Topic: ",c.topicSummary]}):null,e.jsxs("p",{className:"mt-1",children:["Tokens: ",c.tokenEstimate," | Decisions: ",c.decisionCount]}),e.jsxs("p",{children:["Session: ",c.sessionId]}),e.jsxs("p",{children:["Raptor Level: ",c.raptorLevel]}),e.jsx("p",{className:"mt-1 text-muted-foreground",children:c.textSnippet})]}):null]})};function ne(t){return t===0?"#d4a017":t===1?"#3b82f6":"#14b8a6"}function $(t){return t?new Date(t).toLocaleString():"—"}function oe({node:t}){const s=ne(t.level),l=t.children.length>0?`${t.children.length} child${t.children.length===1?"":"ren"}`:"leaf";return e.jsxs("div",{style:{background:"#14142b",border:`1px solid ${s}`,borderRadius:"8px",padding:"0.75rem 1rem",marginBottom:"0.6rem",marginLeft:t.level*24,maxWidth:"90%"},children:[e.jsxs("div",{style:{display:"flex",gap:"0.75rem",alignItems:"center",marginBottom:"0.35rem"},children:[e.jsxs("span",{style:{display:"inline-block",background:s,color:"#fff",borderRadius:"10px",padding:"1px 8px",fontSize:"11px",fontWeight:600},children:["L",t.level]}),e.jsxs("span",{style:{fontSize:"12px",color:"#6b7280"},children:[l," · ",t.tokenEstimate," tok · ",t.qualityMarker]}),e.jsx("span",{style:{fontSize:"12px",color:"#6b7280",marginLeft:"auto"},children:$(t.builtAt)})]}),e.jsx("div",{style:{fontSize:"0.92rem",color:"#e5e7eb"},children:t.summary})]})}function le(){const[t,s]=u.useState(null),[l,h]=u.useState(null),[n,p]=u.useState(!0),[c,x]=u.useState(null);if(u.useEffect(()=>{let d=!1;return p(!0),x(null),Promise.all([V(),z()]).then(([g,v])=>{d||(s(g),h(v),p(!1))}).catch(g=>{d||(x(g instanceof Error?g.message:"Unknown error"),p(!1))}),()=>{d=!0}},[]),n)return e.jsx("div",{className:"rounded-lg border border-border bg-bg-card p-6 text-center text-sm text-muted-foreground",children:"Loading RAPTOR tree..."});if(c)return e.jsx("div",{className:"rounded-lg border border-dashed border-border bg-bg-card p-8 text-center text-sm",children:e.jsxs("p",{className:"text-red-400",children:["Failed to load RAPTOR tree: ",c]})});if(!t||t.empty||t.nodes.length===0)return e.jsx("div",{className:"rounded-lg border border-dashed border-border bg-bg-card p-8 text-center text-sm text-muted-foreground",children:e.jsx("p",{children:"No RAPTOR tree built yet — run a compaction (the tree builds during compaction)."})});const i=l&&!l.empty?l.builds[0]:null,m=i?.coherenceScore!=null?Math.round(i.coherenceScore*100):null;return e.jsxs("div",{className:"w-full p-4",children:[e.jsxs("div",{className:"mb-4 flex items-center gap-6 text-sm text-muted-foreground",children:[e.jsxs("span",{children:[e.jsx("strong",{children:t.nodes.length})," nodes"]}),e.jsxs("span",{children:[e.jsx("strong",{children:t.levels+1})," levels"]}),e.jsxs("span",{children:["Built ",$(t.builtAt??0)]}),i&&e.jsxs(e.Fragment,{children:[e.jsxs("span",{children:["Coherence:"," ",e.jsx("strong",{style:{color:m!=null&&m>=70?"#22c55e":"#f59e0b"},children:m!=null?`${m}%`:"—"})]}),e.jsxs("span",{children:["Leaves: ",e.jsx("strong",{children:i.leafCount})]}),e.jsxs("span",{children:["Depth: ",e.jsx("strong",{children:i.depth})]}),i.timedOut&&e.jsx("span",{style:{color:"#ef4444"},children:"budget timeout"})]})]}),l&&!l.empty&&l.builds.length>1&&e.jsxs("details",{className:"mb-4",children:[e.jsxs("summary",{className:"cursor-pointer text-xs text-muted-foreground",children:["Build history (",l.builds.length," builds)"]}),e.jsx("div",{className:"mt-2 space-y-1",children:l.builds.slice(0,10).map(d=>e.jsxs("div",{className:"flex items-center gap-4 text-xs text-muted-foreground",children:[e.jsx("span",{children:$(d.completedAt)}),e.jsxs("span",{children:[d.nodeCount," nodes"]}),e.jsxs("span",{children:[d.leafCount," leaves"]}),e.jsxs("span",{children:["depth ",d.depth]}),e.jsxs("span",{children:["coherence"," ",d.coherenceScore!=null?`${Math.round(d.coherenceScore*100)}%`:"—"]}),d.timedOut&&e.jsx("span",{style:{color:"#ef4444"},children:"timeout"})]},d.buildId))})]}),t.nodes.map(d=>e.jsx(oe,{node:d},d.id))]})}const ie=()=>{const[t,s]=u.useState("map");return e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxs("nav",{className:"flex gap-2 border-b border-border pb-2 pt-2","aria-label":"Memory map sections",children:[e.jsx(P,{pressed:t==="map",onClick:()=>s("map"),"aria-label":"Memory Map view",children:"Memory Map"}),e.jsx(P,{pressed:t==="raptor",onClick:()=>s("raptor"),"aria-label":"RAPTOR Tree view",children:"RAPTOR Tree"})]}),t==="map"&&e.jsx(se,{}),t==="raptor"&&e.jsx(le,{})]})};export{ie as default};
2
- //# sourceMappingURL=MemoryMapTab-Dvu7vkOm.js.map
@@ -1,2 +0,0 @@
1
- import{r as n,j as e,h as R,i as $,k as G,p as H,l as q,m as V,C as X,n as Y,o as J,q as K,s as Q,t as Z,v as ee}from"./index-DRa2d4TF.js";import{S as te}from"./switch-rU-lor0v.js";import{T as se}from"./toggle-h-9B4w9X.js";function ne(t){try{return new Date(t*1e3).toLocaleString()}catch{return"—"}}function P({achievements:t}){const m=n.useRef(0),[s,g]=n.useState(null),i=t.reduce((r,c)=>Math.max(r,c.unlocked_at??0),0),u=m.current;n.useEffect(()=>{i>m.current&&(m.current=i)},[i]),n.useEffect(()=>{if(u>0&&i>u){const r=t.filter(c=>c.unlocked_at!=null&&(c.unlocked_at??0)>u);if(r.length>0){const c=r.map(o=>`${o.icon??""} ${o.title}`.trim()).join(", ")+" unlocked!";g(c);const p=setTimeout(()=>g(null),4e3);return()=>clearTimeout(p)}}},[t,i,u]);const x=t.filter(r=>!(r.hidden===1&&r.unlocked_at==null));return e.jsxs("div",{className:"ach-section",children:[s!=null&&e.jsx("div",{className:"ach-toast show",children:s}),e.jsxs("div",{className:"ach-tiles",children:[x.length===0&&e.jsx("span",{className:"repo-none",children:"no achievements yet"}),x.map(r=>{if(r.unlocked_at!=null){const c=u>0&&(r.unlocked_at??0)>u;return e.jsxs("div",{className:`ach-tile unlocked${c?" just-unlocked":""}`,children:[r.icon??""," ",r.title,e.jsxs("span",{className:"ach-detail",children:["unlocked ",ne(r.unlocked_at)]})]},r.id)}return e.jsxs("div",{className:"ach-tile locked",children:["??? ",r.title]},r.id)})]})]})}function A(t){return(Math.round(t*10)/10).toString()+"%"}function D(t){return t!=null?new Date(t).toLocaleString():"—"}function U(t){return t&&typeof t=="object"?t:{}}function ae(t){return t.split("/").pop()||t}function z({title:t,rows:m,badge:s,renderValue:g}){return e.jsxs("div",{className:"lb-card",children:[e.jsxs("h3",{children:[t,s]}),m.length===0?e.jsx("div",{className:"lb-empty",children:"—"}):e.jsx("table",{children:e.jsx("tbody",{children:m.map((i,u)=>e.jsxs("tr",{children:[e.jsx("td",{title:i.repo_root,children:ae(i.repo_root)}),e.jsx("td",{className:"num",children:g(i)})]},`${i.repo_root}-${u}`))})})]})}function re(){const[t,m]=n.useState({}),[s,g]=n.useState(0),[i,u]=n.useState([]),[x,r]=n.useState(!1),[c,p]=n.useState(!0),[o,b]=n.useState(null),a=n.useRef(0),f=n.useCallback(async()=>{try{const[h,v,d,y,N,F]=await Promise.all([R({metric:"cache",limit:25}),R({metric:"dedupe",limit:25}),R({metric:"turns",limit:25}),R({metric:"mega_cache",limit:25}),R({metric:"repos",limit:1}),$()]),B=y.find(_=>_.ts>a.current&&_.value>100);a.current>0&&B&&(b(`oopsie! cache went to ${Math.round(B.value)}% — MEGA CACHE 🥧`),setTimeout(()=>b(null),4e3)),y.length>0&&(a.current=Math.max(...y.map(_=>_.ts))),m({cache:h,dedupe:v,turns:d,mega_cache:y}),g(N[0]?.value??0),u(F)}catch{}finally{p(!1)}},[]);n.useEffect(()=>{let h=!0;const v=async()=>{h&&await f()};v();const d=setInterval(()=>void v(),15e3);return()=>{h=!1,clearInterval(d)}},[f]),n.useEffect(()=>{let h=!0;const v=async()=>{try{const y=await G();h&&(r(!!y.game_mode_on),y.theme&&(document.documentElement.dataset.theme=y.theme))}catch{}};v();const d=setInterval(()=>void v(),15e3);return()=>{h=!1,clearInterval(d)}},[]);const w=t.mega_cache??[];let j=null,E=null;for(const h of w){(j==null||h.value>j)&&(j=h.value);const v=U(h.meta),d=v.firstSeenTs??v.firstSeen??h.ts;(E==null||d<E)&&(E=d)}const L=j!=null&&j>100,S=t.turns??[],k=S.reduce((h,v)=>Math.max(h,v.value),0),I=Math.floor(Math.log2(k+1))+1,M=(t.cache?.length??0)>0||(t.dedupe?.length??0)>0||S.length>0||w.length>0||s>0;return e.jsxs("div",{className:`game-tab${x?" game-mode-on":""}`,children:[o!=null&&e.jsx("div",{className:"mega-cache-toast show",children:o}),L&&e.jsxs("div",{className:"mega-cache-banner",children:["🥧"," MEGA CACHE! peak ",A(j)," — first reached ",D(E)]}),L&&e.jsxs("div",{className:"achievement-tile unlocked",children:["🏆"," Opie's Wild Ride",e.jsxs("span",{className:"ach-detail",children:["best ",A(j)," · first ",D(E)]})]}),e.jsx("h2",{children:"High Scores"}),!M&&!c&&e.jsx("div",{className:"game-empty",children:"No scores yet — run a session with game mode on."}),M&&e.jsxs("div",{className:"game-leaderboards",children:[e.jsx(z,{title:"Cache %",rows:t.cache??[],renderValue:h=>A(h.value)}),e.jsx(z,{title:"Dedupe (collapsed)",rows:t.dedupe??[],renderValue:h=>h.value.toLocaleString()}),e.jsx(z,{title:"Turns",rows:S,badge:S.length>0?e.jsxs("span",{className:"lvl-badge",children:["LVL ",I]}):void 0,renderValue:h=>h.value.toLocaleString()}),e.jsx(z,{title:"MEGA CACHE trophies",rows:w,renderValue:h=>e.jsxs(e.Fragment,{children:[A(h.value),e.jsx("span",{className:"lb-meta",children:D(U(h.meta).firstSeenTs??U(h.meta).firstSeen??h.ts)})]})})]}),s>0&&e.jsx("div",{className:"repos-badge-line",children:e.jsxs("span",{className:"repos-badge",children:[s," repos"]})}),e.jsx("h3",{children:"Achievements"}),e.jsx(P,{achievements:i})]})}function le(){const[t,m]=n.useState([]),[s,g]=n.useState(!0),[i,u]=n.useState(null),x=n.useCallback(async()=>{try{const r=await $();m(r),u(null)}catch(r){u(r instanceof Error?r:new Error(String(r)))}finally{g(!1)}},[]);return n.useEffect(()=>{let r=!0;const c=async()=>{r&&await x()};c();const p=setInterval(()=>void c(),15e3);return()=>{r=!1,clearInterval(p)}},[x]),s&&t.length===0?e.jsx("div",{className:"tab-stub",children:"Loading achievements…"}):i&&t.length===0?e.jsxs("div",{className:"tab-stub",children:["Error: ",i.message]}):e.jsxs("div",{className:"achievements-tab",children:[e.jsx("h2",{children:"Achievements"}),e.jsx(P,{achievements:t})]})}const W=[{id:"transparent",label:"Transparent (accents only)",css:{bg:null,fg:"#c9d1d9",accent:"#3fb950",mega:"#f0883e"},ansi:{bg:null,fg:"39",accent:"32",mega:"33"}},{id:"retro",label:"Retro 8-bit green",css:{bg:"#003300",fg:"#33ff33",accent:"#00ff41",mega:"#39ff14"},ansi:{bg:"40",fg:"92",accent:"92",mega:"1;92"}},{id:"orange-bold",label:"Orange bold",css:{bg:"#1a0f00",fg:"#ff8c00",accent:"#ff6b00",mega:"#ff4500"},ansi:{bg:"48;5;52",fg:"38;5;208",accent:"38;5;208",mega:"1;38;5;202"}},{id:"cyan-neon",label:"Cyan neon",css:{bg:"#001a1a",fg:"#00ffff",accent:"#22d3ee",mega:"#7df9ff"},ansi:{bg:"48;5;23",fg:"38;5;51",accent:"38;5;51",mega:"1;38;5;51"}},{id:"amber-mono",label:"Amber phosphor",css:{bg:"#1a1200",fg:"#ffb000",accent:"#ff8c00",mega:"#ff5500"},ansi:{bg:"48;5;58",fg:"38;5;214",accent:"38;5;214",mega:"1;38;5;208"}},{id:"grayscale",label:"Grayscale minimal",css:{bg:"#161616",fg:"#b0b0b0",accent:"#8b949e",mega:"#e6edf3"},ansi:{bg:"48;5;235",fg:"38;5;249",accent:"38;5;249",mega:"1;38;5;255"}}],O=W.map(t=>t.id),T={gameMode:"Turn game mode on/off (themes the widget + dashboard)",theme:"Visual theme (applies instantly)",tuiMode:"TUI widget display density",tier:"Live pressure band — climbs low→mega as context fills the window.",preset:"The env-resolved base compaction preset (low/medium/high/ultra/mega) that set the token threshold.",pressure:"Live pressure = currentTokens / threshold — % of the model context window (threshold fires at the tier's % of window).",threshold:"Compaction threshold = tierPct × model context window — mega-compact trims BELOW pi's native ~80% auto-compact for any model size.",fastGate:"Fast-gate arming floor — the live trim arms once context passes this % of the window."};function ie(t,m,s){let g=t.toLocaleString();return m!=null&&s>0&&(g+=` (${Math.round(m*100)}% of ${s.toLocaleString()})`),g}function oe(t){return`${Math.round((t||0)*100)}%`}function ce(){const[t,m]=n.useState(null),[s,g]=n.useState(null),[i,u]=n.useState(!1);n.useEffect(()=>{let a=!0;const f=async()=>{try{const j=await q();a&&m(j)}catch{}};f();const w=setInterval(()=>void f(),5e3);return()=>{a=!1,clearInterval(w)}},[]),n.useEffect(()=>{let a=!0;const f=async()=>{try{const j=await G();a&&(g(j),j.theme&&(document.documentElement.dataset.theme=j.theme))}catch{}};f();const w=setInterval(()=>void f(),5e3);return()=>{a=!1,clearInterval(w)}},[]);const x=n.useCallback(async a=>{u(!0);try{const f=await H(a);g(f),f.theme&&(document.documentElement.dataset.theme=f.theme)}catch{}u(!1)},[]),r=s?.game_mode_on??!1,c=s?.theme??"transparent",p=s?.tui_display_mode??"full",o=t?.config,b=t?.context.contextWindow??0;return e.jsxs("div",{className:"config-tab",children:[e.jsxs("section",{className:"config-settings",children:[e.jsx("h3",{children:"Settings"}),e.jsx("div",{className:"settings-row",children:e.jsxs("label",{title:T.gameMode,children:[e.jsx("input",{type:"checkbox",checked:r,onChange:a=>x({game_mode_on:a.currentTarget.checked}),disabled:i}),"Game Mode"]})}),e.jsx("div",{className:"settings-row",children:e.jsxs("label",{title:T.theme,children:["Theme",e.jsx("select",{value:c,onChange:a=>x({theme:a.currentTarget.value}),disabled:i,children:W.map(a=>e.jsx("option",{value:a.id,children:a.label},a.id))}),e.jsx("button",{type:"button",disabled:i,className:"theme-cycle-btn",title:"Cycle to the next theme (P3)",onClick:()=>{const a=O.indexOf(c),f=O[(a<0?0:a+1)%O.length];f&&x({theme:f})},children:"Next theme →"})]})}),e.jsx("div",{className:"settings-row",children:e.jsxs("label",{title:T.tuiMode,children:["TUI Mode",e.jsxs("select",{value:p,onChange:a=>x({tui_display_mode:a.currentTarget.value}),disabled:i,children:[e.jsx("option",{value:"full",children:"Full"}),e.jsx("option",{value:"minimal",children:"Minimal"})]})," ",e.jsx("span",{className:"tui-mode-hint",children:"(affects the in-app TUI widget; not shown here)"})]})})]}),e.jsxs("section",{className:"config-display",children:[e.jsx("h3",{children:"Configuration"}),e.jsxs("div",{className:"config-grid",children:[e.jsxs("div",{className:"config-item",children:[e.jsx("span",{className:"config-label",title:T.tier,children:"Tier"}),e.jsx("span",{className:"config-value",children:t?`${t.tier} (live)`:"—"})]}),e.jsxs("div",{className:"config-item",children:[e.jsx("span",{className:"config-label",title:T.preset,children:"Preset"}),e.jsx("span",{className:"config-value",children:t?.presetTier??"—"})]}),e.jsxs("div",{className:"config-item",children:[e.jsx("span",{className:"config-label",title:T.pressure,children:"Pressure"}),e.jsx("span",{className:"config-value",children:t?oe(t.pressure):"—"})]}),e.jsxs("div",{className:"config-item",children:[e.jsx("span",{className:"config-label",title:T.threshold,children:"Threshold"}),e.jsx("span",{className:"config-value",children:o?ie(o.thresholdTokens,o.tierPct,b):"—"})]}),e.jsxs("div",{className:"config-item",children:[e.jsx("span",{className:"config-label",title:T.fastGate,children:"Fast Gate"}),e.jsx("span",{className:"config-value",children:o?`${o.fastGatePct}%`:"—"})]}),e.jsxs("div",{className:"config-item",children:[e.jsx("span",{className:"config-label",children:"Auto"}),e.jsx("span",{className:"config-value",children:o?o.auto?"enabled":"disabled":"—"})]}),e.jsxs("div",{className:"config-item",children:[e.jsx("span",{className:"config-label",children:"Anchor"}),e.jsx("span",{className:"config-value",children:o?.anchorUserMessages??"—"})]})]})]})]})}const C={section:{background:"#1a1a2e",borderRadius:"8px",padding:"1rem",marginBottom:"1rem",border:"1px solid #2a2a4e"},sectionTitle:{fontSize:"1.1rem",fontWeight:700,marginTop:0,marginBottom:"0.75rem",color:"#e0e0e0",borderBottom:"1px solid #333",paddingBottom:"0.5rem"},label:{fontWeight:600,color:"#a0a0c0",marginRight:"0.5rem"},value:{color:"#e0e0e0"},row:{marginBottom:"0.4rem",fontSize:"0.9rem"}};function de(){const[t,m]=n.useState(null),[s,g]=n.useState(null),i=n.useCallback(()=>{V().then(m).catch(p=>g(p instanceof Error?p.message:String(p)))},[]);n.useEffect(()=>{i()},[i]),n.useEffect(()=>{const p=setInterval(i,3e4);return()=>clearInterval(p)},[i]);const u=t?.status==="ok",x=t?.status==="ok"?"Working":t?.status==="unreachable"?"Unreachable":"Error",r=u?"#4caf50":"#f44336",c=u?"✓":"✗";return e.jsxs("div",{style:C.section,children:[e.jsx("h3",{style:C.sectionTitle,children:"Embedder Health"}),s&&e.jsxs("p",{style:{color:"#f44336",fontSize:"0.85rem"},children:["Error: ",s]}),!t&&!s&&e.jsx("p",{style:{color:"#888",fontSize:"0.85rem"},children:"Probing embedder..."}),t&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:C.row,children:[e.jsxs("span",{style:{...C.label,color:`${r}`},children:[c," ",x,":"]}),e.jsxs("span",{style:C.value,children:[t.dim," dims"]}),t.latencyMs!==void 0&&e.jsxs("span",{style:{color:"#a0a0c0",marginLeft:"0.5rem"},children:["(",t.latencyMs.toFixed(1)," ms)"]})]}),e.jsxs("div",{style:C.row,children:[e.jsx("span",{style:C.label,children:"Endpoint:"}),e.jsx("span",{style:C.value,children:t.url??e.jsx("span",{style:{color:"#888"},children:"built-in (no URL)"})})]}),t.error&&e.jsx("p",{style:{color:"#f44336",fontSize:"0.85rem"},children:t.error})]})]})}function me({title:t,children:m}){const[s,g]=n.useState(!0),i=`settings-${t.toLowerCase().replace(/[^a-z0-9]+/g,"-")}`;return e.jsxs("section",{className:"overflow-hidden rounded-xl border border-border bg-bg-elevated/40",children:[e.jsxs("button",{type:"button",onClick:()=>g(u=>!u),className:"flex w-full items-center justify-between rounded-t-xl bg-bg-elevated/60 px-4 py-3 text-left text-sm font-semibold text-foreground transition-colors hover:bg-bg-elevated","aria-expanded":s,"aria-controls":i,children:[e.jsx("span",{children:t}),e.jsx(X,{className:Y("h-4 w-4 text-muted-foreground transition-transform",s&&"rotate-180"),"aria-hidden":"true"})]}),s&&e.jsx("div",{id:i,className:"divide-y divide-border px-4 py-1",children:m})]})}const ue="rounded-md border border-border bg-bg-elevated/50 px-2 py-1 text-sm outline-none transition-colors focus:border-primary disabled:cursor-not-allowed disabled:opacity-50";function he(){return e.jsx("span",{className:"ml-2 inline-flex items-center rounded-md border border-warning/40 bg-warning/15 px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-warning",title:"Requires an LLM embedder (Ollama/HTTP) to be effective",children:"LLM"})}function ge({setting:t,id:m,llmActive:s,saving:g,onUpdate:i}){const[u,x]=n.useState(null),r=t.requiresLlm&&!s,c=n.useRef(null);n.useEffect(()=>()=>{c.current&&clearTimeout(c.current)},[]);const p=n.useCallback(a=>{i(t.key,a).then(f=>x(f)).catch(f=>x(f instanceof Error?f.message:String(f)))},[i,t.key]),o=n.useCallback(a=>{c.current&&clearTimeout(c.current),c.current=setTimeout(()=>p(a),500)},[p]),b=g||r;return e.jsxs("div",{className:"py-2.5",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center text-sm font-semibold text-foreground",children:[e.jsx("label",{htmlFor:`${m}-input`,className:"cursor-pointer",children:t.label}),t.requiresLlm&&!s&&e.jsx(he,{})]}),e.jsx("div",{className:"mt-0.5 text-xs text-muted-foreground",children:t.description})]}),e.jsx("div",{className:"flex shrink-0 items-center gap-2",children:t.type==="boolean"?e.jsx(te,{id:`${m}-input`,checked:!!t.value,disabled:b||r,onCheckedChange:a=>p(String(a)),"aria-label":t.label}):e.jsxs(e.Fragment,{children:[e.jsx("input",{id:`${m}-input`,type:t.type==="number"?"number":"text",defaultValue:String(t.value??""),min:t.min,max:t.max,disabled:b,onChange:a=>o(a.target.value),className:`${ue} ${t.type==="number"?"w-24":"w-56"}`}),t.unit&&e.jsx("span",{className:"text-xs text-muted-foreground",children:t.unit})]})})]}),u&&e.jsxs("p",{className:"mt-1 text-xs text-danger",children:["Error: ",u]})]})}function fe(){const[t,m]=n.useState(null),[s,g]=n.useState(null),[i,u]=n.useState(!1),[x,r]=n.useState(null),c=n.useCallback(()=>{J().then(m).catch(o=>g(o instanceof Error?o.message:String(o)))},[]);n.useEffect(()=>{c()},[c]);const p=n.useCallback(async(o,b)=>{u(!0);try{const a=await K({key:o,value:b});return r(a.restartRequired?"Saved — restart pi to apply changes.":"Saved."),c(),null}catch(a){return a instanceof Error?a.message:String(a)}finally{u(!1)}},[c]);return e.jsxs("div",{className:"flex flex-col gap-3",children:[s&&e.jsxs("p",{className:"text-sm text-danger",children:["Error: ",s]}),!t&&!s&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading settings..."}),t?.categories.map(o=>e.jsx(me,{title:o.name,children:o.settings.map(b=>e.jsx(ge,{setting:b,id:`${o.name.replace(/[^a-z0-9]+/gi,"-")}-${b.key}`,llmActive:t.llmActive,saving:i,onUpdate:p},b.key))},o.name)),x&&e.jsx("div",{className:"mt-1 rounded-md border border-warning/40 bg-warning/10 p-2 text-xs text-warning",role:"status",children:x})]})}const l={container:{padding:"1rem",maxWidth:"720px",margin:"0 auto",fontFamily:"system-ui, sans-serif",color:"#e0e0e0"},section:{background:"#1a1a2e",borderRadius:"8px",padding:"1rem",marginBottom:"1rem",border:"1px solid #2a2a4e"},sectionTitle:{fontSize:"1.1rem",fontWeight:700,marginTop:0,marginBottom:"0.75rem",color:"#e0e0e0",borderBottom:"1px solid #333",paddingBottom:"0.5rem"},label:{fontWeight:600,color:"#a0a0c0",marginRight:"0.5rem"},value:{color:"#e0e0e0"},row:{marginBottom:"0.4rem",fontSize:"0.9rem"},warning:{background:"#3a2a00",border:"1px solid #665500",borderRadius:"8px",padding:"0.75rem",marginTop:"0.5rem",color:"#ffcc00",fontSize:"0.85rem"},badge:{display:"inline-block",padding:"0.15rem 0.5rem",borderRadius:"4px",fontSize:"0.8rem",fontWeight:600,marginLeft:"0.5rem"},detectRow:{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"0.5rem 0",borderBottom:"1px solid #2a2a4e"},button:{background:"#3a5a9f",color:"#fff",border:"none",borderRadius:"6px",padding:"0.5rem 1rem",cursor:"pointer",fontSize:"0.9rem",fontWeight:600}};function xe(){const[t,m]=n.useState(null),[s,g]=n.useState(null),[i,u]=n.useState(null),[x,r]=n.useState(null),[c,p]=n.useState(!1),[o,b]=n.useState(null),[a,f]=n.useState(null),[w,j]=n.useState(null),[E,L]=n.useState(""),S=n.useCallback(()=>{Q().then(m).catch(d=>u(d instanceof Error?d.message:String(d)))},[]),k=n.useCallback((d,y)=>{b(d),j(null),f(null),Z({embedder:d,url:y}).then(N=>{f(N),b(null),S()}).catch(N=>{j(N instanceof Error?N.message:String(N)),b(null)})},[S]),I=n.useCallback(()=>{p(!0),r(null),ee().then(d=>{g(d),p(!1)}).catch(d=>{r(d instanceof Error?d.message:String(d)),p(!1)})},[]);n.useEffect(()=>{S()},[S]),n.useEffect(()=>{const d=setInterval(S,3e4);return()=>clearInterval(d)},[S]);const M=d=>{switch(d){case"trigram":return"TrigramEmbedder (heuristic, default)";case"http":return"HTTP Embedder (BYO localhost)";case"minilm":return"MiniLM (experimental)";default:return"Unknown"}},h=t?.currentEmbedder==="trigram"&&e.jsxs("div",{style:l.warning,children:[e.jsx("strong",{children:"Note:"})," TrigramEmbedder is a heuristic-strength default embedder. It works without any setup but recall quality may be lower than a dedicated embedding backend. If you notice poor recall results, consider installing Ollama and running the"," ",e.jsx("code",{children:"/megasetup"})," command, or set"," ",e.jsx("code",{children:"MEGACOMPACT_EMBEDDING_URL"})," to point at your own localhost embedding server."]}),v=d=>{const y=d?"#1a5a1a":"#3a1a1a",N=d?"#4caf50":"#f44336";return e.jsx("span",{style:{...l.badge,background:y,color:N},children:d?"Detected":"Not found"})};return e.jsxs("div",{style:l.container,children:[e.jsx("h2",{style:{fontSize:"1.3rem",marginTop:0,marginBottom:"1rem"},children:"Embedder Setup"}),e.jsx(de,{}),e.jsxs("div",{style:l.section,children:[e.jsx("h3",{style:l.sectionTitle,children:"Current Embedder Configuration"}),i&&e.jsxs("p",{style:{color:"#f44336",fontSize:"0.85rem"},children:["Error: ",i]}),t&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:l.row,children:[e.jsx("span",{style:l.label,children:"Active Embedder:"}),e.jsx("span",{style:l.value,children:M(t.currentEmbedder)})]}),"configuredEmbedder"in t&&t.configuredEmbedder!==t.currentEmbedder&&e.jsxs("div",{style:l.warning,children:[e.jsx("strong",{children:"Configured but not active:"})," ",M(t.configuredEmbedder)," is configured in .mega-compact.env but not yet loaded."," ",e.jsx("strong",{children:"Restart pi"})," to activate it.",t.configuredUrl&&e.jsxs(e.Fragment,{children:[" (",t.configuredUrl,")"]})]}),"restartRequired"in t&&t.restartRequired&&e.jsxs("div",{style:{...l.row,color:"#ff9800"},children:[e.jsx("span",{style:l.label,children:"Status:"}),e.jsx("span",{style:l.value,children:"Restart required to activate the configured embedder"})]}),e.jsxs("div",{style:l.row,children:[e.jsx("span",{style:l.label,children:"Embedding URL:"}),e.jsx("span",{style:l.value,children:t.embeddingUrl??e.jsx("span",{style:{color:"#888"},children:"not set"})})]}),e.jsxs("div",{style:l.row,children:[e.jsx("span",{style:l.label,children:"Embed Cache:"}),e.jsx("span",{style:l.value,children:t.embedCache??e.jsx("span",{style:{color:"#888"},children:"not set"})})]}),e.jsxs("div",{style:l.row,children:[e.jsx("span",{style:l.label,children:"MiniLM:"}),e.jsx("span",{style:l.value,children:t.minilm?"enabled":"disabled"})]}),h]}),!t&&!i&&e.jsx("p",{style:{color:"#888",fontSize:"0.85rem"},children:"Loading configuration..."})]}),e.jsxs("div",{style:l.section,children:[e.jsx("h3",{style:l.sectionTitle,children:"Local Embedder Detection"}),e.jsx("p",{style:{fontSize:"0.85rem",color:"#a0a0c0",marginTop:0},children:"Detect which local embedding backends are available on this machine. No software is installed — detection only."}),s&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:l.detectRow,children:[e.jsx("span",{children:e.jsx("strong",{children:"Ollama"})}),s.ollama!==null?e.jsxs("span",{children:[v(s.ollama.installed),s.ollama.installed&&e.jsx("span",{style:{fontSize:"0.8rem",color:"#a0a0c0",marginLeft:"0.5rem"},children:s.ollama.running?`server running, ${s.ollama.models.length} model(s)`:"server not running"})]}):e.jsx("span",{style:{color:"#888",fontSize:"0.85rem"},children:"not checked"})]}),e.jsxs("div",{style:l.detectRow,children:[e.jsx("span",{children:e.jsx("strong",{children:"llama.cpp"})}),s.llamaCpp!==null?e.jsxs("span",{children:[v(s.llamaCpp.installed),s.llamaCpp.installed&&s.llamaCpp.detail&&e.jsx("span",{style:{fontSize:"0.8rem",color:"#a0a0c0",marginLeft:"0.5rem"},children:s.llamaCpp.detail})]}):e.jsx("span",{style:{color:"#888",fontSize:"0.85rem"},children:"not checked"})]}),e.jsxs("div",{style:l.detectRow,children:[e.jsx("span",{children:e.jsx("strong",{children:"ONNX Runtime"})}),s.onnx!==null?e.jsxs("span",{children:[v(s.onnx.installed),s.onnx.installed&&s.onnx.detail&&e.jsx("span",{style:{fontSize:"0.8rem",color:"#a0a0c0",marginLeft:"0.5rem"},children:s.onnx.detail})]}):e.jsx("span",{style:{color:"#888",fontSize:"0.85rem"},children:"not checked"})]}),s.error&&e.jsxs("p",{style:{color:"#f44336",fontSize:"0.8rem",marginTop:"0.5rem"},children:["Detection error: ",s.error]})]}),x&&e.jsxs("p",{style:{color:"#f44336",fontSize:"0.85rem"},children:["Error: ",x]}),e.jsxs("div",{style:{marginTop:"1rem"},children:[e.jsx("button",{style:l.button,onClick:I,disabled:c,children:c?"Detecting...":"Run Detection"}),e.jsxs("span",{style:{fontSize:"0.8rem",color:"#888",marginLeft:"0.75rem"},children:["Or run ",e.jsx("code",{children:"/megasetup"})," in the chat for an interactive wizard."]})]}),s&&e.jsxs("div",{style:{marginTop:"1rem",paddingTop:"0.75rem",borderTop:"1px solid #2a2a4e"},children:[e.jsx("div",{style:{fontSize:"0.9rem",fontWeight:600,marginBottom:"0.5rem"},children:"Configure"}),e.jsxs("div",{style:{display:"flex",gap:"0.5rem",flexWrap:"wrap"},children:[e.jsx("button",{style:{...l.button,opacity:s.ollama?.installed?1:.4},onClick:()=>k("ollama"),disabled:!s.ollama?.installed||o!==null,children:o==="ollama"?"Writing...":"Use Ollama"}),e.jsx("button",{style:{...l.button,opacity:s.llamaCpp?.installed?1:.4},onClick:()=>k("llama"),disabled:!s.llamaCpp?.installed||o!==null,children:o==="llama"?"Writing...":"Use llama.cpp"}),e.jsx("button",{style:{...l.button,background:"#444"},onClick:()=>k("trigram"),disabled:o!==null,children:o==="trigram"?"Writing...":"Use Trigram (default)"})]}),a&&e.jsx("div",{style:l.warning,children:a.alreadyActive?"Already active — no restart needed.":`Configured ${a.embedder}. Restart pi to activate (config written to ${a.envPath}).`}),w&&e.jsxs("p",{style:{color:"#f44336",fontSize:"0.85rem",marginTop:"0.5rem"},children:["Configure error: ",w]})]})]}),e.jsxs("div",{style:l.section,children:[e.jsx("h3",{style:l.sectionTitle,children:"Custom Endpoint (remote / third-party)"}),e.jsxs("p",{style:{fontSize:"0.85rem",color:"#a0a0c0",marginTop:0},children:["Point at any OpenAI-compatible embeddings API or hosted endpoint. This opts in to a non-loopback connection (sets"," ",e.jsx("code",{children:"MEGACOMPACT_ALLOW_REMOTE_EMBEDDER=1"}),") — your prompts' embedding requests will be sent to the URL you enter. Default is loopback-only."]}),e.jsxs("div",{style:{display:"flex",gap:"0.5rem",flexWrap:"wrap",alignItems:"center"},children:[e.jsx("input",{type:"url",placeholder:"https://api.example.com/v1/embeddings",value:E,onChange:d=>L(d.target.value),style:{flex:"1 1 300px",background:"#12122a",color:"#e0e0e0",border:"1px solid #2a2a4e",borderRadius:"6px",padding:"0.4rem 0.6rem",fontSize:"0.85rem",fontFamily:"monospace"}}),e.jsx("button",{style:{...l.button,opacity:E?1:.4},onClick:()=>k("custom",E),disabled:!E||o!==null,children:o==="custom"?"Writing...":"Use Custom URL"})]}),e.jsxs("div",{style:l.warning,children:[e.jsx("strong",{children:"Heads up:"})," a remote endpoint receives the text you embed (it does NOT receive your full conversation — only the strings passed to",e.jsx("code",{children:" embed()"})," for recall/dedup). Verify the endpoint's privacy policy before use."]})]}),e.jsxs("div",{style:l.section,children:[e.jsx("h3",{style:l.sectionTitle,children:"How to Upgrade"}),e.jsxs("ul",{style:{fontSize:"0.85rem",lineHeight:1.6,paddingLeft:"1.25rem"},children:[e.jsxs("li",{children:[e.jsx("strong",{children:"Ollama:"})," Install from"," ",e.jsx("a",{href:"https://ollama.com",style:{color:"#6a9fff"},target:"_blank",rel:"noopener noreferrer",children:"ollama.com"}),", then ",e.jsx("code",{children:"ollama pull nomic-embed-text"})," and restart pi. Set ",e.jsx("code",{children:"MEGACOMPACT_EMBEDDING_URL=http://localhost:11434/api/embeddings"}),"."]}),e.jsxs("li",{children:[e.jsx("strong",{children:"llama.cpp:"})," Build or install llama.cpp, run"," ",e.jsx("code",{children:"llama-server"})," with an embedding model, and set the URL accordingly."]}),e.jsxs("li",{children:[e.jsx("strong",{children:"ONNX Runtime:"})," Install"," ",e.jsx("code",{children:"onnxruntime-node"})," in the project root. Not yet integrated — see docs for manual setup."]})]})]}),e.jsxs("div",{style:l.section,children:[e.jsx("h3",{style:l.sectionTitle,children:"Settings"}),e.jsx(fe,{})]})]})}const pe=[{id:"embedder",label:"Embedder"},{id:"config",label:"Config"},{id:"game",label:"Game Mode"},{id:"achievements",label:"Achievements"}];function ye(){const[t,m]=n.useState("embedder");return e.jsxs("div",{className:"mx-auto flex max-w-3xl flex-col gap-4 p-4",children:[e.jsx("nav",{className:"flex gap-2 border-b border-border pb-2","aria-label":"Setup sections",children:pe.map(s=>e.jsx(se,{pressed:t===s.id,onClick:()=>m(s.id),children:s.label},s.id))}),t==="embedder"&&e.jsx(xe,{}),t==="config"&&e.jsx(ce,{}),t==="game"&&e.jsx(re,{}),t==="achievements"&&e.jsx(le,{})]})}export{ye as default};
2
- //# sourceMappingURL=SetupTab-C-y6H-F-.js.map