PR #1 · pramaan-io/pramaan-agents · merged 2026-05-21
sequenceDiagram autonumber participant sqs as SQS participant rt as Runtime participant store as Store participant ws as WebSocket sqs->>rt: SQS event rt->>rt: validate payload rt->>store: start run store-->>rt: run id rt->>ws: stream tokens rt->>store: append turn rt->>store: complete / fail
| Method | in → out | what it does |
|---|---|---|
AgentRunStore | (class) | |
start_run | (request, model_id) → UUID | |
store_body | (content, firm_id, run_id, kind, threshold_bytes) → StoredBody |
Agent run storage layer: RLS-aware, S3 offload for large bodies, RDS IAM auth, plus an in-memory variant for tests.
| new class | signature |
|---|---|
AgentRunStore | (class) |
start_run | (request, model_id) → UUID |
store_body | (content, firm_id, run_id, kind, threshold_bytes) → StoredBody |
_fallback_s3_offload | (content, firm_id, run_id, kind, sha256, size_bytes) → tuple[str, str, str, int] |
InMemoryAgentRunStore | (class) |
load_history | (chat_session_id, limit) → Sequence[ChatMessage] |
append_assistant_turn | (request, run_id, content) → None |
complete_run | (run_id) → None |
fail_run | (run_id, error) → None |
SqlAlchemyAgentRunStore | (class) |
_set_rls | (conn, request) → None |
_next_turn_index | (conn, chat_session_id) → int |
_ids | (request) → dict[str, str] |
_build_database_url | (url_factory) → Any |
_rds_iam_token | (host, port, username, region) → str |
preview : strs3_key : str | Nonesize_bytes : intsha256 : strWebSocket sender interface and a TokenStreamer that batches chunks under a rate cap.
| new class | signature |
|---|---|
ConnectionGoneError | (class) |
WebSocketSender | (class) |
post | (connection_id, payload) → None |
TokenStreamer | (sender, connection_id, run_id, max_posts_per_second, _disconnected, _buffer) |
emit | (content) → None |
flush | () → None |
done | () → None |
Strictly typed request shape with explicit validation for required fields and UUIDs.
| new class | signature |
|---|---|
PayloadValidationError | (class) |
AgentRunRequest | (connection_id, firm_id, matter_id, user_id, chat_session_id, message, request_id) |
from_mapping | (payload) → AgentRunRequest |
_non_empty_string | (value, field) → str |
_uuid | (value, field) → UUID |
Wraps the Strands agent behind one run method, with a stub path for tests.
| new class | signature |
|---|---|
ChatMessage | (role, content, StrandsHarness) |
run | (request, history, token_streamer) → str |
_run_stub | (token_streamer) → str |
_run_strands | (token_streamer) → str |
Composes the runtime container; supplies a no-op websocket sender for non-streamed runs.
| new class | signature |
|---|---|
NullWebSocketSender | (class) |
post | (connection_id, payload) → None |
build_agent_runtime | () → AgentRuntime |
SQS event handler rewritten to delegate to the new runtime and return a structured response.
| new method | signature |
|---|---|
handle_event | (event, runtime) → dict[str, Any] |
Tool call lifecycle hooks — a recorder and a no-op placeholder; guardrails land in Story-756.
| new class | signature |
|---|---|
ToolCallStart | (run_id, tool_name, input_json, ToolCallFinish, tool_call_id, output_json, duration_ms, error_message) |
ToolCallRecorder | (class) |
before_tool_call | (event, event) → None: ... class NoopToolCallRecorder: """Placeholder hook implementation until Story-756 adds real guardrails.""" def before_t |
after_tool_call | (event) → None |
AgentRuntime container holding the store, harness, websocket sender, and tool call recorder.
| new class | signature |
|---|---|
AgentRuntime | (store, harness, websocket_sender, tool_call_recorder) |