Commit Graph
103 Commits
Author SHA1 Message Date
Anatoli Tsinovoy 16ad301117 fix(stats): restore configurable dashboard bind host 2026-08-17 09:46:49 +03:00
can1357 1132c3e31c feat: implemented anthropic keep-alive and migration support for updates
- Added Anthropic prompt-cache refresh scheduling and state management to keep prompts warm across idle sessions.
- Updated pricing models and database stats tracking to calculate and store cost-weighted cache savings.
- Integrated cache savings metrics and efficiency displays into the stats CLI, dashboard routes, and UI components.
- Added support for package renaming, manifest pointer tracking, and installation migration during CLI updates.
2026-08-13 04:59:33 +02:00
can1357 e9888367d1 refactor: migrated packages to internal utility modules and removed external dependencies
- Implemented in-house, zero-dependency utility modules in `pi-utils` covering DOM manipulation, markdown parsing, templating, browser automation helpers, and terminal buffers.
- Migrated packages across the repository to consume the new internal utilities and `omptype` schema validators instead of external dependencies.
- Removed multiple external runtime and development dependencies including Zod, Marked, LRU cache, Turndown, and Puppeteer browser packages.
2026-08-05 13:39:09 +02:00
can1357 191d7f4051 fix(stats): reclaim insecure wildcard dashboards 2026-08-05 01:11:58 +02:00
roboomp 6e3718675e fix(stats): rejected insecure dashboard reuse
Versioned the dashboard identity header and required the current security version with no CORS permission before reusing a listener.

Older versioned and headerless stats dashboards are now identified by their process and restarted so loopback-only binding takes effect immediately.

Fixes #7633
2026-08-04 15:45:45 +00:00
roboomp 70dd7a318e fix(stats): restricted dashboard access
Bound the dashboard and reuse probe to IPv4 loopback, removed wildcard CORS, and reported the actual listening hostname.

Added regression coverage for non-loopback refusal and absent cross-origin access.

Fixes #7633
2026-08-04 15:26:48 +00:00
can1357 455493dfad feat: introduced native file lock bindings for cross-process advisory locking
- Added native `FileLock` bindings supporting cross-process advisory locking on Linux, Unix, and Windows.
- Replaced directory-based file locking and custom stale-lock reclamation with OS-backed native locks.
- Updated TypeScript declarations, native bindings, and package documentation for the new API.
- Added comprehensive unit tests and fixtures validating single-owner constraints and process death handoff.
2026-08-03 16:09:09 +02:00
can1357 9fb082bf14 refactor(utils): consolidated file locking into pi-utils file-lock
- Moved the coding-agent lock-directory primitive to @oh-my-pi/pi-utils/file-lock
  and migrated settings, MCP config-writer, and security store imports.
- Replaced the stats aggregator's parallel ~200-line token/breaker lock protocol
  with the shared primitive: dead owners reclaimed immediately, live-but-wedged
  owners after STATS_SYNC_LOCK_STALE_MS, unstamped acquisitions after the new
  acquireStaleMs grace (10s).
- Shared primitive now treats EPERM kill probes as live owners.
- Rewrote the stats lock-reclamation regressions against the shared protocol
  and moved the file-lock contract test into pi-utils.
2026-08-03 15:25:03 +02:00
can1357 0faa145985 fix(stats): reclaim interrupted sync locks promptly 2026-08-03 15:15:36 +02:00
can1357 c53a47f97d Merge PR #7287: fix(coding-agent): prune archived session stats (@alphastorm)
# Conflicts:
#	packages/coding-agent/src/session/session-manager.ts
2026-08-03 15:15:36 +02:00
roboomp b1ce143a3c fix(stats): added timeout to usage snapshot reads
Installed a five-second SQLite busy timeout before the read-only usage query and covered lock contention with a subprocess-backed regression test.

Fixes #7300
2026-08-01 18:50:54 +00:00
Sunil Srivatsa f3a555ac78 fix(coding-agent): reconcile archived session stats 2026-08-01 14:43:59 -04:00
can1357 3676b5d97f feat: implemented client usage tracking and reporting in the auth broker
- Add usage history, reporting, and client summary endpoints to the auth broker.
- Implement SQLite persistence, batching, and periodic flushing for observed client usage.
- Integrate usage reporting into the coding agent session for completed assistant messages.
- Update stats aggregator and dashboard to retrieve usage history snapshots from the broker.
2026-07-24 15:20:46 +02:00
can1357 30994dafb2 feat(stats): added Providers dashboard with per-provider analytics and utilization insights
- Added `/api/stats/providers` endpoint and database queries returning per-provider request/token/cost totals, hourly burn, and time-series data.
- Created ProvidersRoute UI component with totals panel, trend charts, peak-hours histogram, and window-insights visualizations.
- Added usage-window analytics computing peak utilization fractions, ideal account counts, and exhaustion events from usage snapshots.
- Included comprehensive tests for the aggregation logic, API, and window-stat computations.
2026-07-24 14:41:55 +02:00
roboomp bc5906aeb4 fix(stats): prevented malformed entries from stalling sync
- Guarded malformed persisted content blocks so later project files continue ingesting.
- Marked full-session migrations complete only after a successful sync pass.

Fixes #6373
2026-07-23 18:47:35 +00:00
Wolfgang Schoenberger 9d6e8c2174 fix(stats): clarify overview token totals 2026-07-18 16:40:15 -07:00
roboomp 4ef017232e fix(stats): restricted port reclamation to stats processes
Recorded listener command lines across supported platforms and required an omp-stats-specific command identity before terminating Bun, Node, or omp holders. Unrelated runtimes now take the refusal path without receiving a signal.

Fixes #5970
2026-07-18 07:16:34 +00:00
roboomp 4010bef985 fix(stats): verified dashboard identity before port reuse
Stamped an x-omp-stats-dashboard header on dashboard responses and required it (or the models JSON-array shape) in the reuse probe, so a foreign 200 responder such as an SPA dev server catch-all is no longer mistaken for a live dashboard.

Fixes #5970
2026-07-18 07:10:54 +00:00
roboomp 477112e81d fix(stats): recovered occupied dashboard port
Reused live stats dashboards sharing the requested port and reclaimed stale Bun, Node, or omp listeners after a failed health probe. Foreign listeners now produce an ownership-specific error.

Fixes #5970
2026-07-18 07:04:01 +00:00
roboomp cc9977cce4 fix(advisor): anchored context maintenance on provider usage
- Anchored advisor compaction on provider-reported context usage (cached
  input + generated output) floored by a full local estimate including the
  advisor system prompt and tool schemas, so a near-full cached context is no
  longer undercounted by the per-message estimate.
- Rejected stale provider usage retained across advisor compaction via a
  runtime-only usage-anchor boundary recorded on the summary message.
- Recovered provider overflow by clearing only the advisor's own context at
  the current primary cursor, retrying the bounded failing batch once against
  a fresh context without replaying old primary history, and keeping later
  updates eligible.
- Threaded the selected dashboard range through the stats Recent Errors UI,
  API, and database timestamp filter before ordering and the 50-row limit.

Fixes #5282
2026-07-14 17:58:19 +00:00
can1357 1b0b18c7a6 fix(stats): handled malformed session entries to prevent sync crashes
- Coerce missing `stopReason`, token counts, and timestamps at the parser boundary to satisfy database NOT NULL constraints.
- Skip assistant entries missing essential model attribution or usage data instead of aborting the sync process.
- Filter invalid tool call blocks that lack required identifiers to ensure successful database insertion.
2026-07-12 12:42:37 +02:00
can1357 7df2ac297e fix(stats): handled legacy session entries with missing cost data
- Resolved a crash occurring when syncing legacy session files that lack usage cost breakdowns.
- Updated cost resolution to fallback to catalog pricing when stored cost is unavailable or zero.
2026-07-11 00:08:53 +02:00
can1357 c68a01f597 fix(stats): refined behavior metric extraction and filtering logic
- Adjusted yelling, profanity, and anguish criteria to reduce false-positive metrics.
- Implemented refined regex patterns for negation, blame, and noise reduction.
- Incremented the backfill key to v8 to accommodate updated signal definitions.
- Expanded test suite to validate new constraints for yelling, exclusion words, and sentiment triggers.
2026-07-06 03:55:43 +02:00
can1357 8384acb321 Merge PR #4280: perf(stats): stream session lookup and cache snapcompact JSONL reads (@metaphorics) 2026-07-05 13:25:26 +02:00
metaphorics aac5054c3f perf(stats): stream session lookup and cache snapcompact JSONL reads
getSessionEntry in packages/stats/src/parser.ts previously read the entire session file into memory and parsed every entry just to find one by ID. It now streams the file line-by-line via readLines and returns on the first matching entry, stopping I/O and parsing early. In packages/stats/src/gain-aggregator.ts, readSnapcompactRecords now stats snapcompact-savings.jsonl and caches parsed records keyed by mtimeMs and size, reusing them when the append-only journal has not changed. Cutoff filtering, per-request session:toolCallId deduplication, and project filtering are still applied per call. Verified with bun test test/gain-aggregator.test.ts in packages/stats (3 pass, 0 fail, 16 expect() calls, 1 file, 757.00ms) and bun run check:types.

