The fixture chat panel is now a working agent. Ask Reginald a question → it consults the real project through a tool loop → answers in grounded prose. Read-only v0 (writes still go through propose-approve). Branch cut from main, targets main — no stacking.
Core (@commitea/core/agent)
chat-client — OpenAI-wire chat completions over an injected fetch (same seam as gitea). Any OpenAI-compatible endpoint: LM Studio, Ollama, OpenAI.
model-router — small model for prose + the read tool; big model reserved for later decomposition.
agent-loop — runAgentTurn drives call→tool→result→call until prose (or a step budget), recording each step. Injected complete + execute → fully testable offline.
query-project — the single read tool's engine: compact focus/board/calibration/issue/search views from scheduler + lifecycle + calibration. Unbuilt views return a notImplemented marker — never fabricated. The model reports, never computes.
agent-tools — query_project declaration + Reginald's system prompt.
App
main model bridge (model:status, model:chat) runs the loop; query_project reconciles the repo and builds the view. Model traffic stays in main (token/CSP). gitea.ts refactored to share getGiteaClient + reconcileSnapshot.
preload + global.d.ts expose the bridge; useChat drives the panel — real agent turn when a model is configured, scripted fixture reply otherwise (fixture e2e unchanged). Subtle "consulted the project" activity line.
Config
Env, defaults to LM Studio on :1234: COMMITEA_MODEL_URL / _SMALL (google/gemma-4-e4b) / _BIG (qwen/qwen3.6-35b-a3b). COMMITEA_E2E=1 keeps it unconfigured so the panel stays scripted.
Verified
88 core tests green (14 agent: client parse, loop tool/error/step-budget, all views) + a gated live integration test against the real model. Desktop typecheck clean, 14 fixture e2e green.
Gated live e2e drives the real app against gitea + gemma-4-e4b: asked "What should I work on right now?", Reginald called query_project(focus) and answered "The current focus is on issue #2" — the real scheduler pick. Screenshot in the PR.
Next (Reginald, continued)
Writes via chat: route apply_changes (engine from #41) through the loop with mid-turn propose-approve — chat becomes the write-path in full.
Big-model routing for capture_work decomposition; record_directive → the pm-state ledger.
More query_project views (milestone/runway/standup) + streaming.
Depends on nothing outstanding; #41 (apply_changes) is independent and can merge in either order.
The fixture chat panel is now a **working agent**. Ask Reginald a question → it consults the real project through a tool loop → answers in grounded prose. Read-only v0 (writes still go through propose-approve). Branch cut from `main`, targets `main` — no stacking.
## Core (`@commitea/core/agent`)
- **chat-client** — OpenAI-wire chat completions over an injected fetch (same seam as gitea). Any OpenAI-compatible endpoint: LM Studio, Ollama, OpenAI.
- **model-router** — small model for prose + the read tool; big model reserved for later decomposition.
- **agent-loop** — `runAgentTurn` drives call→tool→result→call until prose (or a step budget), recording each step. Injected `complete` + `execute` → fully testable offline.
- **query-project** — the single read tool's engine: compact `focus`/`board`/`calibration`/`issue`/`search` views from scheduler + lifecycle + calibration. Unbuilt views return a `notImplemented` marker — **never fabricated**. The model reports, never computes.
- **agent-tools** — `query_project` declaration + Reginald's system prompt.
## App
- main **model bridge** (`model:status`, `model:chat`) runs the loop; `query_project` reconciles the repo and builds the view. **Model traffic stays in main** (token/CSP). `gitea.ts` refactored to share `getGiteaClient` + `reconcileSnapshot`.
- preload + `global.d.ts` expose the bridge; **`useChat`** drives the panel — real agent turn when a model is configured, scripted fixture reply otherwise (fixture e2e unchanged). Subtle *"consulted the project"* activity line.
## Config
Env, defaults to LM Studio on `:1234`: `COMMITEA_MODEL_URL` / `_SMALL` (`google/gemma-4-e4b`) / `_BIG` (`qwen/qwen3.6-35b-a3b`). `COMMITEA_E2E=1` keeps it unconfigured so the panel stays scripted.
## Verified
88 core tests green (14 agent: client parse, loop tool/error/step-budget, all views) + a **gated live integration test** against the real model. Desktop typecheck clean, 14 fixture e2e green.
**Gated live e2e drives the real app** against gitea + `gemma-4-e4b`: asked *"What should I work on right now?"*, Reginald called `query_project(focus)` and answered *"The current focus is on issue #2"* — the real scheduler pick. Screenshot in the PR.
## Next (Reginald, continued)
- **Writes via chat**: route `apply_changes` (engine from #41) through the loop with mid-turn propose-approve — chat becomes the write-path in full.
- Big-model routing for `capture_work` decomposition; `record_directive` → the pm-state ledger.
- More `query_project` views (milestone/runway/standup) + streaming.
_Depends on nothing outstanding; #41 (apply_changes) is independent and can merge in either order._
🤖 Generated with [Claude Code](https://claude.com/claude-code)
christian
added 1 commit 2026-07-09 00:43:35 +00:00
The fixture chat panel is now a working agent. Ask Reginald a question and it
consults the real project through a tool loop, then answers in grounded prose.
Read-only v0 — writes still go through the propose-approve controls.
core (@commitea/core/agent):
- chat-client: OpenAI-wire chat completions over an injected fetch (same seam as
gitea). Points at any OpenAI-compatible endpoint (LM Studio/Ollama/OpenAI).
- model-router: small model for prose + the read tool; big model reserved for
later decomposition (pickModel).
- agent-loop: runAgentTurn drives call→tool→result→call until prose (or a step
budget), recording each tool step. Injected complete + execute → fully testable.
- query-project: the single read tool's engine — compact focus/board/calibration/
issue/search views built from scheduler + lifecycle + calibration; unbuilt views
return a notImplemented marker (never fabricated). The model reports, never computes.
- agent-tools: query_project declaration + Reginald's system prompt.
app:
- main model bridge (model:status, model:chat) runs the loop; query_project
reconciles the repo and builds the view. Model traffic stays in main (token/CSP).
gitea.ts refactored to share getGiteaClient + reconcileSnapshot.
- preload + global.d.ts expose the model bridge; useChat drives the panel — real
agent turn when a model is configured, scripted fixture reply otherwise (so
fixture e2e is unchanged). A subtle "consulted the project" activity line.
Model config (env, defaults to LM Studio on :1234): COMMITEA_MODEL_URL /
_SMALL (google/gemma-4-e4b) / _BIG (qwen/qwen3.6-35b-a3b). COMMITEA_E2E=1 keeps
it unconfigured so the panel stays scripted.
Verified: 88 core tests green (14 agent: client parse, loop tool/error/budget,
all views) + a gated live integration test. Desktop typecheck clean, 14 fixture
e2e green. Gated live e2e drives the real app against gitea + gemma-4-e4b: asked
"what now?", Reginald called query_project and answered "focus is on issue #2"
(the real scheduler pick).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
christian
added 1 commit 2026-07-09 01:03:26 +00:00
Instead of a hardcoded model name (which forces LM Studio to JIT-swap your loaded
model out — and fails when a big model already fills memory), resolve the model
at request time: an explicit env override wins, else ask the server which model
is *loaded* (LM Studio's native /api/v0/models), else the first non-embedding
model, else a default. Reginald now uses whatever you load, no config churn.
- main/model.ts: resolveLoadedModel() drives both model:status and model:chat;
COMMITEA_MODEL_SMALL still overrides.
- useChat exposes the resolved model id; the panel header shows it
(google/gemma-4-26b-a4b-qat → "gemma-4-26b-a4b · local").
- live-reginald e2e: header assertion relaxed to the loaded model; timeouts
raised for a slow big local model (~2 calls/turn + a reconcile).
Verified: 14 fixture e2e green; live e2e drives the app against the loaded
gemma-4-26b — "What now?" → "You should work on #2 … on the critical path,
unblocks #33 and #4" (the real scheduler pick), header shows the live model.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The fixture chat panel is now a working agent. Ask Reginald a question → it consults the real project through a tool loop → answers in grounded prose. Read-only v0 (writes still go through propose-approve). Branch cut from
main, targetsmain— no stacking.Core (
@commitea/core/agent)runAgentTurndrives call→tool→result→call until prose (or a step budget), recording each step. Injectedcomplete+execute→ fully testable offline.focus/board/calibration/issue/searchviews from scheduler + lifecycle + calibration. Unbuilt views return anotImplementedmarker — never fabricated. The model reports, never computes.query_projectdeclaration + Reginald's system prompt.App
model:status,model:chat) runs the loop;query_projectreconciles the repo and builds the view. Model traffic stays in main (token/CSP).gitea.tsrefactored to sharegetGiteaClient+reconcileSnapshot.global.d.tsexpose the bridge;useChatdrives the panel — real agent turn when a model is configured, scripted fixture reply otherwise (fixture e2e unchanged). Subtle "consulted the project" activity line.Config
Env, defaults to LM Studio on
:1234:COMMITEA_MODEL_URL/_SMALL(google/gemma-4-e4b) /_BIG(qwen/qwen3.6-35b-a3b).COMMITEA_E2E=1keeps it unconfigured so the panel stays scripted.Verified
88 core tests green (14 agent: client parse, loop tool/error/step-budget, all views) + a gated live integration test against the real model. Desktop typecheck clean, 14 fixture e2e green.
Gated live e2e drives the real app against gitea +
gemma-4-e4b: asked "What should I work on right now?", Reginald calledquery_project(focus)and answered "The current focus is on issue #2" — the real scheduler pick. Screenshot in the PR.Next (Reginald, continued)
apply_changes(engine from #41) through the loop with mid-turn propose-approve — chat becomes the write-path in full.capture_workdecomposition;record_directive→ the pm-state ledger.query_projectviews (milestone/runway/standup) + streaming.Depends on nothing outstanding; #41 (apply_changes) is independent and can merge in either order.
🤖 Generated with Claude Code
d70c6e2542to25cf0a6d39