41c406e1ab
Fable 5 pass: 40 turns, $13.56, 109k output tokens. ## A2A v1.0 upgrade - SCREAMING_SNAKE task states (TASK_STATE_COMPLETED etc) - ROLE_USER/ROLE_AGENT message roles - Unified Parts (no kind field, member-presence discrimination) - Agent Card: supportedInterfaces[], provider, capabilities.extendedAgentCard - SSE: member-discriminated statusUpdate/artifactUpdate, closure=terminal - contextId inside Message (not top-level params) - ISO 8601 millisecond timestamps, createdAt/lastModified on Task - New operations: tasks/list, tasks/subscribe - input-required state reachable via [INPUT_REQUIRED] hint ## Security & correctness (all must-fix from review) - Slash-command bypass removed — remote peers can't invoke operator commands - Per-peer token auth (A2A_PEER_TOKENS) replaces self-asserted params.peer - _pending_replies keyed by task_id with per-context FIFO (no cross-talk) - Timeout returns TASK_STATE_FAILED, not completed - reset_turns uses task's context from store (was silent no-op) - Error codes: spec codes only for spec semantics, custom -32050..-32052 - Real latency metric (was fake 0.0) ## Dead features wired - Push notifications: inline configuration.taskPushNotificationConfig in message/send + tasks/pushNotificationConfig/create. HMAC-signed e2e. - Dynamic Agent Cards: skills from live tools.registry, A2A_ADVERTISED_TOOLSETS - Persistence: new a2a_history(context_id) tool recalls conversations - Dead helpers cut: rate_limit_status, is_open_mode, verify_push_signature, turn_count, check_bearer ## Architecture - TurnTracker/RateLimiter/TaskStore on adapter instance (was module-global) - Handler class at module level (was untestable closure) - on_processing_complete for failure/cancel paths - SSE hang fix: keepalive header no longer prevents socket closure ## a2a_orchestrate kept per user instruction - best mode: only successful replies considered (long error can't win) - all-error case: explicit 'All peers failed' listing - Client paths deduped into _send_task helper ## Tests - inspect.getsource() tests replaced with behavioral coverage - 133 total: 118 unit + 15 integration - v1.0 spec compliance, peer-token auth, FIFO replies, timeout→FAILED, tasks/get-after-complete, streaming SSE parse, subscribe replay, anti-loop rejection, 429s, push e2e, input-required e2e, orchestrate ## Docs - DESIGN.md out-of-scope synced with reality - README and plugin.yaml updated Still TODO (in DESIGN.md): file/data Parts, push-config get/list/delete, tenant, gRPC/HTTP+JSON bindings, true mid-turn task abort.