Closes #4251
2026-07-02 17:30:38 +09:00
can1357 fbf3a6eb3f feat(stats): added tool usage dashboard
- Parsed assistant `toolCall` blocks and `toolResult` messages into persisted `tool_calls` rows with one-shot historical backfill.
- Added tool aggregate queries, model breakdowns, call time-series data, and the `/api/stats/tools` dashboard endpoint.
- Added the `/#/tools` route with summary metrics, stacked calls-over-time chart, per-tool table, and model breakdown panel.
- Added end-to-end stats coverage for tool ingestion, result/error linkage, fork deduplication, incremental updates, and dashboard shaping.
2026-07-02 08:31:18 +02:00
can1357 d20e6c0829 feat: migrated service tier settings to a per-model-family architecture
- Migrated global service tier settings to a per-model-family architecture (OpenAI, Anthropic, Google).
- Implemented `ServiceTierByFamily` mapping to allow independent configuration and resolution per provider.
- Added automatic migration logic for legacy service tier and fast-mode application settings.
- Updated telemetry, session management, and task execution to support provider-specific tier resolution.
2026-06-30 04:14:48 +02:00
roboomp 7d5544493e fix(stats): skipped sync worker smoke on darwin
smokeTestSyncWorker spawned a worker via createSyncWorker on every platform, so omp --smoke-test (and the macOS signing pre-launch run in scripts/ci-macos-sign.sh) still hit the Bun-worker re-entry path the serial macOS sync default avoids. Early-return on darwin and document the carve-out.

Fixes #3733
2026-06-29 11:06:17 +00:00
roboomp 234c1919f5 fix(stats): kept worker pool for one-file syncs
Keyed the serial-parser branch off the caller-requested worker count instead of the per-pool clamp, so a one-file sync still fans out to workers when the caller (or default) asked for more than one.

Fixes #3733
2026-06-28 16:31:17 +00:00
roboomp efb96b123f fix(stats): avoided native jsonl parser trap
Replaced the stats session parser's Bun.JSONL.parseChunk path with a lenient JS line scanner so large session files do not enter the native parser before /stats launches.

Fixes #3733
2026-06-28 16:29:19 +00:00
roboomp b48d488f2c fix(stats): avoided macos stats sync worker abort
Kept the documented workers: 1 path inline and defaulted macOS stats sync to that serial parser path so /stats dashboard launches do not re-enter Bun workers on macOS.

Fixes #3733
2026-06-28 16:21:59 +00:00
can1357 fbad280b57 feat: implemented multi-advisor concurrent runtime with tui management
- Introduced comprehensive support for multiple concurrent, independently-configured advisors via `WATCHDOG.yml` files.
- Implemented a full-screen TUI overlay for managing advisor rosters, models, tools, and instructions.
- Added session-wide advisor initialization, telemetry aggregation, and named transcript isolation.
- Enhanced advisor security and observability with secret redaction in tool results and secure XML attribute encoding.
2026-06-28 12:55:09 +02:00
can1357 5a044dc0da feat: consolidated and automate changelog management
- Added `rewrite-changelog.ts` and `fix-changelogs.ts` utilities to automate the consolidation of release notes using LLM-assisted processing.
- Updated multiple internal changelog files by consolidating redundant entries and improving phrasing for readability.
- Implemented `previewLine` utility in `coding-agent` to prevent visual spillover in status rows by managing text truncation and whitespace.
- Updated `package.json` with new workflow scripts for managing package-level change histories and documentation indexes.
2026-06-27 03:08:52 +02:00
can1357 577d2a8eb8 style: biome format/organize-imports across integrated PRs 2026-06-27 02:06:38 +02:00
can1357 5a1c17c1cb Fix gain dashboard project scoping 2026-06-27 02:04:51 +02:00
David Andrews 619c0aab24 fix(stats/gain): normalize cwd before project match
matchesProject now applies normalizeProjectPath to the raw cwd before
comparing against the selected project root. Without this, a record with
cwd=/repo-worktrees/lane/src would not match the normalized project root
/repo displayed in the selector, causing project-scoped views to show
empty data for any worktree-layout cwd that normalizes to a shorter root.

Addresses codex P2 on commit 8390d278df.
2026-06-26 16:01:27 -04:00
David Andrews 8390d278df fix(stats/gain): address review feedback
- Parse minimizer JSONL once per request; derive records/unparsed/projects
  sets in a single pass instead of three separate reads+parse loops
