Skip to content

feat(agents): Agent Designer Phase 1 — contract + binding persistence (foundation)#591

Merged
philmerrell merged 2 commits into
developfrom
feature/agent-designer-phase1
Jul 8, 2026
Merged

feat(agents): Agent Designer Phase 1 — contract + binding persistence (foundation)#591
philmerrell merged 2 commits into
developfrom
feature/agent-designer-phase1

Conversation

@philmerrell

Copy link
Copy Markdown
Contributor

Agent Designer — Phase 1 (foundation, backend only)

First slice of the Agent Designer epic. Evolves the rag-assistants store in place (D2) into a primitive-agnostic Agent contract. Zero behavior change to existing clients — the SPA sends none of the new fields and AssistantResponse is unchanged. No new surface is exposed yet (the /agents/* router lands dark in the next PR).

Two commits, kept split for review:

PR-1 — Agent contract + compat mapping (pure library)

  • AgentModelConfig (D3 governed single-select; field is model_settings/alias modelConfig to dodge pydantic's reserved model_config) and AgentBinding (open kind on read, KNOWN_BINDING_KINDS for request validation)
  • optional model_settings + bindings on Assistant (additive)
  • compat.py (D2): absent bindings synthesize a knowledge_base binding reffing the assistant id (the KB's only stable identity — F4 deferred); absent model → None, never fabricated
  • Decimal-safe (de)serialization for modelConfig.params floats

PR-2 — Persist bindings + modelConfig with design-time validation

  • service create/update thread the new fields; to_ddb_safe/from_ddb so float params survive DynamoDB (Decimal)
  • app_api/agents/services/binding_validation.py composes existing RBAC (D4): model access (ModelAccessService), memory resolve_permission (viewer+/editor+), inert shape-only checks for tool/skill
  • assistants POST/PUT validate then pass through (4xx raised so it isn't masked as 500)

Design note — knowledge_base bindings

Refined from the spec sketch: knowledge_base is synthesized on read, rejected on write in Phase 1. The KB index (vector_index_id) is not user-configurable and the agent id doesn't exist at create time, so an author-settable KB binding is pointless/chicken-and-egg. Revisit when F4 (first-class KBs) lands.

Testing

71 tests pass, including all pre-existing assistant tests (no regression) and the architecture import-boundary gate. New: compat mapping (10), binding validation matrix incl. the inert no-RBAC guarantee (15), persistence round-trip (3).

Follow-ups (this epic)

  • PR-3: /agents/* alias router behind AGENTS_API_ENABLED (default off, deploys dark)
  • PR-4: dogfood — Oliver as a real Agent with a memory_space binding

🤖 Generated with Claude Code

philmerrell and others added 2 commits July 7, 2026 19:10
…dels

Phase 1 (PR-1) of the Agent Designer. Pure library, zero behavior change:
legacy Assistants read unchanged and no caller passes the new fields yet.

- AgentModelConfig (D3 governed single-select; field is model_settings/
  alias modelConfig to dodge pydantic's reserved model_config — R3)
- AgentBinding (open kind on read, KNOWN_BINDING_KINDS for request validation)
- optional model_settings + bindings on Assistant (additive)
- compat.effective_bindings/to_agent_view (D2): absent bindings synthesize a
  knowledge_base binding reffing the assistant id (KB's only stable identity,
  F4 deferred — R4); absent model maps to None, never fabricated (R1)
- Decimal-safe serialization for modelConfig.params floats

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Phase 1 (PR-2). The Agent fields now round-trip through the rag-assistants
store and are validated at write time by composing existing RBAC checks (D4).
Legacy clients are unaffected: the SPA sends none of the new fields and the
AssistantResponse surface is unchanged.

- service.create_assistant/update_assistant thread bindings + model_settings;
  to_ddb_safe on write / from_ddb on read so modelConfig.params floats survive
  DynamoDB (Decimal); explicit [] replaces bindings, absent leaves them untouched
- app_api/agents/services/binding_validation.py composes model access
  (ModelAccessService), memory resolve_permission (viewer+/editor+), the
  implicit-KB rejection, and inert shape-only checks for tool/skill (D4/D5)
- assistants POST/PUT validate then pass through; validation raises 4xx outside
  the create handler's generic except so it isn't masked as 500
- tests: validation matrix (incl. inert no-RBAC guarantee), persistence round
  trip, legacy no-field read

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@philmerrell philmerrell merged commit c2329f8 into develop Jul 8, 2026
4 checks passed
@philmerrell philmerrell deleted the feature/agent-designer-phase1 branch July 8, 2026 01:27
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