OpenProgram · Agents

Agent configuration implementation plan

Reusable configuration, optional long-term memory, consistent execution semantics.

中文
Target design · New runtime behavior is not implemented. Interactions change document examples only, never live configuration.

Delivery boundary and fixed choices

This plan implements the linked configuration contract. The current deliverable is documentation and a browser-testable editor prototype; it does not migrate real user data or modify runtime behavior. The first production release covers saved/inline configurations, atomic persistence, shared resolution, optional memory and the editor. Optional automatic selection has its own later stage; it is not a prerequisite for manual per-call model selection.

Stages, dependencies and public evidence

Stage / dependency Owned change Exit evidence
P0 · first Typed AgentConfig projection; schema 2 migration; whole-config revision/CAS; recoverable multi-file lifecycle writes A01/A02/A11: same-revision clients cannot both win; restart sees old or complete new config; migration semantic diff empty
P1 · P0 One pure resolver and read-only preview; canonical capability semantics; errors and provenance A03/A07: equivalent inputs resolve identically, selected empty stays empty, explicit denied call fails
P2 · P1 Per-execution memory policy, namespace binding, eligibility lineage and policy-epoch revalidation A05: reads, writes, delayed extraction, compaction and queued commits obey policy; optional outage visibly degrades
P3 · P1 + P2 Python agent()/llm(), chat, CLI, dispatch and scheduler adapters; immutable execution snapshot and history filtering A03/A04/A06/A08/A12: public entry parity; concurrent/failing/cancelled calls do not leak config; resumes retain intent
P4 · P0 + P1; finish after P2/P3 Eight-section UI, whole draft, registry model picker, capability selectors and effective preview A01/A02/A07/A10: real page actions, conflict recovery, unavailable references, responsive and keyboard acceptance
P5 · P0–P4 Portable import/export, duplicate/delete previews, compatibility preflight, product docs and release gate A09/A11/A12: owned resources only; legacy callable behavior preserved; final reviewed candidate fully verified
P6 · optional after P5 Explicit opt-in Agent/model selection policy over eligible candidates Routing tests below pass; manual paths unchanged when policy is absent

Schema and compatibility are implemented before consumers. UI layout work may use fixtures after P1, but a mock does not satisfy P4. Memory controls are not released before every P2 ingress/egress path is covered. Finish and review one bounded stage before treating dependent work as complete.

Source ownership and change locations

Area Existing boundary Planned responsibility
Persistence openprogram/agent/management/manager.py; openprogram/agent/management/workspace.py Keep AgentSpec and storage owner; new colocated configuration.py/resolution.py may separate typed values and pure logic; both filenames are proposed
API apps/server/openprogram_server/_webui/routes/catalog/agents.py Call one atomic manager operation; typed preview, revision and readiness responses; no route-local merge or second tools write
Function calls openprogram/agentic_programming/agent.py; openprogram/agentic_programming/llm.py; openprogram/agentic_programming/runtime/execution.py Normalize old/new arguments once; immutable scoped configuration; preserve return/validation, no Program/MCP tool loop, and explicit authorized native search
Durable dispatch openprogram/programs/tools/agents/agent/agent/agent.py; openprogram/agent/sub_agent_run.py Reuse dispatch and existing task lifecycle; persist snapshot/lineage through actual run and DAG stores
Memory openprogram/memory/backend.py; openprogram/memory/management/config.py Policy enforcement above backend; namespace and commit contracts within backend; trace every caller before signoff
UI apps/web/components/agents/agents-page.tsx Reuse components; typed draft and atomic save; extend existing API/type layer at its actual import path
Docs Configuration contract; Editor; Capabilities; Programs Update these canonical pages, both languages; product usage pages change only alongside real implementation

Before each implementation brief, locate actual chat/scheduler/CLI consumers and persistence schemas through the current call graph, and record their concrete file paths. The paths above are confirmed boundaries, not an invented exhaustive patch list. Do not perform unrelated frontend, provider or memory-engine refactors.

Migration, old clients and rollback

Failure-oriented acceptance scenarios

P3 also owns C1–C10 in collaboration §§6–7: preserve actual execution_id/job_id interfaces, connect completion follow-up and async archive, retain authorized output reads after message exhaustion, and unify history visibility, result limits and exact attach navigation. A helper definition or a test calling it directly is not public-entry completion evidence.

IDs Input / action Required assertion
A01/A03 Create name-only config; call agent and llm using saved versus equivalent inline fields No role requirement; no anonymous persistence; equivalent effective fields except identity/provenance; llm performs no Program/MCP loop; web_search=False emits no native search, while explicit authorized True preserves it
A02 Two processes PATCH model + tools from the same revision; inject failure before replace Exactly one 200, one 409; complete old/new file; next read never sees mixed fields; draft survives error
A04 Two nested parallel invocations with different model and memory; one cancelled during await Provider requests use their own resolved fields; finally restores the caller; cancellation propagates
A05 Put distinct sentinels in memory and off/read-only execution outputs; force recall, compaction and session-end writer No forbidden sentinel enters a request/store through disallowed paths; derived summaries retain write restrictions
A05/A08 Pause queued recall/write, revoke access, then release queue and restart worker Late recall discarded; write denied at commit; retry/recovery cannot broaden grant
A06 Switch saved Agent with clean, inherit and selected history; request inaccessible node Only authorized chosen context is visible; no implicit transfer; inaccessible node fails before inference
A07 selected=[]; denied explicit tool; missing required MCP; llm native search both with/without Agent selection Discovery and invocation agree; no provider/tool side effect before preflight succeeds
A08/A12 Queue a run, edit Agent, resume; then fire next scheduled execution Resumed run uses pinned config plus current revocations; new firing resolves latest revision
A09 Duplicate/export/import/delete with self and shared memory, active run and external cwd No copied memory/history/credentials/schedules; shared and external resources remain; active deletion rejected
A10 Operate all editor sections at desktop/mobile with keyboard; two-client save conflict No draft loss, fake success, overflow or unreachable tabs; conflict details offer reload or explicit reapplication
A11 Migrate legacy fixtures including global-memory inheritance, empty allows, simultaneous names/categories, uncategorized items and default Agent Before/after effective model, capabilities, memory and default selection match; rerun is a no-op

First bounded implementation brief: P0

Implement the saved configuration format and atomic update boundary first. Touch Agent management types/storage, Agent routes, their existing tests and the relevant bilingual product/design documentation. Introduce the minimum value/schema module if separating it keeps the manager readable. Do not modify function execution, memory behavior, UI layout or installed App in this brief.

Public RED: submit concurrent same-precondition PATCH requests changing model and tools, then read the saved Agent. The current route-level check and split writes do not establish the required whole-record transaction; the test must demonstrate a reproducible lost-update/mixed-write gap, not merely inspect method names. Extend tests/component/webui/abilities/test_agent_tools_routes.py for the public concurrency/lifecycle cases; place pure migration fixtures alongside the existing agent-management tests after checking their current location. The focused command is uv run --locked --extra dev python -m pytest -q tests/component/webui/abilities/test_agent_tools_routes.py. Add migration fixtures proving the intended legacy semantics before changing serialization.

GREEN: one validated manager transaction compares revision under a cross-process writer lock and atomically replaces the complete canonical file; routes cannot save tools separately. Keep read compatibility, explicit typed errors and timestamp-adapter behavior. Record the actual public-entry command, failure/pass evidence, changed files and commit in the implementation ledger. Run independent specification review, then fresh quality review. P0 remains incomplete until both pass; no runtime feature can be marked implemented from this plan alone.

Verification and release evidence

Choose focused RED/GREEN tests from the current suite at each brief; extend existing ownership before inventing a new test hierarchy. Confirmed related tests include tests/component/webui/abilities/test_agent_tools_routes.py, tests/unit/agent/workflows/test_agentic_programming_agent.py, tests/component/agent/workflows/test_goal_role_configuration.py, tests/component/webui/settings/test_memory_settings_routes.py, tests/unit/memory/test_memory_runtime_config.py and tests/unit/config/test_docs_information_architecture.py. These are starting points, not evidence that the target scenarios already exist.

# Documentation-only deliverable: run from the design checkout.
uv run --locked --with markdown-it-py --with mdit-py-plugins --with pygments python -m scripts.docs_site.build
uv run --locked --with markdown-it-py --with mdit-py-plugins --with pygments python -m scripts.docs_site.checklinks
uv run --locked --with markdown-it-py --with mdit-py-plugins --with pygments python -m scripts.docs_site.checklang
uv run --locked --with markdown-it-py --with mdit-py-plugins --with pygments python -m scripts.docs_site.check_landing
uv run --locked --extra dev --with markdown-it-py --with mdit-py-plugins --with pygments python -m pytest -q tests/unit/config/test_docs_information_architecture.py