- Use getTimeRangeConfig from aggregator.ts (export it) instead of a
  local RANGE_MS table that would drift on new range additions
- Fix startsWith project filter to be separator-aware (=== project ||
  startsWith(project+'/')) via shared matchesProject helper — prevents
  false matches on path prefix collisions across all three call sites
- Remove author-specific paths (PycharmProjects, .herdr) from
  normalizeProjectPath; replace with generic worktree-suffix regex
  covering .wt/, -wt/, .worktrees/, -worktrees/, and /.*/worktrees/
  layout patterns, keeping /.omp/wt/ drop
- Exclude snapcompact from project-scoped responses (no cwd field means
  no project filter is possible — mixing all-projects savings into a
  per-project view is misleading); global view still shows snapcompact
- Fix overall.reductionPercent to only divide minimizer+distill saved
  bytes by minimizer+distill original bytes; snapcompact has no
  originalBytes so including it in the numerator overstated the ratio
- Key unparsed command map on the full command string; command field in
  GainUnparsedCommand now stores the full string (callers truncate for
  display) to avoid merging distinct long commands sharing a 120-char
  prefix
- Fix api.ts getGainDashboardStats arg order: project before signal to
  match sibling convention; update GainRoute.tsx call site accordingly
- Add CHANGELOG entry under [Unreleased]
2026-06-26 15:27:57 -04:00
David Andrews 6ed4e4a0ba stats: gain dashboard client — project selector + unparsed commands panel
- GainRoute.tsx: project state, GainProjectSelector dropdown (113 roots),
  GainUnparsedCommandsPanel showing actual command strings + hit count + input bytes
- useHashRoute.ts: added 'gain' to VALID_SECTIONS (was falling back to 'overview')
- api.ts: getGainDashboardStats accepts optional project? param
- formatters.ts, routes.ts, App.tsx: wiring for Gain tab route
2026-06-26 04:16:38 -04:00
David Andrews 0fa4affcc4 stats: gain dashboard — project filter, unparsed commands panel
- GainUnparsedCommand type: actual command strings that had no filter match
  (replaces GainMissedSaving which grouped by filter name — not useful for tuning)
- readMinimizerUnparsedRecords(): filter==='missed' && kind==='missed', skips temp paths
- dedupeProjects(): normalize worktree sub-paths → project roots, drop ephemeral dirs
- getGainDashboardStats(range?, project?): project-scoped reads across all sources,
  top-25 unparsed commands sorted by hit count
- server.ts: ?project= query param forwarded to aggregator
- shared-types.ts: GainUnparsedCommand, GainDashboardStats.{unparsedCommands,project,projects}
2026-06-26 04:16:38 -04:00
roboomp b5769a4e10 fix(stats): dedupe forked-session entries to stop double-counting
SessionManager.fork() and createBranchedSession() deep-copy a parent's
entries into the child JSONL — same entry_id, timestamp, model,
responseId, token counts, cost. Stats keyed uniqueness on
(session_file, entry_id), so both files contributed to request, token,
and cost totals.

insertMessageStats and insertUserMessageStats now skip rows whose
(entry_id, timestamp) already exists under a different session_file
(first-write-wins). A one-shot migration on initDb, gated by the
fork_dedupe_v1 meta sentinel, collapses pre-existing duplicate rows
in messages and user_messages by keeping the lowest-id row per
(entry_id, timestamp) group.

