Refresh agent instruction files
Some checks failed
CI / test (3.10) (push) Has been cancelled
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled

This commit is contained in:
2026-05-18 16:55:44 +02:00
parent a27945101c
commit 4b685e849c
6 changed files with 221 additions and 132 deletions

View File

@@ -1,58 +1,8 @@
## Architecture ## Architecture
llm-connect is structured as a **GAAF-2026 layered library**. See <!-- TODO: Describe the key design decisions and component structure.
`ARCHITECTURE-LAYERS.md` for the full layer map and scorecard. Key modules, data flows, external integrations, state machines, etc. -->
### Layer summary ## Quick Reference
``` `~/state-hub/mcp_server/TOOLS.md` — MCP tool reference
Core (frozen after v1)
LLMAdapter ABC adapter.py
RunConfig / LLMResponse models.py
LLMError hierarchy exceptions.py
MockLLMAdapter adapter.py ← test primitive, belongs with Core
Functional (evolvable, independently shippable)
OpenAIAdapter openai.py
GeminiAdapter gemini.py
OpenRouterAdapter openrouter.py
ClaudeCodeAdapter claude_code.py
EmbeddingAdapter ABC embedding_adapter.py
OpenAICompatibleEmbeddingAdapter embedding_openai.py
EmbeddingCache embedding_cache.py
create_adapter() factory.py
create_embedding_adapter() embedding_factory.py
_token_estimator _token_estimator.py
similarity utilities similarity.py
Configuration (user-controlled declarative state)
resolve_llm() chain toml_config.py ← 7-level TOML priority chain
LLMConfig / load_config config.py
_http shared utility _http.py ← also used by Functional adapters
```
### Dependency rule
Core ← Functional ← Configuration
No upward dependencies. `_http.py` is consumed by Functional only.
### Key design decisions
**API key resolution** (`config.resolve_api_key`): three-step chain —
explicit argument → environment variable → plaintext key file in project root.
Adapters raise `LLMConfigurationError` at construction time if no key is found
(except `ClaudeCodeAdapter` which needs no key).
**TOML config chain** (`toml_config.resolve_llm`): 7 priority levels allow
per-project and per-user LLM preferences. Currently defaults to `markitect`
app_name for backward compatibility — consumers pass their own `app_name`.
**Factory pattern** (`factory.create_adapter`): lazy imports prevent pulling
all provider SDKs at module load. Add a new provider by registering its FQN
in `_PROVIDERS`.
**ClaudeCodeAdapter subprocess model**: prompt is piped via stdin (not CLI
arg) to avoid shell argument length limits on large prompts (>30 KB).
**Retry logic**: `OpenAIAdapter` and `OpenRouterAdapter` retry on 429 and 5xx
with exponential backoff. `GeminiAdapter` does not (rate-limit handling deferred).

View File

@@ -1,17 +1,8 @@
## Repo boundary ## Repo boundary
This repo owns **llm-connect** — the multi-provider LLM client library — only. This repo owns **llm-connect** only. It does not own:
It does NOT own: <!-- TODO: List what belongs in adjacent repos, e.g.:
- SSH key management → railiance-infra/
- **API key storage / secret management** → caller's environment (env vars, - State hub code → state-hub/
key files, vault). llm-connect resolves keys but does not store them. -->
- **Consumer routing logic** → `inter-hub/AgentBridge.hs`, `markitect` etc.
`RoutingPolicy` (WP-0003) provides primitives; policy data belongs in the consumer.
- **The Claude Code CLI binary** → installed separately; `ClaudeCodeAdapter`
shells out to it.
- **markitect application code** → `markitect.llm` is a shim that re-exports
from here; all implementation lives in this repo.
- **State hub / custodian infrastructure** → `the-custodian/state-hub/`
- **IHF bridge scripts** → `inter-hub/scripts/llm_bridge.py` lives in inter-hub,
not here. llm-connect is a dependency of that script.

View File