# Runtime implementation: focused checks first, final candidate full layers.
uv run --locked --extra dev python -m pytest -q tests/contracts tests/unit tests/component tests/integration
# Web commands execute in apps/web after its documented dependency setup.
cd apps/web
npm test
npx tsc --noEmit
npm run check
npm run build
cd ../..
uv run --locked --extra dev --extra browser python -m pytest -q -m browser tests/e2e/web

Reconcile these commands with tests/README.md and CONTRIBUTING at implementation time; record any additional prescribed full gates. Browser artifacts must exercise the built production page. Final App acceptance uses /Applications/OpenProgram.app, default profile, port 18100 and ~/.openprogram. After the complete implemented feature is committed, refresh once with scripts/refresh-local-app.sh from the final checkout; do not restart from an old worktree or start a second development profile.

Keep source, tests, local commit, remote push, installed App and live deployment as separate evidence fields. A documentation build does not satisfy runtime or App acceptance. This planning task does not commit, push, migrate, restart or release the application.

Optional selection policy: complete extension boundary

P6 is opt-in and runs before the existing resolver. A caller supplies an existing policy reference instead of agent_id/config; they are mutually exclusive. Policy candidates are saved Agent IDs or provider-qualified model references, never arbitrary generated executable configuration. Model-only selection retains the caller’s non-model fields; Agent selection changes the base and uses the normal history rules. The policy must declare which kind it selects, so a model choice cannot silently change memory or instructions.

Decision Contract
Eligibility Filter unavailable provider/account/model, required modality or structured output/tool support, context limit, authority and remaining resource cap before ranking
Ranking Versioned ordered deterministic rules over explicit task tags, required capabilities and caller preferences; model-assisted ranking is a separately enabled later mode
No match / unavailable Return a typed no-eligible-candidate error, or use an explicitly configured eligible fallback before inference starts; never broaden authority
Trace Record policy version, eligible candidate IDs, exclusions, chosen ID and rule identifier; avoid raw user content and unsupported cost/latency claims
Stability Pin selection for retries/resume; new invocation may select again. Never switch an already active tool loop automatically
Evaluation Fixed fixture cases for routing correctness, no-match, denied candidate, unknown price metadata and deterministic replay; report measured quality/cost/latency on an approved corpus before claims

For one Agent-kind policy, all results are saved Agent IDs: task tag=classify and structured-output capability required → the first eligible saved Agent configured with a selected small model; task tag=code-edit and tools required → a selected saved coding Agent; otherwise → a specified saved default Agent. A separate model-kind policy returns only model references and retains non-model fields. Candidate IDs and thresholds are user-configured from the available catalog, not hardcoded product rankings. Missing price/latency metadata means unknown, not free or fast.

Known integration risks and resolved limits

Risk Required treatment
Memory content indirectly appears in derived history Propagate write restrictions through context dependencies and generated summaries; test cross-Agent transfer, not just original node ingestion
A plugin cannot enforce namespace isolation Expose unsupported readiness; block requested scoped binding, do not claim prompt-only isolation
Concurrent files/default index lifecycle Journal with recovery and idempotence; mutation authority remains in one manager
Old clients overwrite newly typed fields Dual-reader/conditional-write compatibility and explicit errors; no silent downgrade
Configuration snapshots contain personal instructions Protect with existing execution storage ACLs/retention; diagnostics show hashes/references, not prompt text
Expanding UI before runtime supports fields Feature readiness follows verified backend support; prototype status remains explicit

There is no unresolved product decision required to begin P0. Exact consumer file paths and backend-specific revocation support are implementation discovery items with the fail-closed behavior specified above. A backend that cannot meet it stays unsupported; implementation convenience does not silently weaken the contract.

Implementation status

Stage Design Implementation / acceptance
P0 Specified Revision/CAS and compatible reads implemented; schema 2 migration and transactional lifecycle remain planned
P1 Specified Existing runtime resolution and capability policies reused; unified resolver and effective preview remain planned
P2 Specified Execution, background extraction, derived eligibility and recovery policy implemented for self and legacy_global
P3 Specified Saved Web configurations and trial snapshots implemented; full Python/CLI/scheduler entry parity remains planned
P4 Specified Eight sections, shared drafts, model selection and conflict comparison implemented; embedded trial and effective preview remain planned
P5 Specified Configuration duplication/deletion and product docs implemented; portable import/export remains planned, delivery verification recorded separately
P6 (optional) Specified Not implemented

The design document checks and prototype inspection are recorded in the delivery message. They are distinct from the runtime stage evidence listed here. Update this appendix as reviewed implementation lands; keep execution dates and commit history in Git and the implementation ledger, not as appended revisions of this design.