Commit graph

7 commits

Author SHA1 Message Date
AgentSeal
62f6eb27c7 Merge branch 'main' into fix/omp-title-slot-discovery
# Conflicts:
#	src/providers/pi.ts
2026-08-03 21:59:19 +02:00
Aditya Vikram Singh
a4627a1a5a fix(providers): scan bounded leading lines for Pi/OMP session discovery
The shared Pi/OMP discovery gate only checked the first physical line of a
transcript for a `type: "session"` record. Oh My Pi writes a fixed-width
`type: "title"` metadata line before that header (upstream
can1357/oh-my-pi@0ce330a, 2026-06-27), so valid OMP transcripts were rejected
and omitted from `codeburn sessions --provider omp`.

readFirstEntry now scans up to MAX_HEADER_LINES_SCANNED (20) leading lines via
the existing streaming readSessionLines helper, skipping blank lines and
malformed JSON, until it finds a session record. This keeps discovery bounded
for message-only files (and pathological blank/junk-line runs) instead of
reading the whole file, and Pi and OMP continue to share the exact same
discovery path.

Fixes #845
2026-07-29 22:43:01 +05:30
Jan Brennenstuhl
36e5ef0a46
fix(omp): discover title-first session transcripts
Co-authored-by: openai/gpt-5.6-terra <noreply@openai.com>
2026-07-27 19:58:50 +02:00
ozymandiashh
d869ad86e2
fix(pi): classify native skill loads as Skill, not Read (#588) (#590)
Pi and OMP have no dedicated skill tool: a native skill load is emitted as
an ordinary `read` tool call whose path points at the skill's SKILL.md (or a
`skill://<name>` URI in newer OMP builds). The parser mapped every read to the
Read tool and never populated `skills`, so Pi/OMP sessions over-counted Reads
AND always showed an empty "Skills & Agents" breakdown.

Detect these reads (basename === 'SKILL.md', or a skill:// URI), extract the
skill name (parent directory, or the URI segment), and surface the call as the
`Skill` tool with the name recorded in `skills` -- exactly how the Claude
parser represents a skill invocation. That both removes the Read over-count and
lets the shared classifier tag the turn `general` so the Skills & Agents
breakdown picks it up (populating a field the dashboard never received before).
The path is read from arguments.path with a defensive arguments.file_path
fallback.

Tests cover SKILL.md / skill:// / file_path detection, a non-skill read staying
a Read, and an end-to-end check that a parsed skill load reaches the classifier
subCategory that feeds skillBreakdown.
2026-07-01 15:57:31 +02:00
Resham Joshi
e8009c4559
fix(parser): tolerate string message content; isolate per-file parse failures (#441) (#450)
Some checks are pending
CI / semgrep (push) Waiting to run
Some agents (Pi, and others for injected turns) write a message's `content`
as a string instead of an array of blocks. Parsers did `(content ?? []).filter`,
which throws on a string — and because the daily-cache backfill swallowed parse
errors, one bad session silently wiped the entire trend/history.

- Add normalizeContentBlocks(): string -> one text block, array -> as-is (by
  reference; drops null/undefined elements so the same crash can't happen one
  level down), else -> []. Applied across pi/codex/droid/cursor-agent and the
  Claude path in parser.ts.
- Isolate per-file parse failures in parseProviderSources: skip the offending
  file (warn once per provider) instead of re-throwing and aborting the whole
  backfill. The stale cache entry is already cleared, so the file is excluded.
- Surface backfill failures in hydrateCache via stderr instead of silently
  returning an empty cache.

Likely fixes #425 (previous-day always 0) for the throwing-file cause.
Tests: content-utils unit tests + a Pi string-content regression test.
2026-06-06 04:01:12 +02:00
AgentSeal
d92d5b3f26 chore: normalize Pi tool names via toolNameMap
Maps Pi's lowercase tool names (bash, read, edit, write...) to
the capitalized form used by every other provider, so the
dashboard shows consistent tool names across providers and the
activity classifier works without extra lowercase entries.

Reverts the lowercase additions to classifier.ts since the
provider now normalizes tool names at the source.
2026-04-16 01:57:39 -07:00
Damian Jackson
7ac512a7e4 feat: add Pi provider for tracking Pi agent sessions
- Adds support for Pi (pi.ai) as a new session provider.
- Pi sessions are stored as JSONL files under `~/.pi/agent/sessions/<project-dir>/` and use OpenAI-compatible model IDs (gpt-5, gpt-5.4, gpt-4o, etc.).

- `src/providers/pi.ts` (new): Pi provider - discovers JSONL session files, parses assistant turns, extracts token counts, tool calls, and bash commands, deduplicates via response ID with line-index fallback
- `src/providers/types.ts`: added bashCommands field to `ParsedProviderCall` so all providers carry extracted bash command lists
- `src/providers/index.ts`: registered Pi as a core provider alongside Claude and Codex
- `src/providers/codex.ts`, `cursor.ts`: added `bashCommands: []` to satisfy the new required field on `ParsedProviderCall`
- `src/parser.ts`: fixed bug where `providerCallToTurn` always emitted an empty bashCommands array instead of passing through the parsed commands
- `src/classifier.ts`: added lowercase tool name variants (bash, edit, read, write) to match Pi's tool naming convention in JSONL output
- `src/bash-utils.ts`: exclude `true`, `false`, and shell variable assignments from extracted commands; scan past leading `NAME=val` tokens so `FOO=bar ls` correctly records `ls` rather than being dropped
- `package.json`: added pi to keywords
- `tests/providers/pi.test.ts` (new): 16 unit tests covering session discovery, multi-turn parsing, tool/bash extraction, deduplication, zero-token filtering, and display name mapping
- `tests/provider-registry.test.ts`: updated core provider list to include pi

- [X] Unit tests pass (`npx vitest run`, 56 tests across 6 files);
- [X] Manually verified via `npx tsx src/cli.ts` report and showing Pi sessions alongside Claude and Codex in the dashboard.
2026-04-16 01:54:42 -07:00