@@ -1,6 +1,6 @@
## Session Protocol ## Session Protocol
State Hub: http://127.0.0.1:8000 (local) · http://127.0.0.1:18000 (CoulombCore via ops-bridge) State Hub: http://127.0.0.1:8000
**Step 1 — Orient** **Step 1 — Orient**
@@ -8,24 +8,38 @@ Read the offline-safe brief first — it works without a live hub connection:
```bash ```bash
cat .custodian-brief.md cat .custodian-brief.md
``` ```
Then call the MCP tool for richer cross-domain context (skip if unreachable): Then call the MCP tool for richer cross-domain context when MCP tools are exposed:
``` ```
get_domain_summary("custodian") get_domain_summary("custodian")
``` ```
If the hub is offline: `cd ~/the-custodian/state-hub && make api` If MCP tools are unavailable in the current agent session, use the REST API:
```bash
curl -s "http://127.0.0.1:8000/state/summary" | python3 -m json.tool
```
If the hub is offline: `cd ~/state-hub && make api`
**Step 2 — Check inbox** **Step 2 — Check inbox**
With MCP tools:
``` ```
get_messages(to_agent="llm-connect", unread_only=True) get_messages(to_agent="llm-connect", unread_only=True)
``` ```
Mark read with `mark_message_read(message_id)`. Reply or act on coordination Mark read with `mark_message_read(message_id)`. Reply or act on coordination
requests before proceeding. requests before proceeding.
Without MCP tools:
```bash
curl -s "http://127.0.0.1:8000/messages/?to_agent=llm-connect&unread_only=true" \
| python3 -m json.tool
curl -s -X PATCH "http://127.0.0.1:8000/messages/<id>/read" \
-H "Content-Type: application/json" -d '{}'
```
**Step 3 — Scan workplans** **Step 3 — Scan workplans**
```bash ```bash
ls workplans/ ls workplans/
``` ```
For each file with `status: active`, note pending `todo`/`in_progress` tasks. For each file with `status: ready`, `active`, or `blocked`, note pending
`todo`/`in_progress` tasks.
**Step 4 — Present brief** **Step 4 — Present brief**
@@ -45,18 +59,25 @@ If no workstreams: follow First Session Protocol (`first-session.md`).
> are First Session Protocol only. Work structure belongs in repo files (ADR-001). > are First Session Protocol only. Work structure belongs in repo files (ADR-001).
**Session close:** **Session close:**
With MCP tools:
``` ```
add_progress_event(summary="...", topic_id="cee7bedf-2b48-46ef-8601-006474f2ad7a", workstream_id="<uuid>") add_progress_event(summary="...", topic_id="cee7bedf-2b48-46ef-8601-006474f2ad7a", workstream_id="<uuid>")
``` ```
Without MCP tools:
```bash
curl -s -X POST http://127.0.0.1:8000/progress/ \
-H "Content-Type: application/json" \
-d '{"topic_id":"cee7bedf-2b48-46ef-8601-006474f2ad7a","workstream_id":"<uuid>","event_type":"note","summary":"what changed","author":"codex"}'
```
If workplan files were modified, ensure the local copy is up to date first: If workplan files were modified, ensure the local copy is up to date first:
```bash ```bash
git -C <repo_path> pull --ff-only git -C <repo_path> pull --ff-only
cd ~/the-custodian/state-hub && make fix-consistency REPO=llm-connect cd ~/state-hub && make fix-consistency REPO=llm-connect
``` ```
For repos where implementation runs on a remote machine (e.g. CoulombCore), For repos where implementation runs on a remote machine (e.g. CoulombCore),
use the combined target which pulls before fixing: use the combined target which pulls before fixing:
```bash ```bash
cd ~/the-custodian/state-hub && make fix-consistency-remote REPO=llm-connect cd ~/state-hub && make fix-consistency-remote REPO=llm-connect
``` ```
**C-15** (DB task ahead of file) is normal in multi-machine workflows — writeback **C-15** (DB task ahead of file) is normal in multi-machine workflows — writeback
will sync the file to match DB. **C-16** (repo behind remote) blocks all writes will sync the file to match DB. **C-16** (repo behind remote) blocks all writes

View File

