Skip to content

feat(archetypes): Analyst — answers questions from your local data with SQL and one chart (held) - #4026

Merged
mabry1985 merged 2 commits into
mainfrom
feat/analyst-archetype-held
Oct 3, 2026
Merged

mabry1985 merged 2 commits into
mainfrom
feat/analyst-archetype-held

Conversation

@mabry1985

Copy link
Copy Markdown
Member

Adds the Analyst archetype as a held catalog row (Josh tests before the picker). It answers questions from the operator's own data files with read-only SQL (the data plugin's DuckDB) and shows each answer as one live chart and a one-line takeaway.

Bundle: https://github.com/protoLabsAI/analyst-archetype (v0.1.0 in review, protoLabsAI/analyst-archetype#1)

Changes (same shape as brand-launch, #3981)

  • config/soul-presets/analyst.md: the persona. Its default path is question → schema → query → one chart plus a one-line takeaway. It states its assumptions (date range, metric definition), cites the source file, never invents a number (derived percentages and ratios are computed in SQL too), and keeps answers short. First run: if no data folders are allowlisted, it tells the operator to use Settings ▸ Plugins ▸ Data Analyst ▸ Data folders and never tries to set that itself (data_dirs is operator-only).
  • config/archetype-catalog.json: a held row with _held: "Josh tests before the picker (2026-10-03).", id: analyst, icon ChartColumn (lucide 0.468 has it; BarChart3 is not in icons), the bundle URL, soul_preset: analyst, and requires_tools: [data_query, data_chart].
  • config/plugin-directory.yaml: archetype_repos registers protoLabsAI/analyst-archetype (the catalog→registry guard covers held rows).
  • tests/test_bundled_config_assets.py: test_analyst_archetype_is_held pins the row as held, never served, preset resolving, bundle URL and contract, plus the persona's hard rules.
  • docs/guides/fleet.md: names Analyst among the held rows.

The setup dialog asks for a data folder through the bundle's config_inputs (data.data_dirs, type: path). No core change was needed.

Dependencies

Gates

  • ruff check . ✓ · lint-imports ✓ (4 kept)
  • pytest tests/ -q -n 8: 11843 passed, 17 skipped
  • scripts/live_smoke.py ✓
  • No console changes, so the web unit and e2e suites weren't run.

Live check

I ran a throwaway instance on :7908 from a worktree with #4025 and this branch merged in, with the version set to 0.192.0 locally, on anthropic-oauth:claude-sonnet-5-5:

  1. The setup wizard showed Analyst and its Data folder step.
  2. With the folder left blank, the agent made one data_sources call and returned the Settings path. It made no set_config call.
  3. With data_dirs set to a synthetic coffee-shop CSV, it answered with a bar chart in the Artifact panel and "Saturday sells the most: $2,351 … 38.6% above the overall daily average", plus the assumptions and the source file. The numbers match an independent recompute.

An earlier run had the model compute "28% above" by hand when the real figure was 38%. That's why the persona now requires derived figures to come from SQL.

🤖 Generated with Claude Code

mabry1985 and others added 2 commits October 3, 2026 01:14
…th SQL and one chart (held)

Adds the `analyst` archetype: answers the operator's questions from their own data
files (CSV, TSV, Parquet, JSON, Excel, SQLite) via the data plugin's read-only DuckDB,
with one live Vega-Lite chart and a one-line takeaway. It says what it assumed, cites
the source file, never invents a number (derived figures included), and keeps answers
short. On first run with no data folders, it tells the operator where to set them
(Settings ▸ Plugins ▸ Data Analyst ▸ Data folders) and never tries to set them itself.

- config/soul-presets/analyst.md: the persona.
- archetype-catalog.json: the row is parked in `held` (Josh tests before the picker).
- plugin-directory.yaml: `archetype_repos` registers protoLabsAI/analyst-archetype.
- tests: test_analyst_archetype_is_held pins the held state and the persona's rules.
- docs/guides/fleet.md: names Analyst among the held rows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 19 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: b80ffc88-4253-4dde-a749-2062537065ed
📥 Commits

Reviewing files that changed from the base of the PR and between 7549656 and a7371ec.

📒 Files selected for processing (6)
  • changelog.d/4026.added.md
  • config/archetype-catalog.json
  • config/plugin-directory.yaml
  • config/soul-presets/analyst.md
  • docs/guides/fleet.md
  • tests/test_bundled_config_assets.py
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@protoreview protoreview Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QA panel review — PASS

code-review-structural · head a7371ec7ed0b · formal

Purely additive PR adding a held "Analyst" archetype across catalog, soul preset, plugin directory, docs, and a pinning test. The panel raised a single nit (protopatch) on a missing encoding='utf-8' in the new test's read_text() calls, which the verifier confirmed against the project's own PLW1514 ruff rule. No blockers, no majors, no disagreements. Verification covered all 1 finding; no gaps.

Findings

Severity Location Finding Verified
⚪ nit tests/test_bundled_config_assets.py:423 read_text() without encoding='utf-8' contradicts the codebase's own PLW1514 guardrail enforced via ruff. confirmed
findings JSON (machine-readable)
[
  {
    "file": "tests/test_bundled_config_assets.py",
    "line": 423,
    "severity": "nit",
    "category": "conventions",
    "claim": "read_text() without encoding='utf-8' contradicts the codebase's own PLW1514 guardrail enforced via ruff.",
    "evidence": "Three read_text() calls in this test file omit encoding='utf-8'. The project enforces PLW1514 (unspecified-encoding) via ruff and has a dedicated test (test_catalog_utf8_encoding.py) that sweeps operator_api/ for the same pattern, citing four shipped bugs caused by locale-dependent decoding on Windows.",
    "source": "protopatch",
    "verdict": "confirmed",
    "note": "Verified: lines 395 and 412 of the new test call .read_text() without encoding; pyproject.toml ruff config explicitly selects PLW1514 with preview=true and a detailed justification citing four Windows locale bugs."
  }
]

@protoreview protoreview Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Promoting the PASS verdict for head a7371ec7ed0b: all checks terminal-green, zero unresolved review threads. (approve-on-green)

Open findings carried by this approval — non-blocking, but they did not go away:

  • nit tests/test_bundled_config_assets.py:423 — read_text() without encoding='utf-8' contradicts the codebase's own PLW1514 guardrail enforced via ruff.

Approving a WARN does not resolve its findings (issue #22).

@mabry1985
mabry1985 merged commit 321123d into main Oct 3, 2026
23 checks passed
@mabry1985
mabry1985 deleted the feat/analyst-archetype-held branch October 3, 2026 16:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant