Use List/Retrieve/Start/Stream/Cancel naming. Add new tags: Run Internals,
Human-in-the-Loop, Usage. Regenerate TypeScript client.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update logging strategy to explain that event enums have trace()
methods called automatically at emit sites, and that wrapper
variants are no-ops to prevent double-logging.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Defines structured logging conventions for the team: level guidelines
(INFO for production, DEBUG for on-demand investigation), structured
field patterns, and per-crate examples.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- AttractorError → ArcError across 30 source files
- .attractor/ → .arc/ for artifacts and skills paths
- ATTRACTOR_NODE_ID → ARC_NODE_ID env var
- attractor-rust → arc in Cargo.toml repository URLs
- attractor-spec.md → arc-spec.md with content updates
- Update server banner, test comments, README examples, and docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Aligns with the kilroy implementation of the Attractor spec. A default
of 50 retries is far too aggressive for most workflows.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rename the entire "tool" concept to "script": ToolHandler → ScriptHandler,
tool_command attribute → script, tool.output → script.output, and all
related artifact filenames. Add a language attribute (shell | python,
default shell) so script nodes can run Python via python3 -c natively.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Enrich three AgentEvent variants with payload data (UserInput.text,
TurnLimitReached.max_turns, SteeringInjected.text) and forward
UserInput/SteeringInjected to the pipeline event stream. Add cost
field to StageUsage (computed from model pricing catalog) and
total_cost to PipelineCompleted (summed from stage outcomes).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: adb2363c9ec4
The test criteria incorrectly said FAIL outcomes should be retried.
The pseudocode (Section 3.5) and the C reference implementation both
return immediately on FAIL. Only RETRY status triggers the retry loop.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Stores DOT source in ManagedPipeline and pipes it through `dot -Tsvg`
on request. Returns image/svg+xml on success, 502 if graphviz is
unavailable, 404 if pipeline not found. Resolves spec gap #1.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Closes the subgraph class derivation test gap by adding a parse() pipeline
test that verifies DOT subgraph labels produce correct CSS-like classes on
contained nodes. Updates gap analysis to remove resolved items, add spec
contradictions section, and narrow remaining gaps to SVG rendering and
retry predicate customization.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Gap 1: Real preamble synthesis per fidelity mode (truncate, compact,
summary:low/medium/high) in new preamble.rs module, replacing placeholder
- Gap 2: Pass thread_id to CodergenBackend.run() so backends can reuse
LLM sessions across nodes sharing the same thread
- Gap 7: Engine cancellation via AtomicBool token checked between nodes,
wired to server cancel endpoint, new Cancelled error variant
- Gap 8: RecordingInterviewer serialization (to_json/from_json, file I/O)
and new ReplayInterviewer for replaying recorded Q&A sessions
- Gap 12: Preset retry policies selectable from DOT via retry_policy attr
(none, standard, aggressive, linear, patient)
- Gap 15: Engine calls Interviewer.inform() at pipeline start, stage
start, and stage complete lifecycle points
37 new tests (450 unit + 49 integration, all passing).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds the attractor crate implementing all 11 sections of the attractor spec:
- DOT parser (lexer, grammar, semantic analysis) for strict DOT subset
- Pipeline execution engine with edge selection, goal gates, retry logic,
failure routing, checkpoint save/resume, and loop_restart
- 9 node handlers: start, exit, codergen, wait_human, conditional, parallel
(concurrent with join/error policies), fan_in (with LLM eval), tool, manager_loop
- State management: PipelineContext, Outcome, Artifact store, fidelity resolution
- Human-in-the-loop: Interviewer trait with auto_approve, callback, queue,
recording, and console implementations, plus timeout enforcement
- Validation: 14 built-in lint rules with custom rule registration API
- Model stylesheet with universal/shape/class/ID selectors and specificity
- Transforms: variable expansion, stylesheet application, preamble; plus
PipelineBuilder with register_transform and prepare_pipeline
- Condition expression language with =, !=, bare-key truthiness, && combinator
- Event system with all 16 event types emitted by engine and handlers
- Tool call hooks (pre/post) for CodergenHandler
- Run directory with manifest.json and per-node status.json
370 tests (354 unit + 16 integration) covering all spec sections.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Extract shared test infrastructure (MockExecutionEnvironment, TestProfile,
MockLlmProvider) replacing 11 duplicate mock implementations across tests
- Deduplicate tool execution logic between sequential and parallel paths
- Narrow ProviderProfile trait from 14 to 7 required methods via
ProfileCapabilities struct and default implementations
- Replace stringly-typed HashMap event data with typed EventData enum
- Extract shared assemble_system_prompt helper and register_subagent_tools
default method, eliminating copy-paste across all 3 profiles
- Replace fragile shell-based glob with glob crate, fix rg detection
- Add delete_file to ExecutionEnvironment, wire git context into env block
- Remove dead code (AgentError::Io, count_turns, trivial derived-trait tests)
- Use match-based lookups in truncation instead of per-call HashMap allocation
Net reduction: -1,401 lines across 20 files. All 180 tests pass.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add knowledge_cutoff() method to ProviderProfile trait so session can
populate EnvContext from the profile instead of leaving it empty
- Set subagent default max_turns to 50 per spec (was using session
factory default which could be 0/unlimited)
- Add corrected spec compliance review after manual verification found
the initial 5-agent review was largely false positives
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
resolve_model() was passing raw alias strings (e.g. "gpt5") directly to
APIs instead of resolving them to actual model IDs (e.g. "gpt-5.2").
Also rename gpt-5.2-mini to gpt-5-mini, which is the correct OpenAI
model ID.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Enforce stream_read timeout (30s default) in all 4 providers' streaming code
- Add with_timeout() builder method to all adapter constructors
- Fix ResponseFormatType::JsonObject to serialize as "json" per spec
- Add STEP_FINISH to StreamEventType enum in spec doc
- Add UnsupportedToolChoice error and enforce in all adapters via validate_tool_choice()
- Fix error classification to check status code before message content
- Add stop_sequences support to OpenAI Responses API adapter
- Handle Gemini thought parts (thought: true) in both complete and streaming paths
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Parse x-ratelimit-* headers into RateLimitInfo for Anthropic, OpenAI, and
OpenAI-compatible providers (previously hardcoded to None)
- Add "not found"/"does not exist" and "unauthorized"/"invalid key" error
message classification patterns for ambiguous HTTP status codes
- Apply TimeoutConfig.total to wrap the entire multi-step generate() loop
(previously only per_step was used)
- Add metadata field to GenerateParams with builder method, pass through to
Request instead of hardcoding None
- Implement stream_object() for streaming structured output with incremental
JSON parsing via new ObjectStreamEvent type (Partial/Delta/Complete variants)
- Add OpenAI-compatible Chat Completions adapter for third-party endpoints
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>