@@ -1,59 +1,19 @@
## Stack ## Stack
- **Language:** Python 3.10+ <!-- TODO: Fill in language, frameworks, and key dependencies -->
- **Key deps (runtime):** `toml` (TOML config parsing) - **Language:**
- **Key deps (dev):** `pytest`, `ruff`, `mypy` - **Key deps:**
- **HTTP:** stdlib `urllib` via `_http.py` (no requests/httpx runtime dep)
- **Build:** setuptools / uv
## Dev Commands ## Dev Commands
```bash ```bash
# Install (editable, with dev extras) # TODO: Fill in the standard commands for this repo
uv pip install -e ".[dev]"
# or # Install dependencies
pip install -e ".[dev]"
# Run tests # Run tests
uv run pytest
# or
pytest
# Lint # Lint / type check
uv run ruff check .
# Type check # Build / package (if applicable)
uv run mypy llm_connect
# Run a single test file
uv run pytest tests/test_models.py -v
# Build package (dry run)
uv build --no-sources
```
## Project layout
```
llm_connect/ source package
adapter.py LLMAdapter ABC + Mock/ErrorLLMAdapter
models.py RunConfig, LLMResponse
exceptions.py LLMError hierarchy
factory.py create_adapter()
openai.py OpenAIAdapter
gemini.py GeminiAdapter
openrouter.py OpenRouterAdapter
claude_code.py ClaudeCodeAdapter
embedding_adapter.py EmbeddingAdapter ABC
embedding_openai.py OpenAICompatibleEmbeddingAdapter
embedding_cache.py EmbeddingCache
embedding_factory.py create_embedding_adapter()
toml_config.py 7-level TOML config resolution
config.py LLMConfig, resolve_api_key, find_project_root
_http.py shared HTTP POST utility
_token_estimator.py rough token count estimate
similarity.py cosine similarity utilities
tests/ pytest test suite
contracts/ GAAF-2026 contract docs
workplans/ workplan files (LLM-WP-NNNN)
``` ```

View File

@@ -5,6 +5,22 @@ ID prefix: `LLM-WP`
Work items originate as files in this repo **before** being registered in the hub. Work items originate as files in this repo **before** being registered in the hub.
Canonical workplan/workstream frontmatter statuses are:
`proposed`, `ready`, `active`, `blocked`, `backlog`, `finished`, `archived`.
Use `proposed` for a newly drafted plan, `ready` after review against current
repo state, and `finished` when implementation is complete. `stalled` and
`needs_review` are derived health labels, not stored statuses.
Closed workplans may be moved to `workplans/archived/` with a completion-date
prefix: `YYMMDD-llm-connect-WP-NNNN-<slug>.md`. The frontmatter id remains
unchanged; the prefix is only for quick visual reference.
Small opportunistic tasks discovered during another session use **Ad Hoc Tasks**:
`workplans/ADHOC-YYYY-MM-DD.md`, workstream slug `adhoc-YYYY-MM-DD`, and task ids
`ADHOC-YYYY-MM-DD-T01`, `T02`, etc. Use adhocs only for low-risk work completed
directly. Promote anything requiring analysis, design, approval, dependencies, or
multiple planned phases into a normal workplan.
Ecosystem todos from other agents arrive as `[repo:llm-connect]` hub tasks — Ecosystem todos from other agents arrive as `[repo:llm-connect]` hub tasks —
visible at session start. Pick one up by creating the workplan file, then registering visible at session start. Pick one up by creating the workplan file, then registering
the workstream. the workstream.

171
AGENTS.md
View File

