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
llm-connect is structured as a **GAAF-2026 layered library**. See
`ARCHITECTURE-LAYERS.md` for the full layer map and scorecard.
<!-- TODO: Describe the key design decisions and component structure.
Key modules, data flows, external integrations, state machines, etc. -->
### Layer summary
## Quick 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).
`~/state-hub/mcp_server/TOOLS.md` — MCP tool reference

View File

@@ -1,17 +1,8 @@
## 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:
- **API key storage / secret management** → caller's environment (env vars,
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.
<!-- TODO: List what belongs in adjacent repos, e.g.:
- SSH key management → railiance-infra/
- State hub code → state-hub/
-->

View File

@@ -1,6 +1,6 @@
## 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**
@@ -8,24 +8,38 @@ Read the offline-safe brief first — it works without a live hub connection:
```bash
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")
```
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**
With MCP tools:
```
get_messages(to_agent="llm-connect", unread_only=True)
```
Mark read with `mark_message_read(message_id)`. Reply or act on coordination
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**
```bash
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**
@@ -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).
**Session close:**
With MCP tools:
```
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:
```bash
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),
use the combined target which pulls before fixing:
```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
will sync the file to match DB. **C-16** (repo behind remote) blocks all writes

View File

@@ -1,59 +1,19 @@
## Stack
- **Language:** Python 3.10+
- **Key deps (runtime):** `toml` (TOML config parsing)
- **Key deps (dev):** `pytest`, `ruff`, `mypy`
- **HTTP:** stdlib `urllib` via `_http.py` (no requests/httpx runtime dep)
- **Build:** setuptools / uv
<!-- TODO: Fill in language, frameworks, and key dependencies -->
- **Language:**
- **Key deps:**
## Dev Commands
```bash
# Install (editable, with dev extras)
uv pip install -e ".[dev]"
# or
pip install -e ".[dev]"
# TODO: Fill in the standard commands for this repo
# Install dependencies
# Run tests
uv run pytest
# or
pytest
# Lint
uv run ruff check .
# Lint / type check
# Type check
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)
# Build / package (if applicable)
```

View File

@@ -5,6 +5,22 @@ ID prefix: `LLM-WP`
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 —
visible at session start. Pick one up by creating the workplan file, then registering
the workstream.

171
AGENTS.md
View File

@@ -1,11 +1,162 @@
# llm-connect — Codex Instructions
# llm-connect — Agent Instructions
@SCOPE.md
@.claude/rules/repo-identity.md
@.claude/rules/session-protocol.md
@.claude/rules/first-session.md
@.claude/rules/workplan-convention.md
@.claude/rules/stack-and-commands.md
@.claude/rules/architecture.md
@.claude/rules/repo-boundary.md
@.claude/rules/agents.md
## Repo Identity
**Purpose:** Multi-provider LLM client library — unified adapter interface for OpenAI, Claude, Gemini, OpenRouter with embedding support, token estimation, and TOML-based config.
**Domain:** custodian
**Repo slug:** llm-connect
**Topic ID:** `cee7bedf-2b48-46ef-8601-006474f2ad7a`
**Workplan prefix:** `LLM-WP-`
---
## 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/`)