Fixes #3370
2026-06-24 14:14:25 +00:00
can1357 153fd78345 feat(stats): added token usage breakdown by agent type
- Implemented agent type classification and persistence in the database, including a backfill for legacy records.
- Added `AgentType` categorization and aggregated token usage metrics to the backend services.
- Created an `AgentTokenShare` visualization component to display usage distribution on the overview dashboard.
- Integrated agent-based tracking into existing data pipelines, view models, and testing suites.
2026-06-22 17:42:58 +02:00
can1357 f743ddc83d feat: replaced XML-style pi dialect with sigil-delimited format
- Migrated the `pi` AI dialect from legacy XML-style elements to a compact, token-frugal sigil-delimited format using `§` for calls, `""` for body fences, and `¤` for thinking.
- Implemented robust parsing for the new format, including support for incremental streaming of tool arguments and automatic escalation of body fences to prevent content collisions.
- Updated documentation, settings configurations, and test suites across the `ai` and `coding-agent` packages to ensure consistency with the new dialect rules.
- Standardized moderation category terminology in `stats` to improve clarity in reporting metrics.
2026-06-19 01:19:41 +02:00
can1357 71de9a3eb2 Merge PR #2904: fix(stats): contain wide mobile-card tables on narrow desktops (@wolfiesch) 2026-06-18 23:32:53 +02:00
can1357 f5ebab2b83 feat(utils): vendor mermaid rendering 2026-06-18 18:52:38 +02:00
Wolfgang Schoenberger 6295bc9fb4 fix(stats): contain wide mobile-card tables on narrow desktops
The `.stats-table-desktop-only` wrapper used for mobile-card tables
(Requests, Errors, Overview, Projects) lacked the `overflow-x: auto`
containment that `.stats-table-container` already has, so wide tables
spilled the page body horizontally at narrow-desktop widths (768-1023px).
Add a base rule mirroring `.stats-table-container` so these tables scroll
within their own bounds.
2026-06-17 04:12:03 -07:00
lycaon 525f4baa64 feat(stats): redesign the omp stats dashboard
Rewrite the local `omp stats` web UI on the OMP brand palette with a left nav, focused per-section views, a new Projects view, a system-aware light/dark toggle, and flicker-free navigation. Same data, endpoints, and command; the only server change is a 1h time-range bucketing fix in the aggregator.
2026-06-16 23:30:50 -06:00
can1357 3ab675a83b fix: added buffered worker inboxing and standardized worker selectors
- Added `WorkerInbox` and `installWorkerInbox(port)` to queue worker messages before bind.
- Added `consumeWorkerInbox()` to replay buffered messages and clear one active inbox.
- Added buffered inbox consumption in JS and tab worker transports before direct message handlers.
- Normalized worker selector arguments to the `__omp_worker_*` naming across workers and tests.
2026-06-15 11:59:44 +02:00
Scott Hyndmanandcan1357 83d5799dd8 fix(stats): dropped git from profanity list 2026-06-14 17:29:29 +02:00
roboomp 03bead1eac fix(auth): retried SQLITE_BUSY family and hoisted busy_timeout
Concurrent omp --session restores after an unclean shutdown crashed
in SqliteAuthCredentialStore.#initializeSchema() with
SQLITE_BUSY_RECOVERY because the multi-statement schema run installed
PRAGMA busy_timeout=5000 AFTER PRAGMA journal_mode=WAL, the first
lock-taking statement during WAL recovery. Bun's default busy_timeout
is 0, so the lock conflict surfaces immediately.

- packages/ai/src/auth-storage.ts: hoisted PRAGMA busy_timeout to a
  standalone first statement, dropped it from the multi-statement
  schema run, wrapped SqliteAuthCredentialStore.open() in a 4-attempt
  exponential-backoff retry loop on the SQLITE_BUSY family, and the
  exhausted-retry error now includes the DB path. Exported
  isSqliteBusyError(err) (matches code prefix 'SQLITE_BUSY').
- packages/coding-agent/src/session/agent-storage.ts: same hoist and
  the existing retry loop now uses isSqliteBusyError so
  SQLITE_BUSY_RECOVERY / _SNAPSHOT / _TIMEOUT also trigger backoff.
- Hoisted busy_timeout before journal_mode=WAL in every other shared
  SQLite open path: history-storage, autoresearch/storage,
  memories/storage, github-cache, report-tool-issue (auto-QA),
  catalog/model-cache; stats/db.ts now sets busy_timeout at all.
- packages/ai/test/auth-storage-sqlite-busy.test.ts pins the contract:
  isSqliteBusyError matches every BUSY extended code (rejects
  SQLITE_LOCKED, non-errors, strings); open() leaves the connection in
  WAL mode (proves busy_timeout ran before journal_mode); open() retries
  through synthetic SQLITE_BUSY_RECOVERY; non-BUSY errors (SQLITE_CORRUPT)
  short-circuit; exhausted retries throw an error mentioning the DB path
  with exactly 3 sleeps for a 4-attempt budget.

Fixes #2421
2026-06-12 20:17:12 +00:00
can1357 6b76463941 fix: fixed stats dashboard asset serving for bundled CLI distributions
- Fixed npm CLI bundling by invoking `generate-client-bundle.ts --generate` before build and `--reset` after.
- Added `PI_BUNDLED` handling in `packages/stats/src/server.ts` and switched bundled distributions to embedded assets.
- Decoded embedded archives via `decodeEmbeddedClientArchive` and treated legacy placeholder content as missing.
- Handled missing dashboard source/build directories as ENOENT during mtime scans to avoid startup crashes.
- Extended `--smoke-test` to start the stats server and validate dashboard HTML contains expected asset markers.
2026-06-10 10:45:31 +02:00