@@ -1,11 +1,162 @@
# llm-connect — Codex Instructions # llm-connect — Agent Instructions
@SCOPE.md ## Repo Identity
@.claude/rules/repo-identity.md
@.claude/rules/session-protocol.md **Purpose:** Multi-provider LLM client library — unified adapter interface for OpenAI, Claude, Gemini, OpenRouter with embedding support, token estimation, and TOML-based config.
@.claude/rules/first-session.md
@.claude/rules/workplan-convention.md **Domain:** custodian
@.claude/rules/stack-and-commands.md **Repo slug:** llm-connect
@.claude/rules/architecture.md **Topic ID:** `cee7bedf-2b48-46ef-8601-006474f2ad7a`
@.claude/rules/repo-boundary.md **Workplan prefix:** `LLM-WP-`
@.claude/rules/agents.md
---
## State Hub Integration
The Custodian State Hub tracks work across all domains. Interact via HTTP REST —
there is no MCP server for Codex agents.
| Context | URL |
|---------|-----|
| Local workstation | `http://127.0.0.1:8000` |
| Remote via tunnel | `http://127.0.0.1:18000` |
### Orient at session start
```bash
# Offline brief — works without hub connection
cat .custodian-brief.md
# Active workstreams for this domain
curl -s "http://127.0.0.1:8000/workstreams/?topic_id=cee7bedf-2b48-46ef-8601-006474f2ad7a&status=active" \
| python3 -m json.tool
# Check inbox
curl -s "http://127.0.0.1:8000/messages/?to_agent=llm-connect&unread_only=true" \
| python3 -m json.tool
```
Mark a message read:
```bash
curl -s -X PATCH "http://127.0.0.1:8000/messages/<id>/read" \
-H "Content-Type: application/json" -d '{}'
```
### Log progress (required at session close)
```bash
curl -s -X POST http://127.0.0.1:8000/progress/ \
-H "Content-Type: application/json" \
-d '{
"summary": "what was done",
"event_type": "note",
"author": "codex",
"workstream_id": "<uuid>",
"task_id": "<uuid>"
}'
```
Omit `workstream_id` / `task_id` when not applicable.
### Update task status
```bash
curl -s -X PATCH "http://127.0.0.1:8000/tasks/<task_id>" \
-H "Content-Type: application/json" \
-d '{"status": "in_progress"}'
# values: todo | in_progress | done | blocked
```
### Flag a task for human review
```bash
curl -s -X PATCH "http://127.0.0.1:8000/tasks/<task_id>" \
-H "Content-Type: application/json" \
-d '{"needs_human": true, "intervention_note": "reason"}'
```
---
## Session Protocol
**Start:**
1. `cat .custodian-brief.md` — domain goal and open workstreams (offline-safe)
2. Check inbox: `GET /messages/?to_agent=llm-connect&unread_only=true`; mark read
3. Scan workplans: `ls workplans/` — note `status: ready`, `active`, or `blocked` files and open tasks
4. Check blocked tasks: `GET /tasks/?needs_human=true`
**During work:**
- Update task statuses in workplan files as tasks progress
- Record significant decisions via `POST /decisions/`
**Close:**
1. Update workplan file task statuses to reflect progress
2. Log: `POST /progress/` with a summary of what changed
3. Note for the custodian operator: after workplan file changes, run from
`~/state-hub`:
```bash
make fix-consistency REPO=llm-connect
```
This syncs task status from files into the hub DB.
---
## Workplan Convention (ADR-001)
Work items originate as files in this repo — not in the hub. The hub is a
read/cache/index layer that rebuilds from files.
**File location:** `workplans/LLM-WP-NNNN-<slug>.md`
**Archived location:** finished workplans may move to
`workplans/archived/YYMMDD-LLM-WP-NNNN-<slug>.md`. The `YYMMDD` prefix is
the completion/archive date; the frontmatter `id` does not change.
**Ad Hoc Tasks:** small opportunistic fixes discovered during a session use
`workplans/ADHOC-YYYY-MM-DD.md` with task ids `ADHOC-YYYY-MM-DD-T01`, etc. Use
this only for low-risk work completed directly; create a normal workplan for
anything needing analysis, design, approval, dependencies, or multiple phases.
**Frontmatter:**
```yaml
---
id: LLM-WP-NNNN
type: workplan
title: "..."
domain: custodian
repo: llm-connect
status: proposed | ready | active | blocked | backlog | finished | archived
owner: codex
topic_slug: ...
created: "YYYY-MM-DD"
updated: "YYYY-MM-DD"
state_hub_workstream_id: "<uuid>" # written by fix-consistency — do not edit
---
```
Use `proposed` for a new draft, `ready` after review against current repo
state, and `finished` after implementation. `stalled` and `needs_review` are
derived health labels, not frontmatter statuses.
**Task block format** (one per `##` section):
```
## Task Title
` ` `task
id: LLM-WP-NNNN-T01
status: todo | in_progress | done | blocked
priority: high | medium | low
state_hub_task_id: "<uuid>" # written by fix-consistency — do not edit
` ` `
Task description text.
```
Status progression: `todo` → `in_progress` → `done` (or `blocked`)
To create a new workplan:
1. Write the file following the format above
2. Notify the custodian operator to run `make fix-consistency REPO=llm-connect`
(or send a message to the hub agent via `POST /messages/`)