Skip to content

feat(api): rebase JP's session turns/streams backend onto v0.105.5#5375

Open
mmabrouk wants to merge 3 commits into
mainfrom
sessions-rebase/backend
Open

feat(api): rebase JP's session turns/streams backend onto v0.105.5#5375
mmabrouk wants to merge 3 commits into
mainfrom
sessions-rebase/backend

Conversation

@mmabrouk

@mmabrouk mmabrouk commented Jul 18, 2026

Copy link
Copy Markdown
Member

What this is

JP's sessions work (PR #5363, feat/sessions-extensions) predated v0.105.4, v0.105.5, and the runner decomposition (#5369). This is the backend two-thirds of that work rebased onto current main (v0.105.5), on a new branch I own so JP's branch is untouched.

Its parent, big-agents-add-sessions, is already merged into main, so this PR carries only the feat/sessions-extensions delta: the API, the Python SDK, the Fern Python client, and the web generated client.

What it changes

  • Replaces the session_states read-modify-write model with an append-only session_turns domain (new migrations 014017, tracing 003004; the old session_states module and its DTOs/DAO/tests are removed).
  • Renames the stream command discriminator promptinputs/data.
  • Adds the root /sessions router and SessionsService, session-scoped hard-delete/unarchive plumbing, and the API side of /kill teardown.
  • Adds span identity columns plus ag.agent.id, and mounts.agent_id.

Ported from feat/sessions-extensions@1532ec7fe5 (JP); attribution is in the commit.

Reconciliations with the release

Three places where JP's change met a v0.105.x fix. Both behaviors are kept:

  1. sdks/python/agenta/sdk/agents/adapters/harnesses.py — JP renamed HarnessTypeHarnessKind across the SDK. Main (pi-openai, feat(agents): OpenAI-compatible endpoints for Pi via vault custom connections #5345) added model_ref threading in PiHarness and AgentaHarness. Kept both: the rename plus the two model_ref=config.agent.model_ref lines.
  2. sdks/python/agenta/sdk/agents/__init__.py — kept JP's HarnessKind rename and main's new EndpointResolutionError export.
  3. api/pyproject.toml — kept main's 0.105.5 version and re-added JP's greenlet dependency; api/uv.lock updated for greenlet only (surgical, not a full re-resolve). Kept main's sdks/python and services uv.lock (JP's were stale transitive bumps).

Testing

  • SDK agent unit tests green: test_harness_adapters.py + test_agent_composition_seam.py — 38 passed (validates the HarnessKind + model_ref merge); test_wire_contract.py — 34 passed.
  • Full sdks/python/oss/tests/pytest/unit/agents/ is 669/670. The one failure (test_bare_claude_alias_resolves_to_anthropic) is not from this branch: it comes from the separately-applied fix/claude-fable-model-id lane editing claude_models.curated.json in the shared dev worktree. This branch keeps main's catalog verbatim, so on a clean main base the test passes.

For JP

This is a mechanical rebase of your #5363 onto v0.105.5, on a branch I own (sessions-rebase/backend). Please review the three reconciliations and adopt or retarget as you see fit — I did not touch your branches.

https://claude.ai/code/session_01DnWRxU3dCJ11hgDidm26vW


QA finding fixed: record-ingest 422 (span_id typed as UUID)

QA of this branch on the EE dev stack found session records never persisted: every runner→API POST /sessions/records/ingest returned HTTP 422 and dropped after retries (debug/qa-sessions-rebase/FINDING-record-ingest-422.md). Root cause: span_id is an OpenTelemetry span id (64-bit / 16 hex chars) but was typed Optional[UUID] (128-bit / 32 hex), so pydantic rejected every real ingest. trace_id (32 hex) fits UUID and masked it.

Fix (commit 9e2044c898): model span_id as what it is — a validated 16-hex string (OTelSpanId in core/shared/dtos.py) — across the API model, core DTOs, and the DAO column, and varchar in the two unreleased migrations (core_oss/014, tracing_oss/004, edited in place). trace_id stays UUID (genuinely the 32-hex OTel trace id: run.traceId() = spanContext().traceId). New/updated tests: a model-level 16-hex-accept / UUID-reject contract, an acceptance ingest-contract test, an archive/unarchive route test, a multi-turn turns-persist assertion, a mounts.agent_id backfill migration test; existing DAO/mapping tests moved to the 16-hex shape.

Live re-verify (EE dev): after altering the two live span_id columns to varchar to match the corrected migration, the runner-shaped body (16-hex span_id) returns 200 and the record persists with span_id intact; a UUID span_id still returns 422; a real agent run's records ingested at 200 with no uuid_parsing in the api log. Evidence under debug/qa-sessions-rebase/fix-verify/.

Pre-existing, unrelated finding (not fixed here): apply_windowing treats session_turns.span_id as the uuid7 cursor, so test_query_turns_windowed_newest_to_oldest orders by an all-NULL span_id and returns the wrong order. It is triggered by the column merely existing (type-independent), so it predates this fix. Flagged for a follow-up.

Follow-up review fix (committed to this lane): made ix_session_turns_project_id_session_id_turn_index a UNIQUE index in core_oss/014 and mirrored unique=True on the matching Index in the turns DBE, so (project_id, session_id, turn_index) can no longer hold duplicate turn rows. Migration is unreleased (edited in place); the dev DB had duplicate QA rows deduped before the unique index was built live (fresh deploys need no manual step). Sessions suites: pure-unit 120 green; full suite 140 green with the one pre-existing windowing failure above.

Web build unblocked — stale prompt argument removed (this lane): the web image build failed to compile with src/session/api/api.ts(296,37): error TS2353: 'prompt' does not exist in type 'SessionStreamCommandRequest'. The rebased wire contract dropped the prompt field from SessionStreamCommandRequest (it now carries data?: WorkflowRequestData), but commandSessionStream still passed the old prompt. That function is dead on the product path today (zero callers outside its own module; its own doc comment notes steer/send is not wired into chat yet), so I removed the stale prompt parameter and request field to make it compile against the new type — no behavior change. I deliberately did NOT invent a prompt→data/inputs mapping; a one-line comment marks that the real mapping is yours to define (JP) when the send path is actually wired.

The turns DAO now maps duplicate-key IntegrityError to EntityCreationConflict (HTTP 409); see #5376's description for the full context of the turn-counter amendment.

@vercel

vercel Bot commented Jul 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Ready Ready Preview, Comment Jul 19, 2026 6:19pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added session turns APIs for appending, querying, and retrieving turn history.
    • Added session-level query, archive, unarchive, and delete operations.
    • Added session stream name and description editing.
    • Added agent ID filtering for mounts.
    • Added turn and span links to session records and tracing data.
    • Added direct runner sandbox teardown during session termination.
  • Breaking Changes
    • Removed session state APIs and replaced them with turn-based session management.
    • Updated session command payloads to use structured workflow data instead of prompts.
  • Bug Fixes
    • Improved heartbeat reporting for interrupted or superseded turns.

Walkthrough

This PR replaces session-state APIs with session turns and root session lifecycle operations, adds stream headers and runner teardown, propagates agent and tracing identifiers, extends mount filtering, updates Python clients and SDK harness types, and removes web session-state exports.

Changes

Session platform migration

Layer / File(s) Summary
Session turns and persistence
api/oss/src/core/sessions/turns/*, api/oss/src/dbs/postgres/sessions/turns/*, api/oss/databases/postgres/migrations/*
Adds session-turn DTOs, DAO/service methods, PostgreSQL storage, reference querying, windowing, latest-turn lookup, and migration support.
Root session and stream APIs
api/oss/src/core/sessions/*, api/oss/src/apis/fastapi/sessions/*, api/entrypoints/routers.py
Adds turn endpoints, session query/delete/archive/unarchive routes, stream header operations, updated routing, and root session orchestration.
Mount and tracing metadata
api/oss/src/core/mounts/*, api/oss/src/core/tracing/*, api/oss/src/dbs/postgres/mounts/*, api/oss/src/dbs/postgres/tracing/*
Adds canonical agent identifiers, agent-mount filtering and teardown, root-span identity promotion, tracing fields, and query support.
Client and SDK contracts
clients/python/agenta_client/*, sdks/python/agenta/sdk/*
Replaces session-state client methods with turn and lifecycle methods, adds stream-header and record-linkage fields, renames response models, and replaces HarnessType with HarnessKind.
Runtime and web integration
hosting/*, docs/*, web/*, api/pyproject.toml
Wires runner URL/token settings, documents runner configuration, adds the runtime dependency, and switches web session inspection and exports from state to streams.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 29.03% which is insufficient. The required threshold is 60.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: rebasing the sessions turns/streams backend onto v0.105.5.
Description check ✅ Passed The description is detailed and clearly matches the backend rebase, schema changes, SDK updates, and fixes described in the diff.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sessions-rebase/backend

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 19

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
api/oss/tests/pytest/unit/sessions/test_records_mapping_upsert.py (1)

127-135: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Assert turn_id and span_id are in the conflict update set.

Both names already occur in the INSERT column list, so these assertions pass even if they are removed from DO UPDATE SET.

Proposed assertion
 compiled = str(captured["stmt"]).lower()
+update_clause = compiled.split("do update set", 1)[1]
 ...
-assert "turn_id" in compiled
-assert "span_id" in compiled
+assert "turn_id = excluded.turn_id" in update_clause
+assert "span_id = excluded.span_id" in update_clause
api/oss/src/core/sessions/streams/service.py (1)

301-336: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Treat a different durable turn as stale and never reacquire interrupted locks.

After steer, an old heartbeat sees a different prior_stream.turn_id, leaves is_current_turn=True, and failed acquire_* calls do not correct it. After cancel, the code reports False but recreates the deleted locks. Return stale immediately for a different turn and only acquire locks during genuine first establishment.

🧹 Nitpick comments (3)
web/oss/src/components/SessionInspector/api.ts (1)

41-45: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Deduplicate identical functions.

With these changes, fetchState is now functionally identical to fetchStream (lines 28-34). Consider refactoring fetchState to call fetchStream directly to avoid code duplication, or remove fetchState entirely if the callers can be safely updated.

♻️ Proposed refactor
 export async function fetchState(sessionId: string, projectId?: string | null) {
-    const res = await client().sessions.fetchSessionStream(
-        {session_id: sessionId},
-        scope(projectId),
-    )
-    return res.stream ?? null
+    return fetchStream(sessionId, projectId)
 }
api/oss/tests/pytest/unit/mounts/test_agent_id_backfill.py (1)

24-29: 🗄️ Data Integrity & Integration | 🔵 Trivial | 🏗️ Heavy lift

Exercise the actual backfill SQL instead of a duplicated parser.

This helper can remain correct while the migration’s substr offset or prefix condition drifts. Extract the SQL expression into an importable migration constant or add a Postgres migration test that executes it against representative slugs.

api/oss/src/dbs/postgres/tracing/dbes.py (1)

43-47: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Consider adding missing indexes for user_id and agent_id.

The table configuration introduces an index for session_id, and a code comment in api/oss/src/dbs/postgres/tracing/dao.py mentions that user_id is also an indexed root-only column. However, user_id and agent_id are missing their corresponding composite indexes here. To ensure optimal query performance when filtering by these newly added fields, consider adding them to the table arguments.

⚡ Proposed indices
         Index(
             "ix_spans_project_id_session_id",
             "project_id",
             "session_id",
         ),  # for session filtering (root-only column)
+        Index(
+            "ix_spans_project_id_user_id",
+            "project_id",
+            "user_id",
+        ),
+        Index(
+            "ix_spans_project_id_agent_id",
+            "project_id",
+            "agent_id",
+        ),

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a05e1504-f63e-4440-9fec-8520dcf3cff6

📥 Commits

Reviewing files that changed from the base of the PR and between 3b0c0cb and 386c63e.

⛔ Files ignored due to path filters (51)
  • api/uv.lock is excluded by !**/*.lock
  • web/packages/agenta-api-client/src/generated/api/resources/mounts/client/Client.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/mounts/client/requests/MountQueryRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/Client.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/ArchiveSessionRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/DeleteSessionRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/FetchTurnRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionDetachRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionHeartbeatRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionQueryRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionRecordIngestRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionStreamCommandRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionStreamQueryRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionTurnAppendRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionTurnQueryRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SetSessionStreamHeaderRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/UnarchiveSessionRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/index.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/CommandMode.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/HarnessKind.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/HarnessSessionRecord.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/Mount.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/MountCreate.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/MountQuery.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionHeartbeatResponseModel.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionHeartbeatResult.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionInteraction.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionMount.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionMountQuery.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionRecord.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionState.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStateData.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStateFlags.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStateUpsertRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStream.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStreamCommandResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStreamHeaderEdit.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStreamResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStreamsResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionTurn.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionTurnQuery.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionTurnResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionTurnsResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionsResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SpanInput.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SpanOutput.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SpansNodeInput.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SpansNodeOutput.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/WorkflowRequestData.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/index.ts is excluded by !**/generated/**
📒 Files selected for processing (170)
  • api/entrypoints/routers.py
  • api/oss/databases/postgres/migrations/core/env.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000014_add_session_turns.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000015_add_session_streams_header.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000016_add_mounts_agent_id.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000017_drop_session_states.py
  • api/oss/databases/postgres/migrations/tracing_oss/versions/oss000000003_add_span_identity_columns.py
  • api/oss/databases/postgres/migrations/tracing_oss/versions/oss000000004_add_records_turn_span.py
  • api/oss/src/apis/fastapi/mounts/router.py
  • api/oss/src/apis/fastapi/mounts/utils.py
  • api/oss/src/apis/fastapi/otlp/extractors/adapters/logfire_adapter.py
  • api/oss/src/apis/fastapi/otlp/extractors/canonical_attributes.py
  • api/oss/src/apis/fastapi/otlp/extractors/span_data_builders.py
  • api/oss/src/apis/fastapi/otlp/utils/serialization.py
  • api/oss/src/apis/fastapi/sessions/models.py
  • api/oss/src/apis/fastapi/sessions/router.py
  • api/oss/src/apis/fastapi/tracing/router.py
  • api/oss/src/core/mounts/dtos.py
  • api/oss/src/core/mounts/interfaces.py
  • api/oss/src/core/mounts/service.py
  • api/oss/src/core/sessions/dtos.py
  • api/oss/src/core/sessions/interactions/dtos.py
  • api/oss/src/core/sessions/interactions/interfaces.py
  • api/oss/src/core/sessions/interactions/service.py
  • api/oss/src/core/sessions/records/dtos.py
  • api/oss/src/core/sessions/service.py
  • api/oss/src/core/sessions/states/dtos.py
  • api/oss/src/core/sessions/states/interfaces.py
  • api/oss/src/core/sessions/states/service.py
  • api/oss/src/core/sessions/streams/dtos.py
  • api/oss/src/core/sessions/streams/interfaces.py
  • api/oss/src/core/sessions/streams/runner_client.py
  • api/oss/src/core/sessions/streams/service.py
  • api/oss/src/core/sessions/turns/__init__.py
  • api/oss/src/core/sessions/turns/dtos.py
  • api/oss/src/core/sessions/turns/interfaces.py
  • api/oss/src/core/sessions/turns/service.py
  • api/oss/src/core/sessions/turns/types.py
  • api/oss/src/core/tracing/dtos.py
  • api/oss/src/core/tracing/service.py
  • api/oss/src/core/tracing/utils/filtering.py
  • api/oss/src/core/tracing/utils/trees.py
  • api/oss/src/dbs/postgres/mounts/dao.py
  • api/oss/src/dbs/postgres/mounts/dbas.py
  • api/oss/src/dbs/postgres/mounts/dbes.py
  • api/oss/src/dbs/postgres/mounts/mappings.py
  • api/oss/src/dbs/postgres/sessions/interactions/dao.py
  • api/oss/src/dbs/postgres/sessions/records/dao.py
  • api/oss/src/dbs/postgres/sessions/records/dbas.py
  • api/oss/src/dbs/postgres/sessions/records/dbes.py
  • api/oss/src/dbs/postgres/sessions/records/mappings.py
  • api/oss/src/dbs/postgres/sessions/states/dao.py
  • api/oss/src/dbs/postgres/sessions/states/dbes.py
  • api/oss/src/dbs/postgres/sessions/states/mappings.py
  • api/oss/src/dbs/postgres/sessions/streams/dao.py
  • api/oss/src/dbs/postgres/sessions/streams/dbes.py
  • api/oss/src/dbs/postgres/sessions/streams/mappings.py
  • api/oss/src/dbs/postgres/sessions/turns/__init__.py
  • api/oss/src/dbs/postgres/sessions/turns/dao.py
  • api/oss/src/dbs/postgres/sessions/turns/dbas.py
  • api/oss/src/dbs/postgres/sessions/turns/dbes.py
  • api/oss/src/dbs/postgres/sessions/turns/mappings.py
  • api/oss/src/dbs/postgres/sessions/turns/utils.py
  • api/oss/src/dbs/postgres/tracing/dao.py
  • api/oss/src/dbs/postgres/tracing/dbas.py
  • api/oss/src/dbs/postgres/tracing/dbes.py
  • api/oss/src/dbs/postgres/tracing/mappings.py
  • api/oss/src/dbs/postgres/tracing/utils.py
  • api/oss/src/utils/env.py
  • api/oss/tests/pytest/acceptance/session_states/test_harness_sessions_roundtrip.py
  • api/oss/tests/pytest/acceptance/session_states/test_session_states_basics.py
  • api/oss/tests/pytest/acceptance/sessions/__init__.py
  • api/oss/tests/pytest/acceptance/sessions/test_stream_header_basics.py
  • api/oss/tests/pytest/acceptance/sessions/test_stream_header_roundtrip.py
  • api/oss/tests/pytest/unit/mounts/test_agent_id_backfill.py
  • api/oss/tests/pytest/unit/mounts/test_agent_mounts.py
  • api/oss/tests/pytest/unit/otlp/test_logfire_adapter.py
  • api/oss/tests/pytest/unit/session_states/__init__.py
  • api/oss/tests/pytest/unit/session_states/test_harness_sessions_mapping.py
  • api/oss/tests/pytest/unit/session_states/test_session_id_validation.py
  • api/oss/tests/pytest/unit/sessions/conftest.py
  • api/oss/tests/pytest/unit/sessions/test_command_matrix_inputs_data.py
  • api/oss/tests/pytest/unit/sessions/test_heartbeat_is_current_turn.py
  • api/oss/tests/pytest/unit/sessions/test_kill_runner_teardown.py
  • api/oss/tests/pytest/unit/sessions/test_record_ingest_endpoint.py
  • api/oss/tests/pytest/unit/sessions/test_records_mapping_upsert.py
  • api/oss/tests/pytest/unit/sessions/test_records_turn_span_dao.py
  • api/oss/tests/pytest/unit/sessions/test_runner_client_kill.py
  • api/oss/tests/pytest/unit/sessions/test_sessions_root_service.py
  • api/oss/tests/pytest/unit/sessions/test_stream_header_merge.py
  • api/oss/tests/pytest/unit/sessions/test_turns_dao.py
  • api/oss/tests/pytest/unit/sessions/test_wp5_dao_fanout.py
  • api/oss/tests/pytest/unit/sessions/test_wp5_mount_teardown.py
  • api/oss/tests/pytest/unit/sessions/test_wp5_root_router.py
  • api/oss/tests/pytest/unit/tracing/test_dao_ingest_identity_columns.py
  • api/oss/tests/pytest/unit/tracing/utils/test_trees.py
  • api/pyproject.toml
  • clients/python/agenta_client/__init__.py
  • clients/python/agenta_client/mounts/client.py
  • clients/python/agenta_client/mounts/raw_client.py
  • clients/python/agenta_client/sessions/client.py
  • clients/python/agenta_client/sessions/raw_client.py
  • clients/python/agenta_client/types/__init__.py
  • clients/python/agenta_client/types/harness_kind.py
  • clients/python/agenta_client/types/harness_session_record.py
  • clients/python/agenta_client/types/mount.py
  • clients/python/agenta_client/types/mount_create.py
  • clients/python/agenta_client/types/mount_query.py
  • clients/python/agenta_client/types/session_heartbeat_result.py
  • clients/python/agenta_client/types/session_interaction.py
  • clients/python/agenta_client/types/session_mount.py
  • clients/python/agenta_client/types/session_mount_query.py
  • clients/python/agenta_client/types/session_record.py
  • clients/python/agenta_client/types/session_response.py
  • clients/python/agenta_client/types/session_state.py
  • clients/python/agenta_client/types/session_state_data.py
  • clients/python/agenta_client/types/session_state_upsert_request.py
  • clients/python/agenta_client/types/session_stream.py
  • clients/python/agenta_client/types/session_stream_command_response.py
  • clients/python/agenta_client/types/session_stream_header_edit.py
  • clients/python/agenta_client/types/session_stream_response.py
  • clients/python/agenta_client/types/session_streams_response.py
  • clients/python/agenta_client/types/session_turn.py
  • clients/python/agenta_client/types/session_turn_query.py
  • clients/python/agenta_client/types/session_turn_response.py
  • clients/python/agenta_client/types/session_turns_response.py
  • clients/python/agenta_client/types/sessions_response.py
  • clients/python/agenta_client/types/span_input.py
  • clients/python/agenta_client/types/span_output.py
  • clients/python/agenta_client/types/spans_node_input.py
  • clients/python/agenta_client/types/spans_node_output.py
  • clients/python/agenta_client/types/workflow_request_data.py
  • docs/docs/self-host/reference/01-configuration.mdx
  • hosting/docker-compose/ee/docker-compose.dev.yml
  • hosting/docker-compose/ee/docker-compose.gh.yml
  • hosting/docker-compose/oss/docker-compose.dev.yml
  • hosting/docker-compose/oss/docker-compose.gh.yml
  • hosting/kubernetes/helm/templates/api-deployment.yaml
  • sdks/python/agenta/sdk/agents/__init__.py
  • sdks/python/agenta/sdk/agents/adapters/harnesses.py
  • sdks/python/agenta/sdk/agents/adapters/local.py
  • sdks/python/agenta/sdk/agents/adapters/sandbox_agent.py
  • sdks/python/agenta/sdk/agents/dtos.py
  • sdks/python/agenta/sdk/agents/errors.py
  • sdks/python/agenta/sdk/agents/interfaces.py
  • sdks/python/agenta/sdk/agents/utils/wire.py
  • sdks/python/agenta/sdk/engines/tracing/tracing.py
  • sdks/python/agenta/sdk/middlewares/running/normalizer.py
  • sdks/python/agenta/sdk/models/tracing.py
  • sdks/python/oss/tests/pytest/integration/agents/_fake_runner_backend.py
  • sdks/python/oss/tests/pytest/integration/agents/_qa_transcripts.py
  • sdks/python/oss/tests/pytest/unit/agents/conftest.py
  • sdks/python/oss/tests/pytest/unit/agents/connections/test_dtos_model_ref.py
  • sdks/python/oss/tests/pytest/unit/agents/skills/test_skills_e2e.py
  • sdks/python/oss/tests/pytest/unit/agents/test_agent_composition_seam.py
  • sdks/python/oss/tests/pytest/unit/agents/test_dtos_capabilities_events.py
  • sdks/python/oss/tests/pytest/unit/agents/test_environment_lifecycle.py
  • sdks/python/oss/tests/pytest/unit/agents/test_harness_adapters.py
  • sdks/python/oss/tests/pytest/unit/agents/test_harness_identity.py
  • sdks/python/oss/tests/pytest/unit/agents/test_wire_contract.py
  • sdks/python/oss/tests/pytest/unit/test_batch_fold_stream_contract_routing.py
  • sdks/python/oss/tests/pytest/unit/test_invoke_real_handlers_negotiation_routing.py
  • sdks/python/oss/tests/pytest/unit/test_normalizer_passthrough.py
  • sdks/python/oss/tests/pytest/unit/test_tracing_store_agent.py
  • services/oss/tests/pytest/unit/agent/conftest.py
  • web/oss/src/components/SessionInspector/api.ts
  • web/packages/agenta-entities/src/session/api/api.ts
  • web/packages/agenta-entities/src/session/core/liveness.ts
  • web/packages/agenta-entities/src/session/core/schema.ts
  • web/packages/agenta-entities/src/session/index.ts
💤 Files with no reviewable changes (18)
  • clients/python/agenta_client/types/harness_session_record.py
  • clients/python/agenta_client/types/session_state_upsert_request.py
  • api/oss/src/core/sessions/states/interfaces.py
  • clients/python/agenta_client/types/session_state.py
  • api/oss/tests/pytest/unit/session_states/test_harness_sessions_mapping.py
  • api/oss/tests/pytest/unit/session_states/test_session_id_validation.py
  • api/oss/src/dbs/postgres/sessions/states/dbes.py
  • api/oss/src/core/sessions/states/service.py
  • api/oss/src/dbs/postgres/sessions/states/mappings.py
  • api/oss/src/core/sessions/states/dtos.py
  • api/oss/tests/pytest/acceptance/session_states/test_session_states_basics.py
  • clients/python/agenta_client/types/session_state_data.py
  • web/packages/agenta-entities/src/session/index.ts
  • api/oss/tests/pytest/acceptance/session_states/test_harness_sessions_roundtrip.py
  • api/oss/databases/postgres/migrations/core/env.py
  • web/packages/agenta-entities/src/session/core/schema.ts
  • api/oss/src/dbs/postgres/sessions/states/dao.py
  • web/packages/agenta-entities/src/session/api/api.ts

Comment on lines +60 to 61
class SessionStreamResponse(BaseModel):
stream: Optional[SessionStream] = None

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Add count to the stream response envelope.

SessionStreamResponse omits the required response count, unlike the other new session response models.

Proposed fix
 class SessionStreamResponse(BaseModel):
+    count: int = 0
     stream: Optional[SessionStream] = None

As per coding guidelines, “include count plus payload in response envelopes.”

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
class SessionStreamResponse(BaseModel):
stream: Optional[SessionStream] = None
class SessionStreamResponse(BaseModel):
count: int = 0
stream: Optional[SessionStream] = None

Source: Coding guidelines

Comment on lines +236 to +242
self.router.add_api_route(
"/sessions/streams/header",
self.set_session_stream_header,
methods=["PUT", "POST"],
operation_id="set_session_stream_header",
tags=["Sessions"],
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
sed -n '228,243p' api/oss/src/apis/fastapi/sessions/router.py
rg -n -C2 'operation_id="set_session_stream_header"' .

Repository: Agenta-AI/agenta

Length of output: 1078


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

path = Path("api/oss/src/apis/fastapi/sessions/router.py")
text = path.read_text()

# Print every add_api_route block with methods and operation_id in this file.
for m in re.finditer(r'self\.router\.add_api_route\(\n(.*?)\n\s*\)', text, re.S):
    block = m.group(1)
    if 'operation_id=' in block:
        print("BLOCK:\n" + block + "\n---")
PY

# Search for other multi-method routes with explicit operation_id across the repo.
rg -n -U 'methods=\[[^]]*,[^]]*\].*?operation_id=' api/oss/src/apis/fastapi

Repository: Agenta-AI/agenta

Length of output: 6743


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect FastAPI's route -> OpenAPI generation semantics if the package is available.
python3 - <<'PY'
import inspect
try:
    import fastapi
    from fastapi.routing import APIRoute
    import fastapi.openapi.utils as u
    print("fastapi", fastapi.__version__)
    print("APIRoute has operation_id attr:", "operation_id" in APIRoute.__dict__ or hasattr(APIRoute, "operation_id"))
    print("get_openapi_path source excerpt:")
    src = inspect.getsource(u.get_openapi_path)
    for i, line in enumerate(src.splitlines(), 1):
        if "operation_id" in line or "route.methods" in line or "method" in line and "operation_id" in src:
            print(f"{i}: {line}")
except Exception as e:
    print("ERR", type(e).__name__, e)
PY

Repository: Agenta-AI/agenta

Length of output: 204


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check whether this repo has any tests/docs explicitly expecting method-distinct operation IDs.
rg -n 'operation_id|operationId|OpenAPI' api/oss/src/apis/fastapi api/oss/src | head -n 200

Repository: Agenta-AI/agenta

Length of output: 19700


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Probe whether FastAPI treats one APIRoute with multiple methods as one or multiple OpenAPI operations.
python3 - <<'PY'
try:
    from fastapi import FastAPI
    app = FastAPI()

    `@app.api_route`("/x", methods=["PUT", "POST"], operation_id="same_id")
    def handler():
        return {}

    schema = app.openapi()
    ops = schema["paths"]["/x"]
    print(list(ops.keys()))
    print({method: ops[method].get("operationId") for method in ops})
except Exception as e:
    print("ERR", type(e).__name__, e)
PY

Repository: Agenta-AI/agenta

Length of output: 204


🌐 Web query:

FastAPI multi-method route same operationId OpenAPI duplicate operation_id methods list generated client collision

💡 Result:

In FastAPI, using the @app.api_route decorator with multiple HTTP methods (e.g., methods=['GET', 'POST']) has historically caused issues with OpenAPI schema generation [1][2][3]. Because OpenAPI requires every operation to have a unique operationId, the default behavior in older versions of FastAPI—which often assigned the same operationId to all methods on a multi-method route—resulted in duplicate ID warnings and potential client generation errors [1][2][4]. Technical Context and Solutions: 1. Root Cause: FastAPI's default unique ID generation logic historically selected an arbitrary method (often the first in a set) to suffix the operationId, causing all methods on a single route to share the same identifier [1][2][5]. Because route.methods is a set, this behavior was also non-deterministic across different Python runs, leading to unstable OpenAPI schemas [2][4][6]. 2. Recommended Fixes: * Use Explicit operation_id: The most reliable way to avoid collisions is to manually define a unique operation_id for each method [3][7]. @app.get("/items/", operation_id="get_items") @app.post("/items/", operation_id="create_items") async def items:... * Update FastAPI: Recent updates to the framework (including PRs #15698 and related fixes) have introduced logic to ensure that for multi-method routes, FastAPI now generates distinct operationIds by appending the specific HTTP method to each operation [2][8][4]. If you are experiencing this issue, ensure your FastAPI installation is up to date [2][4]. * Separate Routes: If your client generator continues to struggle with multi-method routes, the community-recommended best practice is to separate the functionality into individual route decorators (@app.get, @app.post, etc.) rather than using a single @app.api_route call [3][9][6]. * Custom ID Generation: You can globally override the default behavior by providing a custom generate_unique_id_function to the FastAPI app, which gives you full control over how operation IDs are constructed [7]. def custom_generate_unique_id(route: APIRoute) -> str: return f"{route.name}_{list(route.methods)}" app = FastAPI(generate_unique_id_function=custom_generate_unique_id)

Citations:


🌐 Web query:

FastAPI add_api_route methods=["PUT", "POST"] operation_id same OpenAPI generated operationId duplicate

💡 Result:

The issue where add_api_route with multiple HTTP methods causes duplicate operationId values in FastAPI is a known limitation that stems from how FastAPI historically generated these IDs [1][2][3]. When a route is registered with multiple methods (e.g., methods=["POST", "PUT"]), FastAPI's default generate_unique_id function historically generated a single unique_id based on only the first method in the set, and the OpenAPI metadata generator applied this same ID to all methods on that route [1][4][5]. This violates the OpenAPI specification, which requires each operation to have a unique operationId [1][4][3]. As of mid-2026, improvements have been integrated into FastAPI to address this behavior [1][4]. If you are encountering this issue, you have the following options: 1. Use explicit operation IDs: The most reliable way to avoid collisions is to define a unique operation_id for each method explicitly [2][6]. When an explicit operation_id is provided, FastAPI will use it as-is for that operation [1][4][3]. python # Example of setting explicit IDs app.add_api_route("/items", handler_post, methods=["POST"], operation_id="create_item") app.add_api_route("/items", handler_put, methods=["PUT"], operation_id="update_item") 2. Separate the routes: Instead of using a single add_api_route call with multiple methods, you can define separate routes for each method [2][7]. This allows each path operation to have its own unique operationId automatically [2][3]. 3. Update FastAPI: Ensure you are using a recent version of FastAPI. Recent updates have introduced logic to automatically generate unique, per-method operationId values for multi-method routes by appending the specific method (e.g., _post, _put) to the route's base ID, ensuring compliance with the OpenAPI specification [1][4][3]. If you are using a custom generate_unique_id_function, ensure it is designed to produce unique IDs for each distinct operation, taking into account both the path and the HTTP method [2][6].

Citations:


🌐 Web query:

FastAPI operation_id multi-method route OpenAPI same ID each method source

💡 Result:

According to the OpenAPI specification, the operationId field must be unique among all operations described in an API [1][2][3][4]. In FastAPI, previous versions had a known bug where routes registered with multiple HTTP methods (e.g., methods=["GET", "POST"]) incorrectly shared the same default operationId [5][6][7]. Recent updates to FastAPI (addressed in several pull requests such as #15698, #15321, #15194, and #15222) have implemented fixes for this behavior [5][6][8][9]. When using modern versions of FastAPI, the framework now automatically generates unique operationIds for routes with multiple methods by appending the specific HTTP method to the base identifier [5][6][9]. If you are experiencing duplicate operationId warnings or require specific naming, you have several options: 1. Use explicit identifiers: You can manually set a unique operation_id for each path operation using the operation_id parameter in your route decorator [10][11]. @app.get("/items/", operation_id="get_items_list") async def read_items:... @app.post("/items/", operation_id="create_item") async def create_item:... 2. Customize ID generation: You can provide a custom generate_unique_id_function to the FastAPI app, which allows you to define the logic used to create operationIds for all your routes [10][11]. This function receives the APIRoute object and must return a unique string [10]. If you are on an older version of FastAPI, upgrading to the latest version is the recommended path to resolve the default duplicate operationId behavior [5][9].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n 'fastapi[ =<~!].*|fastapi==' -g 'pyproject.toml' -g 'poetry.lock' -g 'requirements*.txt' -g 'uv.lock' -g 'Pipfile*' -g 'package*.json' api . | head -n 200

Repository: Agenta-AI/agenta

Length of output: 154


🌐 Web query:

FastAPI explicit operation_id multi-method route same operationId for PUT POST

💡 Result:

In FastAPI, the operationId in the OpenAPI schema must be unique for every operation to comply with the OpenAPI 3.x specification [1][2]. If you explicitly define an operation_id for a route, FastAPI uses that exact value [3][4]. Consequently, if you assign the same operation_id to a path operation that handles multiple methods (e.g., both POST and PUT), it will result in a duplicate operationId in the generated OpenAPI schema, which often triggers a UserWarning during schema generation [3][5][6]. For routes where you do not explicitly set an operation_id, FastAPI automatically generates one based on the function name and the HTTP method [3][1]. Historically, multi-method routes caused issues where they shared the same generated ID, but recent updates (as of mid-2026) have introduced logic to ensure that these automatically generated IDs are unique per method (e.g., appending the method name) [5][1][4]. To maintain valid OpenAPI compliance when using multiple methods, you should follow these guidelines: 1. Avoid Explicit Duplicate IDs: Do not provide the same operation_id string to different HTTP methods on the same route [3]. If you must set them manually, ensure each method's ID is unique [3]. 2. Let FastAPI Handle It: If you omit the operation_id parameter, FastAPI's default generation logic will now handle the uniqueness for you, creating distinct IDs for each method [1][4]. 3. Custom Generators: If you use a custom generate_unique_id_function to define your own global ID naming convention, ensure that your function generates a unique string for every path operation, as FastAPI will use your function's output as the base for all operations on that route [3][4].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n 'methods=\["PUT", "POST"\]|methods=\["POST", "PUT"\]|operation_id="set_session_stream_header"|operationId' api/oss/src api/oss/tests api/oss | head -n 200

Repository: Agenta-AI/agenta

Length of output: 2896


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find the pinned FastAPI version in the API environment files.
fd -a 'pyproject.toml|poetry.lock|requirements*.txt|uv.lock|Pipfile*' api/oss api | while read -r f; do
  rg -n 'fastapi' "$f" || true
done

Repository: Agenta-AI/agenta

Length of output: 977


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n 'generate_unique_id_function|unique_id' api/oss/src api/oss | head -n 100

Repository: Agenta-AI/agenta

Length of output: 335


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read the exact route block and nearby code to ensure there isn't a hidden workaround.
sed -n '232,246p' api/oss/src/apis/fastapi/sessions/router.py

Repository: Agenta-AI/agenta

Length of output: 597


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check whether this repo customizes FastAPI operation-id generation.
rg -n 'generate_unique_id_function|unique_id' api/oss/src api/oss | head -n 100

Repository: Agenta-AI/agenta

Length of output: 335


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check if any app-level OpenAPI customizations affect operationId generation.
rg -n 'openapi|operationId|operation_id|generate_unique_id' api/oss/src/utils api/oss/src/apis/fastapi api/oss/src | head -n 200

Repository: Agenta-AI/agenta

Length of output: 19980


Give PUT and POST distinct operation IDs, or split this into separate routes. operation_id="set_session_stream_header" is shared by both verbs here, so the OpenAPI schema will contain duplicate operationIds and can confuse generated clients.

Comment thread api/oss/src/apis/fastapi/sessions/router.py
Comment on lines +59 to +74
references: Optional[List[Reference]] = query.references if query else None
if references:
matching_turns = await self.turns_service.query_turns(
project_id=project_id,
query=SessionTurnQuery(references=references),
)
session_ids = sorted({turn.session_id for turn in matching_turns})
if not session_ids:
return []

return await self.streams_service.query_streams(
project_id=project_id,
filter=SessionStreamQuery(),
windowing=windowing,
session_ids=session_ids,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀 Performance & Scalability | 🟠 Major | 🏗️ Heavy lift

Resolve reference filters inside SQL instead of materializing every turn.

This unwindowed query loads all matching turn DTOs, deduplicates them in Python, then creates a potentially huge IN (...) filter before stream pagination applies. Use a distinct-session subquery or join between turns and streams.

Comment on lines +92 to +107
await self.turns_service.delete_by_session_id(
project_id=project_id,
session_id=session_id,
)
await self.interactions_service.delete_by_session_id(
project_id=project_id,
session_id=session_id,
)
await self.mounts_service.delete_session_mounts(
project_id=project_id,
session_id=session_id,
)
await self.streams_service.hard_delete(
project_id=project_id,
session_id=session_id,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Quiesce active sessions before hard-delete or archive fan-out.

Neither path clears Redis locks or tears down the runner. A heartbeat can recreate a hard-deleted stream, while an archived session may keep running against a hidden row. Call streams_service.kill(...) before deletion; reject active archives or explicitly tear them down first.

Also applies to: 118-126

Comment on lines +327 to +345
# A late-arriving lower-index write for a stale turn must never win — the
# resume pointer is ORDER BY turn_index DESC, not insertion order.
latest_overall = await dao.append(
project_id=project_id,
user_id=None,
turn=SessionTurnCreate(
session_id=session_id,
stream_id=stream_id,
turn_index=3,
harness_kind=HarnessKind.CLAUDE,
agent_session_id="claude-sess-3",
sandbox_id="sandbox-3",
),
)

latest = await dao.latest_turn(project_id=project_id, session_id=session_id)
assert latest is not None
assert latest.id == latest_overall.id
assert latest.turn_index == 3

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Actually append a stale lower-index turn after the latest turn.

The code inserts index 3 last, so both insertion-order and turn_index DESC implementations pass. Insert the expected latest turn at index 4, then append index 3, and assert that index 4 remains latest.

Comment on lines +103 to +120
async def test_delete_session_delegates_to_service_keyed_by_session_id():
sessions_service = AsyncMock()
router = SessionsRootRouter(sessions_service=sessions_service)

project_id = uuid4()
user_id = uuid4()
app = FastAPI()
request = _make_authed_request(app, project_id, user_id, method="DELETE")

with _patched_access(True):
result = await router.delete_session(request=request, session_id="sess-1")

assert result == {"ok": True}
sessions_service.delete_session.assert_awaited_once()
call_kwargs = sessions_service.delete_session.await_args.kwargs
assert call_kwargs["project_id"] == project_id
assert call_kwargs["session_id"] == "sess-1"
assert "stream_id" not in call_kwargs

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Assert the complete mutation scope.

Line 117 should verify user_id; Lines 217-219 should verify both project_id and user_id. Because the service is an unspecced AsyncMock, dropping these scope arguments would otherwise pass and could permit cross-tenant mutation regressions.

Also applies to: 203-219

Comment on lines +84 to +98
@pytest.mark.anyio
async def test_ingest_child_span_leaves_identity_columns_null(anyio_backend):
assert anyio_backend == "asyncio"
engine = _FakeEngine()
dao = TracingDAO(engine=engine)

child = _flat_span(span_id=uuid4().hex, parent_id=uuid4().hex)

await dao.ingest(project_id=uuid4(), user_id=uuid4(), span_dtos=[child])

values = engine.executed[0].compile().params

assert values["session_id"] is None
assert values["user_id"] is None
assert values["agent_id"] is None

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Supply identity fields when testing child-span suppression.

The current values are null at input, so the assertions pass even if child spans do no root-only filtering. Construct the child with session_id, user_id, and agent_id, then verify ingestion clears them.

Proposed change
-child = _flat_span(span_id=uuid4().hex, parent_id=uuid4().hex)
+child = _flat_span(
+    span_id=uuid4().hex,
+    parent_id=uuid4().hex,
+    session_id="sess-1",
+    user_id="user-1",
+    agent_id="agent-1",
+)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@pytest.mark.anyio
async def test_ingest_child_span_leaves_identity_columns_null(anyio_backend):
assert anyio_backend == "asyncio"
engine = _FakeEngine()
dao = TracingDAO(engine=engine)
child = _flat_span(span_id=uuid4().hex, parent_id=uuid4().hex)
await dao.ingest(project_id=uuid4(), user_id=uuid4(), span_dtos=[child])
values = engine.executed[0].compile().params
assert values["session_id"] is None
assert values["user_id"] is None
assert values["agent_id"] is None
`@pytest.mark.anyio`
async def test_ingest_child_span_leaves_identity_columns_null(anyio_backend):
assert anyio_backend == "asyncio"
engine = _FakeEngine()
dao = TracingDAO(engine=engine)
child = _flat_span(
span_id=uuid4().hex,
parent_id=uuid4().hex,
session_id="sess-1",
user_id="user-1",
agent_id="agent-1",
)
await dao.ingest(project_id=uuid4(), user_id=uuid4(), span_dtos=[child])
values = engine.executed[0].compile().params
assert values["session_id"] is None
assert values["user_id"] is None
assert values["agent_id"] is None

@@ -38,4 +38,4 @@ def __getattr__(attr_name: str) -> typing.Any:
def __dir__():
lazy_attrs = list(_dynamic_imports.keys())
return sorted(lazy_attrs)
__all__ = ["AdminAccountCreateOptions", "AdminAccountRead", "AdminAccountsCreate", "AdminAccountsDelete", "AdminAccountsDeleteTarget", "AdminAccountsResponse", "AdminApiKeyCreate", "AdminApiKeyResponse", "AdminDeleteResponse", "AdminDeletedEntities", "AdminDeletedEntity", "AdminOrganizationCreate", "AdminOrganizationMembershipCreate", "AdminOrganizationMembershipRead", "AdminOrganizationRead", "AdminProjectCreate", "AdminProjectMembershipCreate", "AdminProjectMembershipRead", "AdminProjectRead", "AdminSimpleAccountCreate", "AdminSimpleAccountDeleteEntry", "AdminSimpleAccountRead", "AdminSimpleAccountsApiKeysCreate", "AdminSimpleAccountsCreate", "AdminSimpleAccountsDelete", "AdminSimpleAccountsOrganizationsCreate", "AdminSimpleAccountsOrganizationsMembershipsCreate", "AdminSimpleAccountsOrganizationsTransferOwnership", "AdminSimpleAccountsOrganizationsTransferOwnershipIncludeProjects", "AdminSimpleAccountsOrganizationsTransferOwnershipIncludeProjectsZero", "AdminSimpleAccountsOrganizationsTransferOwnershipIncludeWorkspaces", "AdminSimpleAccountsOrganizationsTransferOwnershipIncludeWorkspacesZero", "AdminSimpleAccountsOrganizationsTransferOwnershipResponse", "AdminSimpleAccountsProjectsCreate", "AdminSimpleAccountsProjectsMembershipsCreate", "AdminSimpleAccountsResponse", "AdminSimpleAccountsUsersCreate", "AdminSimpleAccountsUsersIdentitiesCreate", "AdminSimpleAccountsUsersResetPassword", "AdminSimpleAccountsWorkspacesCreate", "AdminSimpleAccountsWorkspacesMembershipsCreate", "AdminStructuredError", "AdminSubscriptionCreate", "AdminSubscriptionRead", "AdminUserCreate", "AdminUserIdentityCreate", "AdminUserIdentityRead", "AdminUserIdentityReadStatus", "AdminUserRead", "AdminWorkspaceCreate", "AdminWorkspaceMembershipCreate", "AdminWorkspaceMembershipRead", "AdminWorkspaceRead", "AgentTemplateOverlay", "AgentaApi", "AgentaApiEnvironment", "Analytics", "AnalyticsResponse", "Annotation", "AnnotationCreate", "AnnotationCreateLinks", "AnnotationEdit", "AnnotationEditLinks", "AnnotationLinkResponse", "AnnotationLinks", "AnnotationQuery", "AnnotationQueryLinks", "AnnotationResponse", "AnnotationsResponse", "Application", "ApplicationArtifactFlags", "ApplicationArtifactQueryFlags", "ApplicationCatalogPreset", "ApplicationCatalogPresetResponse", "ApplicationCatalogPresetsResponse", "ApplicationCatalogTemplate", "ApplicationCatalogTemplateResponse", "ApplicationCatalogTemplatesResponse", "ApplicationCatalogType", "ApplicationCatalogTypesResponse", "ApplicationCreate", "ApplicationEdit", "ApplicationFlags", "ApplicationQuery", "ApplicationResponse", "ApplicationRevisionCommit", "ApplicationRevisionCreate", "ApplicationRevisionDataInput", "ApplicationRevisionDataInputHeadersValue", "ApplicationRevisionDataInputRuntime", "ApplicationRevisionDataOutput", "ApplicationRevisionDataOutputHeadersValue", "ApplicationRevisionDataOutputRuntime", "ApplicationRevisionEdit", "ApplicationRevisionFlags", "ApplicationRevisionInput", "ApplicationRevisionOutput", "ApplicationRevisionQuery", "ApplicationRevisionQueryFlags", "ApplicationRevisionResolveResponse", "ApplicationRevisionResponse", "ApplicationRevisionsLog", "ApplicationRevisionsResponse", "ApplicationVariant", "ApplicationVariantCreate", "ApplicationVariantEdit", "ApplicationVariantFlags", "ApplicationVariantFork", "ApplicationVariantResponse", "ApplicationVariantsResponse", "ApplicationsResponse", "AsyncAgentaApi", "BodyConfigsFetchVariantsConfigsFetchPost", "Bucket", "BuiltinToolConfig", "BuiltinToolConfigPermission", "CapabilitiesResult", "Capability", "CapabilityConnection", "CapabilityGuidance", "CollectStatusResponse", "CommandMode", "ComparisonOperator", "Condition", "ConditionOperator", "ConditionOptions", "ConditionValue", "ConfigResponseModel", "ConnectAffordance", "ConnectionRequirement", "CreateSimpleTestsetFromFileRequestFileType", "CreateTestsetRevisionFromFileRequestFileType", "CustomModelSettingsDto", "CustomProviderDto", "CustomProviderKind", "CustomProviderSettingsDto", "CustomSecretDto", "CustomSecretFormat", "CustomSecretSettingsDto", "CustomSecretSettingsDtoContent", "CustomSecretSettingsDtoContentOneValue", "DictOperator", "DiscoverResponse", "DiscoverResponseMethodsValue", "DiscoveredAlternative", "DiscoveredTool", "DiscoveredToolType", "DiscoveredTriggerAlternative", "DiscoveredTriggerEvent", "DiscoveredTriggerEventType", "EditSimpleTestsetFromFileRequestFileType", "EntityRef", "Environment", "EnvironmentCreate", "EnvironmentEdit", "EnvironmentFlags", "EnvironmentQueryFlags", "EnvironmentResponse", "EnvironmentRevisionCommit", "EnvironmentRevisionCreate", "EnvironmentRevisionData", "EnvironmentRevisionDelta", "EnvironmentRevisionEdit", "EnvironmentRevisionInput", "EnvironmentRevisionOutput", "EnvironmentRevisionResolveResponse", "EnvironmentRevisionResponse", "EnvironmentRevisionsLog", "EnvironmentRevisionsResponse", "EnvironmentVariant", "EnvironmentVariantCreate", "EnvironmentVariantEdit", "EnvironmentVariantFork", "EnvironmentVariantResponse", "EnvironmentVariantsResponse", "EnvironmentsResponse", "ErrorPolicy", "EvaluationMetrics", "EvaluationMetricsCreate", "EvaluationMetricsIdsResponse", "EvaluationMetricsQuery", "EvaluationMetricsQueryScenarioIds", "EvaluationMetricsQueryTimestamps", "EvaluationMetricsRefresh", "EvaluationMetricsResponse", "EvaluationMetricsSetRequest", "EvaluationQueue", "EvaluationQueueCreate", "EvaluationQueueData", "EvaluationQueueEdit", "EvaluationQueueFlags", "EvaluationQueueIdResponse", "EvaluationQueueIdsResponse", "EvaluationQueueQuery", "EvaluationQueueQueryFlags", "EvaluationQueueResponse", "EvaluationQueueScenariosQuery", "EvaluationQueuesResponse", "EvaluationResult", "EvaluationResultCreate", "EvaluationResultIdResponse", "EvaluationResultIdsResponse", "EvaluationResultQuery", "EvaluationResultResponse", "EvaluationResultsResponse", "EvaluationResultsSetRequest", "EvaluationRun", "EvaluationRunCreate", "EvaluationRunDataConcurrency", "EvaluationRunDataInput", "EvaluationRunDataMapping", "EvaluationRunDataMappingColumn", "EvaluationRunDataMappingStep", "EvaluationRunDataOutput", "EvaluationRunDataStepInput", "EvaluationRunDataStepInputKey", "EvaluationRunDataStepInputOrigin", "EvaluationRunDataStepInputType", "EvaluationRunDataStepOutput", "EvaluationRunDataStepOutputOrigin", "EvaluationRunDataStepOutputType", "EvaluationRunEdit", "EvaluationRunFlags", "EvaluationRunIdResponse", "EvaluationRunIdsRequest", "EvaluationRunIdsResponse", "EvaluationRunQuery", "EvaluationRunQueryFlags", "EvaluationRunResponse", "EvaluationRunsResponse", "EvaluationScenario", "EvaluationScenarioCreate", "EvaluationScenarioEdit", "EvaluationScenarioIdResponse", "EvaluationScenarioIdsResponse", "EvaluationScenarioQuery", "EvaluationScenarioResponse", "EvaluationScenariosResponse", "EvaluationStatus", "Evaluator", "EvaluatorArtifactFlags", "EvaluatorArtifactQueryFlags", "EvaluatorCatalogPreset", "EvaluatorCatalogPresetResponse", "EvaluatorCatalogPresetsResponse", "EvaluatorCatalogTemplate", "EvaluatorCatalogTemplateResponse", "EvaluatorCatalogTemplatesResponse", "EvaluatorCatalogType", "EvaluatorCatalogTypesResponse", "EvaluatorCreate", "EvaluatorEdit", "EvaluatorFlags", "EvaluatorQuery", "EvaluatorResponse", "EvaluatorRevisionCommit", "EvaluatorRevisionCreate", "EvaluatorRevisionDataInput", "EvaluatorRevisionDataInputHeadersValue", "EvaluatorRevisionDataInputRuntime", "EvaluatorRevisionDataOutput", "EvaluatorRevisionDataOutputHeadersValue", "EvaluatorRevisionDataOutputRuntime", "EvaluatorRevisionEdit", "EvaluatorRevisionFlags", "EvaluatorRevisionInput", "EvaluatorRevisionOutput", "EvaluatorRevisionQuery", "EvaluatorRevisionQueryFlags", "EvaluatorRevisionResolveResponse", "EvaluatorRevisionResponse", "EvaluatorRevisionsLog", "EvaluatorRevisionsResponse", "EvaluatorTemplate", "EvaluatorTemplatesResponse", "EvaluatorVariant", "EvaluatorVariantCreate", "EvaluatorVariantEdit", "EvaluatorVariantFlags", "EvaluatorVariantFork", "EvaluatorVariantResponse", "EvaluatorVariantsResponse", "EvaluatorsResponse", "Event", "EventQuery", "EventType", "EventsQueryResponse", "ExistenceOperator", "FetchLegacyAnalyticsRequestNewest", "FetchLegacyAnalyticsRequestOldest", "FetchSimpleTestsetToFileRequestFileType", "FetchTestsetRevisionToFileRequestFileType", "FilteringInput", "FilteringInputConditionsItem", "FilteringOutput", "FilteringOutputConditionsItem", "Focus", "Folder", "FolderCreate", "FolderEdit", "FolderIdResponse", "FolderKind", "FolderQuery", "FolderQueryKinds", "FolderResponse", "FoldersResponse", "Format", "Formatting", typing.Any, typing.Any, "GatewayToolConfig", "GatewayToolConfigPermission", "HarnessSessionRecord", "Header", "HttpValidationError", "InviteRequest", "Invocation", "InvocationCreate", "InvocationCreateLinks", "InvocationEdit", "InvocationEditLinks", "InvocationLinkResponse", "InvocationLinks", "InvocationQuery", "InvocationQueryLinks", "InvocationResponse", "InvocationsResponse", "JsonSchemasInput", "JsonSchemasOutput", typing.Any, typing.Any, "LegacyLifecycleDto", "ListApiKeysResponse", "ListOperator", "ListOptions", "LogicalOperator", "MetricSpec", "MetricType", "MetricsBucket", "Mount", "MountCreate", "MountCredentials", "MountCredentialsResponse", "MountData", "MountEdit", "MountFileDeletedResponse", "MountFileWrittenResponse", "MountFlags", "MountFolderCreatedResponse", "MountQuery", "MountResponse", "MountsResponse", "NumericOperator", "OTelEventInput", "OTelEventInputTimestamp", "OTelEventOutput", "OTelEventOutputTimestamp", "OTelHashInput", "OTelHashOutput", "OTelLinkInput", "OTelLinkOutput", "OTelLinksResponse", "OTelReferenceInput", "OTelReferenceOutput", "OTelSpanKind", "OTelStatusCode", "OTelTracingRequest", "OTelTracingResponse", "OldAnalyticsResponse", "Organization", "OrganizationDetails", "OrganizationDomainResponse", "OrganizationProviderResponse", "OrganizationUpdate", "Permission", "PlaygroundBuildKitContext", "ProjectsResponse", "QueriesResponse", "Query", "QueryApplicationVariantsRequestOrder", "QueryCreate", "QueryEdit", "QueryEnvironmentRevisionsRequestOrder", "QueryEnvironmentVariantsRequestOrder", "QueryEnvironmentsRequestOrder", "QueryEvaluatorVariantsRequestOrder", "QueryFlags", "QueryQueriesRequestOrder", "QueryQueryFlags", "QueryResponse", "QueryRevision", "QueryRevisionCommit", "QueryRevisionCreate", "QueryRevisionDataInput", "QueryRevisionDataOutput", "QueryRevisionEdit", "QueryRevisionQuery", "QueryRevisionResponse", "QueryRevisionsLog", "QueryRevisionsResponse", "QuerySpansAnalyticsRequestNewest", "QuerySpansAnalyticsRequestOldest", "QueryVariant", "QueryVariantCreate", "QueryVariantEdit", "QueryVariantFork", "QueryVariantQuery", "QueryVariantResponse", "QueryVariantsResponse", "QueryWorkflowRevisionsRequestOrder", "QueryWorkflowVariantsRequestOrder", "QueryWorkflowsRequestOrder", "Reference", "ReferenceRequestModelInput", "ReferenceRequestModelOutput", "RequestType", "ResolutionInfo", "ResolvedTool", "RetrievalInfo", "SecretDto", "SecretDtoData", "SecretKind", "SecretResponseDto", "SecretResponseDtoData", "Selector", "SessionHeartbeatResponseModel", "SessionIdsResponse", "SessionInteraction", "SessionInteractionData", "SessionInteractionFlags", "SessionInteractionKind", "SessionInteractionQuery", "SessionInteractionQueryFlags", "SessionInteractionResponse", "SessionInteractionStatus", "SessionInteractionsResponse", "SessionMount", "SessionMountQuery", "SessionMountsResponse", "SessionRecord", "SessionRecordResponse", "SessionRecordsQueryResponse", "SessionState", "SessionStateData", "SessionStateFlags", "SessionStateResponse", "SessionStateUpsertRequest", "SessionStream", "SessionStreamCommandResponseModel", "SessionStreamFlags", "SessionStreamResponseModel", "SessionStreamsResponseModel", "SimpleApplication", "SimpleApplicationAdditionalContext", "SimpleApplicationCreate", "SimpleApplicationDataInput", "SimpleApplicationDataInputHeadersValue", "SimpleApplicationDataInputRuntime", "SimpleApplicationDataOutput", "SimpleApplicationDataOutputHeadersValue", "SimpleApplicationDataOutputRuntime", "SimpleApplicationEdit", "SimpleApplicationFlags", "SimpleApplicationQuery", "SimpleApplicationQueryFlags", "SimpleApplicationResponse", "SimpleApplicationsResponse", "SimpleEnvironment", "SimpleEnvironmentCreate", "SimpleEnvironmentEdit", "SimpleEnvironmentQuery", "SimpleEnvironmentResponse", "SimpleEnvironmentsResponse", "SimpleEvaluation", "SimpleEvaluationCreate", "SimpleEvaluationData", "SimpleEvaluationDataApplicationSteps", "SimpleEvaluationDataApplicationStepsOneValue", "SimpleEvaluationDataEvaluatorSteps", "SimpleEvaluationDataEvaluatorStepsOneValue", "SimpleEvaluationDataQuerySteps", "SimpleEvaluationDataQueryStepsOneValue", "SimpleEvaluationDataTestsetSteps", "SimpleEvaluationDataTestsetStepsOneValue", "SimpleEvaluationEdit", "SimpleEvaluationIdResponse", "SimpleEvaluationQuery", "SimpleEvaluationResponse", "SimpleEvaluationsResponse", "SimpleEvaluator", "SimpleEvaluatorCreate", "SimpleEvaluatorDataInput", "SimpleEvaluatorDataInputHeadersValue", "SimpleEvaluatorDataInputRuntime", "SimpleEvaluatorDataOutput", "SimpleEvaluatorDataOutputHeadersValue", "SimpleEvaluatorDataOutputRuntime", "SimpleEvaluatorEdit", "SimpleEvaluatorFlags", "SimpleEvaluatorQuery", "SimpleEvaluatorQueryFlags", "SimpleEvaluatorResponse", "SimpleEvaluatorsResponse", "SimpleQueriesResponse", "SimpleQuery", "SimpleQueryCreate", "SimpleQueryEdit", "SimpleQueryQuery", "SimpleQueryResponse", "SimpleQueue", "SimpleQueueCreate", "SimpleQueueData", "SimpleQueueDataEvaluators", "SimpleQueueDataEvaluatorsOneValue", "SimpleQueueIdResponse", "SimpleQueueIdsResponse", "SimpleQueueKind", "SimpleQueueQuery", "SimpleQueueResponse", "SimpleQueueScenariosQuery", "SimpleQueueScenariosResponse", "SimpleQueueSettings", "SimpleQueuesResponse", "SimpleTestset", "SimpleTestsetCreate", "SimpleTestsetEdit", "SimpleTestsetQuery", "SimpleTestsetResponse", "SimpleTestsetsResponse", "SimpleTrace", "SimpleTraceChannel", "SimpleTraceCreate", "SimpleTraceCreateLinks", "SimpleTraceEdit", "SimpleTraceEditLinks", "SimpleTraceKind", "SimpleTraceLinkResponse", "SimpleTraceLinks", "SimpleTraceOrigin", "SimpleTraceQuery", "SimpleTraceQueryLinks", "SimpleTraceReferences", "SimpleTraceResponse", "SimpleTracesResponse", "SimpleWorkflow", "SimpleWorkflowCreate", "SimpleWorkflowDataInput", "SimpleWorkflowDataInputHeadersValue", "SimpleWorkflowDataInputRuntime", "SimpleWorkflowDataOutput", "SimpleWorkflowDataOutputHeadersValue", "SimpleWorkflowDataOutputRuntime", "SimpleWorkflowEdit", "SimpleWorkflowFlags", "SimpleWorkflowQuery", "SimpleWorkflowQueryFlags", "SimpleWorkflowResponse", "SimpleWorkflowsResponse", "SpanInput", "SpanInputEndTime", "SpanInputStartTime", "SpanOutput", "SpanOutputEndTime", "SpanOutputStartTime", "SpanResponse", "SpanType", "SpansNodeInput", "SpansNodeInputEndTime", "SpansNodeInputSpansValue", "SpansNodeInputStartTime", "SpansNodeOutput", "SpansNodeOutputEndTime", "SpansNodeOutputSpansValue", "SpansNodeOutputStartTime", "SpansResponse", "SpansTreeInput", "SpansTreeInputSpansValue", "SpansTreeOutput", "SpansTreeOutputSpansValue", "SsoProviderDto", "SsoProviderInfo", "SsoProviderSettingsDto", "SsoProviders", "StandardProviderDto", "StandardProviderKind", "StandardProviderSettingsDto", "Status", "StringOperator", "TestcaseInput", "TestcaseOutput", "TestcaseResponse", "TestcasesResponse", "Testset", "TestsetCreate", "TestsetEdit", "TestsetFlags", "TestsetQuery", "TestsetResponse", "TestsetRevision", "TestsetRevisionCommit", "TestsetRevisionCreate", "TestsetRevisionDataInput", "TestsetRevisionDataOutput", "TestsetRevisionDelta", "TestsetRevisionDeltaColumns", "TestsetRevisionDeltaRows", "TestsetRevisionEdit", "TestsetRevisionQuery", "TestsetRevisionResponse", "TestsetRevisionsLog", "TestsetRevisionsResponse", "TestsetVariant", "TestsetVariantCreate", "TestsetVariantEdit", "TestsetVariantFork", "TestsetVariantQuery", "TestsetVariantResponse", "TestsetVariantsResponse", "TestsetsResponse", "TextOptions", "ToolAuthScheme", "ToolCallData", "ToolCallFunction", "ToolCallResponse", "ToolCatalogAction", "ToolCatalogActionDetails", "ToolCatalogActionResponse", "ToolCatalogActionResponseAction", "ToolCatalogActionsResponse", "ToolCatalogActionsResponseActionsItem", "ToolCatalogCategoriesResponse", "ToolCatalogCategory", "ToolCatalogIntegration", "ToolCatalogIntegrationDetails", "ToolCatalogIntegrationResponse", "ToolCatalogIntegrationResponseIntegration", "ToolCatalogIntegrationsResponse", "ToolCatalogIntegrationsResponseIntegrationsItem", "ToolCatalogProvider", "ToolCatalogProviderDetails", "ToolCatalogProviderResponse", "ToolCatalogProviderResponseProvider", "ToolCatalogProvidersResponse", "ToolCatalogProvidersResponseProvidersItem", "ToolConnection", "ToolConnectionCreate", "ToolConnectionCreateData", "ToolConnectionResponse", "ToolConnectionState", "ToolConnectionStatus", "ToolConnectionsResponse", "ToolProviderKind", "ToolResolveRequestToolsItem", "ToolResolveRequestToolsItem_Builtin", "ToolResolveRequestToolsItem_Gateway", "ToolResolveResponse", "ToolResult", "ToolResultData", "TraceIdResponse", "TraceIdsResponse", "TraceInput", "TraceInputSpansValue", "TraceOutput", "TraceOutputSpansValue", "TraceRequest", "TraceResponse", "TraceType", "TracesRequest", "TracesResponse", "TracingQuery", "TriggerAuthScheme", "TriggerCapabilitiesResult", "TriggerCapability", "TriggerCapabilityConnection", "TriggerCatalogEvent", "TriggerCatalogEventDetails", "TriggerCatalogEventResponse", "TriggerCatalogEventsResponse", "TriggerCatalogIntegration", "TriggerCatalogIntegrationResponse", "TriggerCatalogIntegrationsResponse", "TriggerCatalogProvider", "TriggerCatalogProviderResponse", "TriggerCatalogProvidersResponse", "TriggerConnectAffordance", "TriggerConnection", "TriggerConnectionCreate", "TriggerConnectionCreateData", "TriggerConnectionRequirement", "TriggerConnectionResponse", "TriggerConnectionStatus", "TriggerConnectionsResponse", "TriggerDeliveriesResponse", "TriggerDelivery", "TriggerDeliveryData", "TriggerDeliveryQuery", "TriggerDeliveryResponse", "TriggerDiscoveryConnectionState", "TriggerDiscoveryGuidance", "TriggerEventAck", "TriggerProviderKind", "TriggerSchedule", "TriggerScheduleCreate", "TriggerScheduleData", "TriggerScheduleDataInputsFields", "TriggerScheduleEdit", "TriggerScheduleFlags", "TriggerScheduleQuery", "TriggerScheduleResponse", "TriggerSchedulesResponse", "TriggerSubscription", "TriggerSubscriptionCreate", "TriggerSubscriptionCreateRequest", "TriggerSubscriptionData", "TriggerSubscriptionDataInputsFields", "TriggerSubscriptionEdit", "TriggerSubscriptionFlags", "TriggerSubscriptionQuery", "TriggerSubscriptionResponse", "TriggerSubscriptionsResponse", "UnprocessableEntityError", "UserIdsResponse", "ValidationError", "ValidationErrorLocItem", "WebhookDeliveriesResponse", "WebhookDelivery", "WebhookDeliveryCreate", "WebhookDeliveryData", "WebhookDeliveryQuery", "WebhookDeliveryResponse", "WebhookDeliveryResponseInfo", "WebhookEventType", "WebhookProviderDto", "WebhookProviderSettingsDto", "WebhookSubscription", "WebhookSubscriptionCreate", "WebhookSubscriptionData", "WebhookSubscriptionDataAuthMode", "WebhookSubscriptionEdit", "WebhookSubscriptionFlags", "WebhookSubscriptionQuery", "WebhookSubscriptionResponse", "WebhookSubscriptionTestRequestSubscription", "WebhookSubscriptionsResponse", "Windowing", "WindowingOrder", "Workflow", "WorkflowArtifactFlags", "WorkflowCatalogFlags", "WorkflowCatalogHarness", "WorkflowCatalogHarnessResponse", "WorkflowCatalogHarnessesResponse", "WorkflowCatalogPreset", "WorkflowCatalogPresetResponse", "WorkflowCatalogPresetsResponse", "WorkflowCatalogTemplate", "WorkflowCatalogTemplateResponse", "WorkflowCatalogTemplatesResponse", "WorkflowCatalogType", "WorkflowCatalogTypeResponse", "WorkflowCatalogTypesResponse", "WorkflowCreate", "WorkflowEdit", "WorkflowFlags", "WorkflowResponse", "WorkflowRevisionCommit", "WorkflowRevisionCreate", "WorkflowRevisionDataInput", "WorkflowRevisionDataInputHeadersValue", "WorkflowRevisionDataInputRuntime", "WorkflowRevisionDataOutput", "WorkflowRevisionDataOutputHeadersValue", "WorkflowRevisionDataOutputRuntime", "WorkflowRevisionDelta", "WorkflowRevisionEdit", "WorkflowRevisionFlags", "WorkflowRevisionInput", "WorkflowRevisionOutput", "WorkflowRevisionResolveResponse", "WorkflowRevisionResponse", "WorkflowRevisionsLog", "WorkflowRevisionsResponse", "WorkflowVariant", "WorkflowVariantCreate", "WorkflowVariantEdit", "WorkflowVariantFlags", "WorkflowVariantFork", "WorkflowVariantResponse", "WorkflowVariantsResponse", "WorkflowsResponse", "Workspace", "WorkspaceMemberResponse", "WorkspacePermission", "WorkspaceResponse", "access", "annotations", "applications", "billing", "environments", "evaluations", "evaluators", "events", "folders", "invocations", "keys", "legacy", "mounts", "organizations", "projects", "queries", "secrets", "sessions", "status", "testcases", "testsets", "tools", "traces", "triggers", "users", "webhooks", "workflows", "workspaces"]
__all__ = ["AdminAccountCreateOptions", "AdminAccountRead", "AdminAccountsCreate", "AdminAccountsDelete", "AdminAccountsDeleteTarget", "AdminAccountsResponse", "AdminApiKeyCreate", "AdminApiKeyResponse", "AdminDeleteResponse", "AdminDeletedEntities", "AdminDeletedEntity", "AdminOrganizationCreate", "AdminOrganizationMembershipCreate", "AdminOrganizationMembershipRead", "AdminOrganizationRead", "AdminProjectCreate", "AdminProjectMembershipCreate", "AdminProjectMembershipRead", "AdminProjectRead", "AdminSimpleAccountCreate", "AdminSimpleAccountDeleteEntry", "AdminSimpleAccountRead", "AdminSimpleAccountsApiKeysCreate", "AdminSimpleAccountsCreate", "AdminSimpleAccountsDelete", "AdminSimpleAccountsOrganizationsCreate", "AdminSimpleAccountsOrganizationsMembershipsCreate", "AdminSimpleAccountsOrganizationsTransferOwnership", "AdminSimpleAccountsOrganizationsTransferOwnershipIncludeProjects", "AdminSimpleAccountsOrganizationsTransferOwnershipIncludeProjectsZero", "AdminSimpleAccountsOrganizationsTransferOwnershipIncludeWorkspaces", "AdminSimpleAccountsOrganizationsTransferOwnershipIncludeWorkspacesZero", "AdminSimpleAccountsOrganizationsTransferOwnershipResponse", "AdminSimpleAccountsProjectsCreate", "AdminSimpleAccountsProjectsMembershipsCreate", "AdminSimpleAccountsResponse", "AdminSimpleAccountsUsersCreate", "AdminSimpleAccountsUsersIdentitiesCreate", "AdminSimpleAccountsUsersResetPassword", "AdminSimpleAccountsWorkspacesCreate", "AdminSimpleAccountsWorkspacesMembershipsCreate", "AdminStructuredError", "AdminSubscriptionCreate", "AdminSubscriptionRead", "AdminUserCreate", "AdminUserIdentityCreate", "AdminUserIdentityRead", "AdminUserIdentityReadStatus", "AdminUserRead", "AdminWorkspaceCreate", "AdminWorkspaceMembershipCreate", "AdminWorkspaceMembershipRead", "AdminWorkspaceRead", "AgentTemplateOverlay", "AgentaApi", "AgentaApiEnvironment", "Analytics", "AnalyticsResponse", "Annotation", "AnnotationCreate", "AnnotationCreateLinks", "AnnotationEdit", "AnnotationEditLinks", "AnnotationLinkResponse", "AnnotationLinks", "AnnotationQuery", "AnnotationQueryLinks", "AnnotationResponse", "AnnotationsResponse", "Application", "ApplicationArtifactFlags", "ApplicationArtifactQueryFlags", "ApplicationCatalogPreset", "ApplicationCatalogPresetResponse", "ApplicationCatalogPresetsResponse", "ApplicationCatalogTemplate", "ApplicationCatalogTemplateResponse", "ApplicationCatalogTemplatesResponse", "ApplicationCatalogType", "ApplicationCatalogTypesResponse", "ApplicationCreate", "ApplicationEdit", "ApplicationFlags", "ApplicationQuery", "ApplicationResponse", "ApplicationRevisionCommit", "ApplicationRevisionCreate", "ApplicationRevisionDataInput", "ApplicationRevisionDataInputHeadersValue", "ApplicationRevisionDataInputRuntime", "ApplicationRevisionDataOutput", "ApplicationRevisionDataOutputHeadersValue", "ApplicationRevisionDataOutputRuntime", "ApplicationRevisionEdit", "ApplicationRevisionFlags", "ApplicationRevisionInput", "ApplicationRevisionOutput", "ApplicationRevisionQuery", "ApplicationRevisionQueryFlags", "ApplicationRevisionResolveResponse", "ApplicationRevisionResponse", "ApplicationRevisionsLog", "ApplicationRevisionsResponse", "ApplicationVariant", "ApplicationVariantCreate", "ApplicationVariantEdit", "ApplicationVariantFlags", "ApplicationVariantFork", "ApplicationVariantResponse", "ApplicationVariantsResponse", "ApplicationsResponse", "AsyncAgentaApi", "BodyConfigsFetchVariantsConfigsFetchPost", "Bucket", "BuiltinToolConfig", "BuiltinToolConfigPermission", "CapabilitiesResult", "Capability", "CapabilityConnection", "CapabilityGuidance", "CollectStatusResponse", "CommandMode", "ComparisonOperator", "Condition", "ConditionOperator", "ConditionOptions", "ConditionValue", "ConfigResponseModel", "ConnectAffordance", "ConnectionRequirement", "CreateSimpleTestsetFromFileRequestFileType", "CreateTestsetRevisionFromFileRequestFileType", "CustomModelSettingsDto", "CustomProviderDto", "CustomProviderKind", "CustomProviderSettingsDto", "CustomSecretDto", "CustomSecretFormat", "CustomSecretSettingsDto", "CustomSecretSettingsDtoContent", "CustomSecretSettingsDtoContentOneValue", "DictOperator", "DiscoverResponse", "DiscoverResponseMethodsValue", "DiscoveredAlternative", "DiscoveredTool", "DiscoveredToolType", "DiscoveredTriggerAlternative", "DiscoveredTriggerEvent", "DiscoveredTriggerEventType", "EditSimpleTestsetFromFileRequestFileType", "EntityRef", "Environment", "EnvironmentCreate", "EnvironmentEdit", "EnvironmentFlags", "EnvironmentQueryFlags", "EnvironmentResponse", "EnvironmentRevisionCommit", "EnvironmentRevisionCreate", "EnvironmentRevisionData", "EnvironmentRevisionDelta", "EnvironmentRevisionEdit", "EnvironmentRevisionInput", "EnvironmentRevisionOutput", "EnvironmentRevisionResolveResponse", "EnvironmentRevisionResponse", "EnvironmentRevisionsLog", "EnvironmentRevisionsResponse", "EnvironmentVariant", "EnvironmentVariantCreate", "EnvironmentVariantEdit", "EnvironmentVariantFork", "EnvironmentVariantResponse", "EnvironmentVariantsResponse", "EnvironmentsResponse", "ErrorPolicy", "EvaluationMetrics", "EvaluationMetricsCreate", "EvaluationMetricsIdsResponse", "EvaluationMetricsQuery", "EvaluationMetricsQueryScenarioIds", "EvaluationMetricsQueryTimestamps", "EvaluationMetricsRefresh", "EvaluationMetricsResponse", "EvaluationMetricsSetRequest", "EvaluationQueue", "EvaluationQueueCreate", "EvaluationQueueData", "EvaluationQueueEdit", "EvaluationQueueFlags", "EvaluationQueueIdResponse", "EvaluationQueueIdsResponse", "EvaluationQueueQuery", "EvaluationQueueQueryFlags", "EvaluationQueueResponse", "EvaluationQueueScenariosQuery", "EvaluationQueuesResponse", "EvaluationResult", "EvaluationResultCreate", "EvaluationResultIdResponse", "EvaluationResultIdsResponse", "EvaluationResultQuery", "EvaluationResultResponse", "EvaluationResultsResponse", "EvaluationResultsSetRequest", "EvaluationRun", "EvaluationRunCreate", "EvaluationRunDataConcurrency", "EvaluationRunDataInput", "EvaluationRunDataMapping", "EvaluationRunDataMappingColumn", "EvaluationRunDataMappingStep", "EvaluationRunDataOutput", "EvaluationRunDataStepInput", "EvaluationRunDataStepInputKey", "EvaluationRunDataStepInputOrigin", "EvaluationRunDataStepInputType", "EvaluationRunDataStepOutput", "EvaluationRunDataStepOutputOrigin", "EvaluationRunDataStepOutputType", "EvaluationRunEdit", "EvaluationRunFlags", "EvaluationRunIdResponse", "EvaluationRunIdsRequest", "EvaluationRunIdsResponse", "EvaluationRunQuery", "EvaluationRunQueryFlags", "EvaluationRunResponse", "EvaluationRunsResponse", "EvaluationScenario", "EvaluationScenarioCreate", "EvaluationScenarioEdit", "EvaluationScenarioIdResponse", "EvaluationScenarioIdsResponse", "EvaluationScenarioQuery", "EvaluationScenarioResponse", "EvaluationScenariosResponse", "EvaluationStatus", "Evaluator", "EvaluatorArtifactFlags", "EvaluatorArtifactQueryFlags", "EvaluatorCatalogPreset", "EvaluatorCatalogPresetResponse", "EvaluatorCatalogPresetsResponse", "EvaluatorCatalogTemplate", "EvaluatorCatalogTemplateResponse", "EvaluatorCatalogTemplatesResponse", "EvaluatorCatalogType", "EvaluatorCatalogTypesResponse", "EvaluatorCreate", "EvaluatorEdit", "EvaluatorFlags", "EvaluatorQuery", "EvaluatorResponse", "EvaluatorRevisionCommit", "EvaluatorRevisionCreate", "EvaluatorRevisionDataInput", "EvaluatorRevisionDataInputHeadersValue", "EvaluatorRevisionDataInputRuntime", "EvaluatorRevisionDataOutput", "EvaluatorRevisionDataOutputHeadersValue", "EvaluatorRevisionDataOutputRuntime", "EvaluatorRevisionEdit", "EvaluatorRevisionFlags", "EvaluatorRevisionInput", "EvaluatorRevisionOutput", "EvaluatorRevisionQuery", "EvaluatorRevisionQueryFlags", "EvaluatorRevisionResolveResponse", "EvaluatorRevisionResponse", "EvaluatorRevisionsLog", "EvaluatorRevisionsResponse", "EvaluatorTemplate", "EvaluatorTemplatesResponse", "EvaluatorVariant", "EvaluatorVariantCreate", "EvaluatorVariantEdit", "EvaluatorVariantFlags", "EvaluatorVariantFork", "EvaluatorVariantResponse", "EvaluatorVariantsResponse", "EvaluatorsResponse", "Event", "EventQuery", "EventType", "EventsQueryResponse", "ExistenceOperator", "FetchLegacyAnalyticsRequestNewest", "FetchLegacyAnalyticsRequestOldest", "FetchSimpleTestsetToFileRequestFileType", "FetchTestsetRevisionToFileRequestFileType", "FilteringInput", "FilteringInputConditionsItem", "FilteringOutput", "FilteringOutputConditionsItem", "Focus", "Folder", "FolderCreate", "FolderEdit", "FolderIdResponse", "FolderKind", "FolderQuery", "FolderQueryKinds", "FolderResponse", "FoldersResponse", "Format", "Formatting", typing.Any, typing.Any, "GatewayToolConfig", "GatewayToolConfigPermission", "HarnessKind", "Header", "HttpValidationError", "InviteRequest", "Invocation", "InvocationCreate", "InvocationCreateLinks", "InvocationEdit", "InvocationEditLinks", "InvocationLinkResponse", "InvocationLinks", "InvocationQuery", "InvocationQueryLinks", "InvocationResponse", "InvocationsResponse", "JsonSchemasInput", "JsonSchemasOutput", typing.Any, typing.Any, "LegacyLifecycleDto", "ListApiKeysResponse", "ListOperator", "ListOptions", "LogicalOperator", "MetricSpec", "MetricType", "MetricsBucket", "Mount", "MountCreate", "MountCredentials", "MountCredentialsResponse", "MountData", "MountEdit", "MountFileDeletedResponse", "MountFileWrittenResponse", "MountFlags", "MountFolderCreatedResponse", "MountQuery", "MountResponse", "MountsResponse", "NumericOperator", "OTelEventInput", "OTelEventInputTimestamp", "OTelEventOutput", "OTelEventOutputTimestamp", "OTelHashInput", "OTelHashOutput", "OTelLinkInput", "OTelLinkOutput", "OTelLinksResponse", "OTelReferenceInput", "OTelReferenceOutput", "OTelSpanKind", "OTelStatusCode", "OTelTracingRequest", "OTelTracingResponse", "OldAnalyticsResponse", "Organization", "OrganizationDetails", "OrganizationDomainResponse", "OrganizationProviderResponse", "OrganizationUpdate", "Permission", "PlaygroundBuildKitContext", "ProjectsResponse", "QueriesResponse", "Query", "QueryApplicationVariantsRequestOrder", "QueryCreate", "QueryEdit", "QueryEnvironmentRevisionsRequestOrder", "QueryEnvironmentVariantsRequestOrder", "QueryEnvironmentsRequestOrder", "QueryEvaluatorVariantsRequestOrder", "QueryFlags", "QueryQueriesRequestOrder", "QueryQueryFlags", "QueryResponse", "QueryRevision", "QueryRevisionCommit", "QueryRevisionCreate", "QueryRevisionDataInput", "QueryRevisionDataOutput", "QueryRevisionEdit", "QueryRevisionQuery", "QueryRevisionResponse", "QueryRevisionsLog", "QueryRevisionsResponse", "QuerySpansAnalyticsRequestNewest", "QuerySpansAnalyticsRequestOldest", "QueryVariant", "QueryVariantCreate", "QueryVariantEdit", "QueryVariantFork", "QueryVariantQuery", "QueryVariantResponse", "QueryVariantsResponse", "QueryWorkflowRevisionsRequestOrder", "QueryWorkflowVariantsRequestOrder", "QueryWorkflowsRequestOrder", "Reference", "ReferenceRequestModelInput", "ReferenceRequestModelOutput", "RequestType", "ResolutionInfo", "ResolvedTool", "RetrievalInfo", "SecretDto", "SecretDtoData", "SecretKind", "SecretResponseDto", "SecretResponseDtoData", "Selector", "SessionHeartbeatResult", "SessionIdsResponse", "SessionInteraction", "SessionInteractionData", "SessionInteractionFlags", "SessionInteractionKind", "SessionInteractionQuery", "SessionInteractionQueryFlags", "SessionInteractionResponse", "SessionInteractionStatus", "SessionInteractionsResponse", "SessionMount", "SessionMountQuery", "SessionMountsResponse", "SessionRecord", "SessionRecordResponse", "SessionRecordsQueryResponse", "SessionResponse", "SessionStream", "SessionStreamCommandResponse", "SessionStreamFlags", "SessionStreamHeaderEdit", "SessionStreamResponse", "SessionStreamsResponse", "SessionTurn", "SessionTurnQuery", "SessionTurnResponse", "SessionTurnsResponse", "SessionsResponse", "SimpleApplication", "SimpleApplicationAdditionalContext", "SimpleApplicationCreate", "SimpleApplicationDataInput", "SimpleApplicationDataInputHeadersValue", "SimpleApplicationDataInputRuntime", "SimpleApplicationDataOutput", "SimpleApplicationDataOutputHeadersValue", "SimpleApplicationDataOutputRuntime", "SimpleApplicationEdit", "SimpleApplicationFlags", "SimpleApplicationQuery", "SimpleApplicationQueryFlags", "SimpleApplicationResponse", "SimpleApplicationsResponse", "SimpleEnvironment", "SimpleEnvironmentCreate", "SimpleEnvironmentEdit", "SimpleEnvironmentQuery", "SimpleEnvironmentResponse", "SimpleEnvironmentsResponse", "SimpleEvaluation", "SimpleEvaluationCreate", "SimpleEvaluationData", "SimpleEvaluationDataApplicationSteps", "SimpleEvaluationDataApplicationStepsOneValue", "SimpleEvaluationDataEvaluatorSteps", "SimpleEvaluationDataEvaluatorStepsOneValue", "SimpleEvaluationDataQuerySteps", "SimpleEvaluationDataQueryStepsOneValue", "SimpleEvaluationDataTestsetSteps", "SimpleEvaluationDataTestsetStepsOneValue", "SimpleEvaluationEdit", "SimpleEvaluationIdResponse", "SimpleEvaluationQuery", "SimpleEvaluationResponse", "SimpleEvaluationsResponse", "SimpleEvaluator", "SimpleEvaluatorCreate", "SimpleEvaluatorDataInput", "SimpleEvaluatorDataInputHeadersValue", "SimpleEvaluatorDataInputRuntime", "SimpleEvaluatorDataOutput", "SimpleEvaluatorDataOutputHeadersValue", "SimpleEvaluatorDataOutputRuntime", "SimpleEvaluatorEdit", "SimpleEvaluatorFlags", "SimpleEvaluatorQuery", "SimpleEvaluatorQueryFlags", "SimpleEvaluatorResponse", "SimpleEvaluatorsResponse", "SimpleQueriesResponse", "SimpleQuery", "SimpleQueryCreate", "SimpleQueryEdit", "SimpleQueryQuery", "SimpleQueryResponse", "SimpleQueue", "SimpleQueueCreate", "SimpleQueueData", "SimpleQueueDataEvaluators", "SimpleQueueDataEvaluatorsOneValue", "SimpleQueueIdResponse", "SimpleQueueIdsResponse", "SimpleQueueKind", "SimpleQueueQuery", "SimpleQueueResponse", "SimpleQueueScenariosQuery", "SimpleQueueScenariosResponse", "SimpleQueueSettings", "SimpleQueuesResponse", "SimpleTestset", "SimpleTestsetCreate", "SimpleTestsetEdit", "SimpleTestsetQuery", "SimpleTestsetResponse", "SimpleTestsetsResponse", "SimpleTrace", "SimpleTraceChannel", "SimpleTraceCreate", "SimpleTraceCreateLinks", "SimpleTraceEdit", "SimpleTraceEditLinks", "SimpleTraceKind", "SimpleTraceLinkResponse", "SimpleTraceLinks", "SimpleTraceOrigin", "SimpleTraceQuery", "SimpleTraceQueryLinks", "SimpleTraceReferences", "SimpleTraceResponse", "SimpleTracesResponse", "SimpleWorkflow", "SimpleWorkflowCreate", "SimpleWorkflowDataInput", "SimpleWorkflowDataInputHeadersValue", "SimpleWorkflowDataInputRuntime", "SimpleWorkflowDataOutput", "SimpleWorkflowDataOutputHeadersValue", "SimpleWorkflowDataOutputRuntime", "SimpleWorkflowEdit", "SimpleWorkflowFlags", "SimpleWorkflowQuery", "SimpleWorkflowQueryFlags", "SimpleWorkflowResponse", "SimpleWorkflowsResponse", "SpanInput", "SpanInputEndTime", "SpanInputStartTime", "SpanOutput", "SpanOutputEndTime", "SpanOutputStartTime", "SpanResponse", "SpanType", "SpansNodeInput", "SpansNodeInputEndTime", "SpansNodeInputSpansValue", "SpansNodeInputStartTime", "SpansNodeOutput", "SpansNodeOutputEndTime", "SpansNodeOutputSpansValue", "SpansNodeOutputStartTime", "SpansResponse", "SpansTreeInput", "SpansTreeInputSpansValue", "SpansTreeOutput", "SpansTreeOutputSpansValue", "SsoProviderDto", "SsoProviderInfo", "SsoProviderSettingsDto", "SsoProviders", "StandardProviderDto", "StandardProviderKind", "StandardProviderSettingsDto", "Status", "StringOperator", "TestcaseInput", "TestcaseOutput", "TestcaseResponse", "TestcasesResponse", "Testset", "TestsetCreate", "TestsetEdit", "TestsetFlags", "TestsetQuery", "TestsetResponse", "TestsetRevision", "TestsetRevisionCommit", "TestsetRevisionCreate", "TestsetRevisionDataInput", "TestsetRevisionDataOutput", "TestsetRevisionDelta", "TestsetRevisionDeltaColumns", "TestsetRevisionDeltaRows", "TestsetRevisionEdit", "TestsetRevisionQuery", "TestsetRevisionResponse", "TestsetRevisionsLog", "TestsetRevisionsResponse", "TestsetVariant", "TestsetVariantCreate", "TestsetVariantEdit", "TestsetVariantFork", "TestsetVariantQuery", "TestsetVariantResponse", "TestsetVariantsResponse", "TestsetsResponse", "TextOptions", "ToolAuthScheme", "ToolCallData", "ToolCallFunction", "ToolCallResponse", "ToolCatalogAction", "ToolCatalogActionDetails", "ToolCatalogActionResponse", "ToolCatalogActionResponseAction", "ToolCatalogActionsResponse", "ToolCatalogActionsResponseActionsItem", "ToolCatalogCategoriesResponse", "ToolCatalogCategory", "ToolCatalogIntegration", "ToolCatalogIntegrationDetails", "ToolCatalogIntegrationResponse", "ToolCatalogIntegrationResponseIntegration", "ToolCatalogIntegrationsResponse", "ToolCatalogIntegrationsResponseIntegrationsItem", "ToolCatalogProvider", "ToolCatalogProviderDetails", "ToolCatalogProviderResponse", "ToolCatalogProviderResponseProvider", "ToolCatalogProvidersResponse", "ToolCatalogProvidersResponseProvidersItem", "ToolConnection", "ToolConnectionCreate", "ToolConnectionCreateData", "ToolConnectionResponse", "ToolConnectionState", "ToolConnectionStatus", "ToolConnectionsResponse", "ToolProviderKind", "ToolResolveRequestToolsItem", "ToolResolveRequestToolsItem_Builtin", "ToolResolveRequestToolsItem_Gateway", "ToolResolveResponse", "ToolResult", "ToolResultData", "TraceIdResponse", "TraceIdsResponse", "TraceInput", "TraceInputSpansValue", "TraceOutput", "TraceOutputSpansValue", "TraceRequest", "TraceResponse", "TraceType", "TracesRequest", "TracesResponse", "TracingQuery", "TriggerAuthScheme", "TriggerCapabilitiesResult", "TriggerCapability", "TriggerCapabilityConnection", "TriggerCatalogEvent", "TriggerCatalogEventDetails", "TriggerCatalogEventResponse", "TriggerCatalogEventsResponse", "TriggerCatalogIntegration", "TriggerCatalogIntegrationResponse", "TriggerCatalogIntegrationsResponse", "TriggerCatalogProvider", "TriggerCatalogProviderResponse", "TriggerCatalogProvidersResponse", "TriggerConnectAffordance", "TriggerConnection", "TriggerConnectionCreate", "TriggerConnectionCreateData", "TriggerConnectionRequirement", "TriggerConnectionResponse", "TriggerConnectionStatus", "TriggerConnectionsResponse", "TriggerDeliveriesResponse", "TriggerDelivery", "TriggerDeliveryData", "TriggerDeliveryQuery", "TriggerDeliveryResponse", "TriggerDiscoveryConnectionState", "TriggerDiscoveryGuidance", "TriggerEventAck", "TriggerProviderKind", "TriggerSchedule", "TriggerScheduleCreate", "TriggerScheduleData", "TriggerScheduleDataInputsFields", "TriggerScheduleEdit", "TriggerScheduleFlags", "TriggerScheduleQuery", "TriggerScheduleResponse", "TriggerSchedulesResponse", "TriggerSubscription", "TriggerSubscriptionCreate", "TriggerSubscriptionCreateRequest", "TriggerSubscriptionData", "TriggerSubscriptionDataInputsFields", "TriggerSubscriptionEdit", "TriggerSubscriptionFlags", "TriggerSubscriptionQuery", "TriggerSubscriptionResponse", "TriggerSubscriptionsResponse", "UnprocessableEntityError", "UserIdsResponse", "ValidationError", "ValidationErrorLocItem", "WebhookDeliveriesResponse", "WebhookDelivery", "WebhookDeliveryCreate", "WebhookDeliveryData", "WebhookDeliveryQuery", "WebhookDeliveryResponse", "WebhookDeliveryResponseInfo", "WebhookEventType", "WebhookProviderDto", "WebhookProviderSettingsDto", "WebhookSubscription", "WebhookSubscriptionCreate", "WebhookSubscriptionData", "WebhookSubscriptionDataAuthMode", "WebhookSubscriptionEdit", "WebhookSubscriptionFlags", "WebhookSubscriptionQuery", "WebhookSubscriptionResponse", "WebhookSubscriptionTestRequestSubscription", "WebhookSubscriptionsResponse", "Windowing", "WindowingOrder", "Workflow", "WorkflowArtifactFlags", "WorkflowCatalogFlags", "WorkflowCatalogHarness", "WorkflowCatalogHarnessResponse", "WorkflowCatalogHarnessesResponse", "WorkflowCatalogPreset", "WorkflowCatalogPresetResponse", "WorkflowCatalogPresetsResponse", "WorkflowCatalogTemplate", "WorkflowCatalogTemplateResponse", "WorkflowCatalogTemplatesResponse", "WorkflowCatalogType", "WorkflowCatalogTypeResponse", "WorkflowCatalogTypesResponse", "WorkflowCreate", "WorkflowEdit", "WorkflowFlags", "WorkflowRequestData", "WorkflowResponse", "WorkflowRevisionCommit", "WorkflowRevisionCreate", "WorkflowRevisionDataInput", "WorkflowRevisionDataInputHeadersValue", "WorkflowRevisionDataInputRuntime", "WorkflowRevisionDataOutput", "WorkflowRevisionDataOutputHeadersValue", "WorkflowRevisionDataOutputRuntime", "WorkflowRevisionDelta", "WorkflowRevisionEdit", "WorkflowRevisionFlags", "WorkflowRevisionInput", "WorkflowRevisionOutput", "WorkflowRevisionResolveResponse", "WorkflowRevisionResponse", "WorkflowRevisionsLog", "WorkflowRevisionsResponse", "WorkflowVariant", "WorkflowVariantCreate", "WorkflowVariantEdit", "WorkflowVariantFlags", "WorkflowVariantFork", "WorkflowVariantResponse", "WorkflowVariantsResponse", "WorkflowsResponse", "Workspace", "WorkspaceMemberResponse", "WorkspacePermission", "WorkspaceResponse", "access", "annotations", "applications", "billing", "environments", "evaluations", "evaluators", "events", "folders", "invocations", "keys", "legacy", "mounts", "organizations", "projects", "queries", "secrets", "sessions", "status", "testcases", "testsets", "tools", "traces", "triggers", "users", "webhooks", "workflows", "workspaces"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Invalid typing.Any elements in _dynamic_imports and __all__.

Both files contain unquoted typing.Any objects instead of strings in the __all__ lists and _dynamic_imports keys. In Python, __all__ must be a sequence of strings; including non-string objects causes a TypeError when from module import * is executed and will break static analysis and type checkers. This is likely a Fern generator issue where certain schemas (e.g., FullJsonInput, LabelJsonOutput) resolve to Any and are written verbatim.

  • clients/python/agenta_client/__init__.py#L41-L41: Fix the generator config or OpenAPI spec so that valid string aliases are produced instead of typing.Any.
  • clients/python/agenta_client/types/__init__.py#L797-L797: Update the generator configuration to avoid leaking typing.Any into __all__ here as well.
📍 Affects 2 files
  • clients/python/agenta_client/__init__.py#L41-L41 (this comment)
  • clients/python/agenta_client/types/__init__.py#L797-L797

Comment on lines +278 to +280
if agent_id:
span.set_attribute("id", agent_id, namespace="agent")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Add fallback for raw OpenTelemetry spans.

Similar to store_session, if span is a raw opentelemetry.trace.Span (which does not accept the namespace kwarg), set_attribute will raise a TypeError. This results in the agent_id attribute being silently dropped or causing a crash (depending on the implementation of suppress()).

Please add a try...except TypeError block to handle raw spans by setting "agent.id". Note that the store_user method appears to have this same issue and could also benefit from a similar fallback.

🐛 Proposed fix
-            if agent_id:
-                span.set_attribute("id", agent_id, namespace="agent")
+            if agent_id:
+                try:
+                    span.set_attribute("id", agent_id, namespace="agent")
+                except TypeError:
+                    span.set_attribute("agent.id", agent_id)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if agent_id:
span.set_attribute("id", agent_id, namespace="agent")
if agent_id:
try:
span.set_attribute("id", agent_id, namespace="agent")
except TypeError:
span.set_attribute("agent.id", agent_id)

@mmabrouk mmabrouk left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed after the rebase, the live QA round, and the ingest fix. Verdict: the backend port is faithful and the append-only turns model is the right foundation. Three verified reconciliations with v0.105.x are correct (HarnessKind rename + model_ref threading, the EndpointResolutionError export, the surgical greenlet lock edit). The span-id contract fix is correctly typed at every layer with contract tests on both sides.

One substantive request (inline below): the (project_id, session_id, turn_index) index should be UNIQUE while the migration is still unreleased. Two other items already flagged in the body for JP's judgment, not blockers: the apply_windowing helper auto-picking the always-NULL span_id column as the turns cursor, and the 017 migration dropping session_states rows without conversion (should be a deliberate product decision).

op.create_index(
"ix_session_turns_project_id_session_id_turn_index",
"session_turns",
["project_id", "session_id", "turn_index"],

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recommend unique=True on this index while the migration is still unreleased. Append-only turns are the concurrency substrate for everything multi-surface (two writers racing the same turn index must conflict cleanly, with the loser retrying as the next index), and today nothing prevents a duplicate (session_id, turn_index) pair, which would make latest_turn reads ambiguous. As a bonus it also converts an at-least-once append retry that races its own success into a harmless conflict instead of a silent duplicate row. One-line change now; a data-dedup migration later.

@mmabrouk
mmabrouk force-pushed the sessions-rebase/backend branch from 9e2044c to 3f975df Compare July 18, 2026 17:42
@mmabrouk
mmabrouk marked this pull request as ready for review July 18, 2026 19:10
@dosubot dosubot Bot added size:XXL This PR changes 1000+ lines, ignoring generated files. Backend labels Jul 18, 2026
@mmabrouk
mmabrouk requested a review from jp-agenta July 18, 2026 19:20

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8c1a7f80-aad4-4ac5-b93c-f37a35c9853d

📥 Commits

Reviewing files that changed from the base of the PR and between 386c63e and 3f975df.

⛔ Files ignored due to path filters (51)
  • api/uv.lock is excluded by !**/*.lock
  • web/packages/agenta-api-client/src/generated/api/resources/mounts/client/Client.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/mounts/client/requests/MountQueryRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/Client.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/ArchiveSessionRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/DeleteSessionRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/FetchTurnRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionDetachRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionHeartbeatRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionQueryRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionRecordIngestRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionStreamCommandRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionStreamQueryRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionTurnAppendRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionTurnQueryRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SetSessionStreamHeaderRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/UnarchiveSessionRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/index.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/CommandMode.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/HarnessKind.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/HarnessSessionRecord.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/Mount.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/MountCreate.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/MountQuery.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionHeartbeatResponseModel.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionHeartbeatResult.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionInteraction.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionMount.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionMountQuery.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionRecord.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionState.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStateData.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStateFlags.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStateUpsertRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStream.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStreamCommandResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStreamHeaderEdit.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStreamResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStreamsResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionTurn.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionTurnQuery.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionTurnResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionTurnsResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionsResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SpanInput.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SpanOutput.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SpansNodeInput.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SpansNodeOutput.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/WorkflowRequestData.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/index.ts is excluded by !**/generated/**
📒 Files selected for processing (174)
  • api/entrypoints/routers.py
  • api/oss/databases/postgres/migrations/core/env.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000014_add_session_turns.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000015_add_session_streams_header.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000016_add_mounts_agent_id.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000017_drop_session_states.py
  • api/oss/databases/postgres/migrations/tracing_oss/versions/oss000000003_add_span_identity_columns.py
  • api/oss/databases/postgres/migrations/tracing_oss/versions/oss000000004_add_records_turn_span.py
  • api/oss/src/apis/fastapi/mounts/router.py
  • api/oss/src/apis/fastapi/mounts/utils.py
  • api/oss/src/apis/fastapi/otlp/extractors/adapters/logfire_adapter.py
  • api/oss/src/apis/fastapi/otlp/extractors/canonical_attributes.py
  • api/oss/src/apis/fastapi/otlp/extractors/span_data_builders.py
  • api/oss/src/apis/fastapi/otlp/utils/serialization.py
  • api/oss/src/apis/fastapi/sessions/models.py
  • api/oss/src/apis/fastapi/sessions/router.py
  • api/oss/src/apis/fastapi/tracing/router.py
  • api/oss/src/core/mounts/dtos.py
  • api/oss/src/core/mounts/interfaces.py
  • api/oss/src/core/mounts/service.py
  • api/oss/src/core/sessions/dtos.py
  • api/oss/src/core/sessions/interactions/dtos.py
  • api/oss/src/core/sessions/interactions/interfaces.py
  • api/oss/src/core/sessions/interactions/service.py
  • api/oss/src/core/sessions/records/dtos.py
  • api/oss/src/core/sessions/service.py
  • api/oss/src/core/sessions/states/dtos.py
  • api/oss/src/core/sessions/states/interfaces.py
  • api/oss/src/core/sessions/states/service.py
  • api/oss/src/core/sessions/streams/dtos.py
  • api/oss/src/core/sessions/streams/interfaces.py
  • api/oss/src/core/sessions/streams/runner_client.py
  • api/oss/src/core/sessions/streams/service.py
  • api/oss/src/core/sessions/turns/__init__.py
  • api/oss/src/core/sessions/turns/dtos.py
  • api/oss/src/core/sessions/turns/interfaces.py
  • api/oss/src/core/sessions/turns/service.py
  • api/oss/src/core/sessions/turns/types.py
  • api/oss/src/core/shared/dtos.py
  • api/oss/src/core/tracing/dtos.py
  • api/oss/src/core/tracing/service.py
  • api/oss/src/core/tracing/utils/filtering.py
  • api/oss/src/core/tracing/utils/trees.py
  • api/oss/src/dbs/postgres/mounts/dao.py
  • api/oss/src/dbs/postgres/mounts/dbas.py
  • api/oss/src/dbs/postgres/mounts/dbes.py
  • api/oss/src/dbs/postgres/mounts/mappings.py
  • api/oss/src/dbs/postgres/sessions/interactions/dao.py
  • api/oss/src/dbs/postgres/sessions/records/dao.py
  • api/oss/src/dbs/postgres/sessions/records/dbas.py
  • api/oss/src/dbs/postgres/sessions/records/dbes.py
  • api/oss/src/dbs/postgres/sessions/records/mappings.py
  • api/oss/src/dbs/postgres/sessions/states/dao.py
  • api/oss/src/dbs/postgres/sessions/states/dbes.py
  • api/oss/src/dbs/postgres/sessions/states/mappings.py
  • api/oss/src/dbs/postgres/sessions/streams/dao.py
  • api/oss/src/dbs/postgres/sessions/streams/dbes.py
  • api/oss/src/dbs/postgres/sessions/streams/mappings.py
  • api/oss/src/dbs/postgres/sessions/turns/__init__.py
  • api/oss/src/dbs/postgres/sessions/turns/dao.py
  • api/oss/src/dbs/postgres/sessions/turns/dbas.py
  • api/oss/src/dbs/postgres/sessions/turns/dbes.py
  • api/oss/src/dbs/postgres/sessions/turns/mappings.py
  • api/oss/src/dbs/postgres/sessions/turns/utils.py
  • api/oss/src/dbs/postgres/tracing/dao.py
  • api/oss/src/dbs/postgres/tracing/dbas.py
  • api/oss/src/dbs/postgres/tracing/dbes.py
  • api/oss/src/dbs/postgres/tracing/mappings.py
  • api/oss/src/dbs/postgres/tracing/utils.py
  • api/oss/src/utils/env.py
  • api/oss/tests/pytest/acceptance/session_states/test_harness_sessions_roundtrip.py
  • api/oss/tests/pytest/acceptance/session_states/test_session_states_basics.py
  • api/oss/tests/pytest/acceptance/sessions/__init__.py
  • api/oss/tests/pytest/acceptance/sessions/test_archive_unarchive.py
  • api/oss/tests/pytest/acceptance/sessions/test_records_ingest_contract.py
  • api/oss/tests/pytest/acceptance/sessions/test_stream_header_basics.py
  • api/oss/tests/pytest/acceptance/sessions/test_stream_header_roundtrip.py
  • api/oss/tests/pytest/unit/mounts/test_agent_id_backfill.py
  • api/oss/tests/pytest/unit/mounts/test_agent_mounts.py
  • api/oss/tests/pytest/unit/otlp/test_logfire_adapter.py
  • api/oss/tests/pytest/unit/session_states/__init__.py
  • api/oss/tests/pytest/unit/session_states/test_harness_sessions_mapping.py
  • api/oss/tests/pytest/unit/session_states/test_session_id_validation.py
  • api/oss/tests/pytest/unit/sessions/conftest.py
  • api/oss/tests/pytest/unit/sessions/test_command_matrix_inputs_data.py
  • api/oss/tests/pytest/unit/sessions/test_heartbeat_is_current_turn.py
  • api/oss/tests/pytest/unit/sessions/test_kill_runner_teardown.py
  • api/oss/tests/pytest/unit/sessions/test_mounts_agent_id_backfill.py
  • api/oss/tests/pytest/unit/sessions/test_record_ingest_endpoint.py
  • api/oss/tests/pytest/unit/sessions/test_records_mapping_upsert.py
  • api/oss/tests/pytest/unit/sessions/test_records_turn_span_dao.py
  • api/oss/tests/pytest/unit/sessions/test_runner_client_kill.py
  • api/oss/tests/pytest/unit/sessions/test_sessions_root_service.py
  • api/oss/tests/pytest/unit/sessions/test_stream_header_merge.py
  • api/oss/tests/pytest/unit/sessions/test_turns_dao.py
  • api/oss/tests/pytest/unit/sessions/test_wp5_dao_fanout.py
  • api/oss/tests/pytest/unit/sessions/test_wp5_mount_teardown.py
  • api/oss/tests/pytest/unit/sessions/test_wp5_root_router.py
  • api/oss/tests/pytest/unit/tracing/test_dao_ingest_identity_columns.py
  • api/oss/tests/pytest/unit/tracing/utils/test_trees.py
  • api/pyproject.toml
  • clients/python/agenta_client/__init__.py
  • clients/python/agenta_client/mounts/client.py
  • clients/python/agenta_client/mounts/raw_client.py
  • clients/python/agenta_client/sessions/client.py
  • clients/python/agenta_client/sessions/raw_client.py
  • clients/python/agenta_client/types/__init__.py
  • clients/python/agenta_client/types/harness_kind.py
  • clients/python/agenta_client/types/harness_session_record.py
  • clients/python/agenta_client/types/mount.py
  • clients/python/agenta_client/types/mount_create.py
  • clients/python/agenta_client/types/mount_query.py
  • clients/python/agenta_client/types/session_heartbeat_result.py
  • clients/python/agenta_client/types/session_interaction.py
  • clients/python/agenta_client/types/session_mount.py
  • clients/python/agenta_client/types/session_mount_query.py
  • clients/python/agenta_client/types/session_record.py
  • clients/python/agenta_client/types/session_response.py
  • clients/python/agenta_client/types/session_state.py
  • clients/python/agenta_client/types/session_state_data.py
  • clients/python/agenta_client/types/session_state_upsert_request.py
  • clients/python/agenta_client/types/session_stream.py
  • clients/python/agenta_client/types/session_stream_command_response.py
  • clients/python/agenta_client/types/session_stream_header_edit.py
  • clients/python/agenta_client/types/session_stream_response.py
  • clients/python/agenta_client/types/session_streams_response.py
  • clients/python/agenta_client/types/session_turn.py
  • clients/python/agenta_client/types/session_turn_query.py
  • clients/python/agenta_client/types/session_turn_response.py
  • clients/python/agenta_client/types/session_turns_response.py
  • clients/python/agenta_client/types/sessions_response.py
  • clients/python/agenta_client/types/span_input.py
  • clients/python/agenta_client/types/span_output.py
  • clients/python/agenta_client/types/spans_node_input.py
  • clients/python/agenta_client/types/spans_node_output.py
  • clients/python/agenta_client/types/workflow_request_data.py
  • docs/docs/self-host/reference/01-configuration.mdx
  • hosting/docker-compose/ee/docker-compose.dev.yml
  • hosting/docker-compose/ee/docker-compose.gh.yml
  • hosting/docker-compose/oss/docker-compose.dev.yml
  • hosting/docker-compose/oss/docker-compose.gh.yml
  • hosting/kubernetes/helm/templates/api-deployment.yaml
  • sdks/python/agenta/sdk/agents/__init__.py
  • sdks/python/agenta/sdk/agents/adapters/harnesses.py
  • sdks/python/agenta/sdk/agents/adapters/local.py
  • sdks/python/agenta/sdk/agents/adapters/sandbox_agent.py
  • sdks/python/agenta/sdk/agents/dtos.py
  • sdks/python/agenta/sdk/agents/errors.py
  • sdks/python/agenta/sdk/agents/interfaces.py
  • sdks/python/agenta/sdk/agents/utils/wire.py
  • sdks/python/agenta/sdk/engines/tracing/tracing.py
  • sdks/python/agenta/sdk/middlewares/running/normalizer.py
  • sdks/python/agenta/sdk/models/tracing.py
  • sdks/python/oss/tests/pytest/integration/agents/_fake_runner_backend.py
  • sdks/python/oss/tests/pytest/integration/agents/_qa_transcripts.py
  • sdks/python/oss/tests/pytest/unit/agents/conftest.py
  • sdks/python/oss/tests/pytest/unit/agents/connections/test_dtos_model_ref.py
  • sdks/python/oss/tests/pytest/unit/agents/skills/test_skills_e2e.py
  • sdks/python/oss/tests/pytest/unit/agents/test_agent_composition_seam.py
  • sdks/python/oss/tests/pytest/unit/agents/test_dtos_capabilities_events.py
  • sdks/python/oss/tests/pytest/unit/agents/test_environment_lifecycle.py
  • sdks/python/oss/tests/pytest/unit/agents/test_harness_adapters.py
  • sdks/python/oss/tests/pytest/unit/agents/test_harness_identity.py
  • sdks/python/oss/tests/pytest/unit/agents/test_wire_contract.py
  • sdks/python/oss/tests/pytest/unit/test_batch_fold_stream_contract_routing.py
  • sdks/python/oss/tests/pytest/unit/test_invoke_real_handlers_negotiation_routing.py
  • sdks/python/oss/tests/pytest/unit/test_normalizer_passthrough.py
  • sdks/python/oss/tests/pytest/unit/test_tracing_store_agent.py
  • services/oss/tests/pytest/unit/agent/conftest.py
  • web/oss/src/components/SessionInspector/api.ts
  • web/packages/agenta-entities/src/session/api/api.ts
  • web/packages/agenta-entities/src/session/core/liveness.ts
  • web/packages/agenta-entities/src/session/core/schema.ts
  • web/packages/agenta-entities/src/session/index.ts
💤 Files with no reviewable changes (18)
  • web/packages/agenta-entities/src/session/index.ts
  • api/oss/tests/pytest/unit/session_states/test_session_id_validation.py
  • clients/python/agenta_client/types/session_state.py
  • api/oss/src/core/sessions/states/service.py
  • api/oss/src/core/sessions/states/interfaces.py
  • api/oss/tests/pytest/acceptance/session_states/test_harness_sessions_roundtrip.py
  • api/oss/databases/postgres/migrations/core/env.py
  • api/oss/src/dbs/postgres/sessions/states/dbes.py
  • clients/python/agenta_client/types/session_state_data.py
  • api/oss/src/dbs/postgres/sessions/states/dao.py
  • api/oss/tests/pytest/unit/session_states/test_harness_sessions_mapping.py
  • api/oss/tests/pytest/acceptance/session_states/test_session_states_basics.py
  • clients/python/agenta_client/types/session_state_upsert_request.py
  • api/oss/src/dbs/postgres/sessions/states/mappings.py
  • clients/python/agenta_client/types/harness_session_record.py
  • api/oss/src/core/sessions/states/dtos.py
  • web/packages/agenta-entities/src/session/api/api.ts
  • web/packages/agenta-entities/src/session/core/schema.ts
🚧 Files skipped from review as they are similar to previous changes (130)
  • api/oss/src/dbs/postgres/sessions/records/mappings.py
  • sdks/python/agenta/sdk/agents/init.py
  • clients/python/agenta_client/types/mount.py
  • api/oss/src/core/sessions/interactions/interfaces.py
  • api/oss/src/core/sessions/turns/types.py
  • clients/python/agenta_client/types/span_output.py
  • api/oss/src/core/sessions/interactions/service.py
  • clients/python/agenta_client/types/mount_create.py
  • api/oss/src/dbs/postgres/sessions/turns/dbes.py
  • clients/python/agenta_client/types/session_heartbeat_result.py
  • clients/python/agenta_client/types/session_record.py
  • hosting/kubernetes/helm/templates/api-deployment.yaml
  • sdks/python/agenta/sdk/agents/errors.py
  • clients/python/agenta_client/types/session_stream_response.py
  • web/packages/agenta-entities/src/session/core/liveness.ts
  • sdks/python/oss/tests/pytest/integration/agents/_qa_transcripts.py
  • sdks/python/agenta/sdk/models/tracing.py
  • api/oss/src/dbs/postgres/tracing/dbas.py
  • api/oss/src/dbs/postgres/mounts/dbes.py
  • clients/python/agenta_client/types/harness_kind.py
  • clients/python/agenta_client/types/session_stream_command_response.py
  • api/oss/src/apis/fastapi/tracing/router.py
  • clients/python/agenta_client/types/session_mount.py
  • api/oss/src/core/sessions/dtos.py
  • sdks/python/agenta/sdk/agents/adapters/local.py
  • api/oss/src/apis/fastapi/otlp/extractors/adapters/logfire_adapter.py
  • sdks/python/agenta/sdk/engines/tracing/tracing.py
  • clients/python/agenta_client/types/session_mount_query.py
  • api/oss/src/dbs/postgres/tracing/dbes.py
  • api/oss/src/core/sessions/turns/interfaces.py
  • api/oss/src/dbs/postgres/sessions/turns/utils.py
  • api/oss/databases/postgres/migrations/tracing_oss/versions/oss000000003_add_span_identity_columns.py
  • clients/python/agenta_client/types/session_turn.py
  • clients/python/agenta_client/types/session_turn_query.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000015_add_session_streams_header.py
  • clients/python/agenta_client/types/mount_query.py
  • sdks/python/oss/tests/pytest/unit/test_batch_fold_stream_contract_routing.py
  • api/oss/src/dbs/postgres/sessions/turns/dbas.py
  • clients/python/agenta_client/types/workflow_request_data.py
  • api/oss/src/apis/fastapi/otlp/utils/serialization.py
  • api/oss/src/dbs/postgres/mounts/dbas.py
  • api/oss/src/dbs/postgres/tracing/utils.py
  • api/oss/src/core/tracing/utils/trees.py
  • sdks/python/oss/tests/pytest/unit/agents/connections/test_dtos_model_ref.py
  • hosting/docker-compose/ee/docker-compose.dev.yml
  • sdks/python/oss/tests/pytest/unit/test_invoke_real_handlers_negotiation_routing.py
  • api/oss/src/dbs/postgres/mounts/mappings.py
  • api/oss/src/dbs/postgres/sessions/turns/mappings.py
  • clients/python/agenta_client/types/span_input.py
  • clients/python/agenta_client/types/session_stream_header_edit.py
  • web/oss/src/components/SessionInspector/api.ts
  • clients/python/agenta_client/types/session_response.py
  • api/oss/src/dbs/postgres/sessions/records/dbes.py
  • api/oss/tests/pytest/unit/sessions/conftest.py
  • docs/docs/self-host/reference/01-configuration.mdx
  • api/oss/tests/pytest/acceptance/sessions/test_stream_header_roundtrip.py
  • api/oss/tests/pytest/unit/sessions/test_records_mapping_upsert.py
  • clients/python/agenta_client/types/sessions_response.py
  • api/oss/databases/postgres/migrations/tracing_oss/versions/oss000000004_add_records_turn_span.py
  • clients/python/agenta_client/types/session_turns_response.py
  • api/oss/src/core/sessions/streams/runner_client.py
  • sdks/python/oss/tests/pytest/unit/agents/test_environment_lifecycle.py
  • api/oss/src/core/sessions/interactions/dtos.py
  • api/oss/tests/pytest/unit/otlp/test_logfire_adapter.py
  • sdks/python/agenta/sdk/agents/utils/wire.py
  • sdks/python/agenta/sdk/agents/adapters/sandbox_agent.py
  • hosting/docker-compose/ee/docker-compose.gh.yml
  • api/oss/src/core/sessions/records/dtos.py
  • api/oss/src/apis/fastapi/otlp/extractors/span_data_builders.py
  • api/oss/src/apis/fastapi/mounts/utils.py
  • api/oss/tests/pytest/unit/sessions/test_wp5_mount_teardown.py
  • api/oss/src/dbs/postgres/sessions/interactions/dao.py
  • api/oss/src/core/tracing/utils/filtering.py
  • hosting/docker-compose/oss/docker-compose.gh.yml
  • api/oss/src/core/mounts/interfaces.py
  • clients/python/agenta_client/types/session_stream.py
  • api/oss/tests/pytest/unit/tracing/test_dao_ingest_identity_columns.py
  • api/oss/src/core/sessions/turns/dtos.py
  • clients/python/agenta_client/types/spans_node_output.py
  • api/oss/tests/pytest/acceptance/sessions/test_stream_header_basics.py
  • sdks/python/agenta/sdk/agents/interfaces.py
  • api/oss/tests/pytest/unit/sessions/test_command_matrix_inputs_data.py
  • api/oss/src/core/sessions/service.py
  • api/oss/src/dbs/postgres/sessions/streams/mappings.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000016_add_mounts_agent_id.py
  • sdks/python/oss/tests/pytest/unit/agents/test_agent_composition_seam.py
  • api/oss/tests/pytest/unit/sessions/test_wp5_dao_fanout.py
  • clients/python/agenta_client/types/session_streams_response.py
  • sdks/python/oss/tests/pytest/unit/test_tracing_store_agent.py
  • api/oss/src/core/tracing/dtos.py
  • api/oss/src/dbs/postgres/mounts/dao.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000017_drop_session_states.py
  • api/oss/src/core/mounts/service.py
  • api/oss/src/core/mounts/dtos.py
  • api/pyproject.toml
  • clients/python/agenta_client/mounts/raw_client.py
  • sdks/python/oss/tests/pytest/unit/agents/conftest.py
  • api/oss/tests/pytest/unit/sessions/test_stream_header_merge.py
  • api/oss/tests/pytest/unit/tracing/utils/test_trees.py
  • api/oss/tests/pytest/unit/sessions/test_turns_dao.py
  • api/oss/src/apis/fastapi/mounts/router.py
  • api/oss/tests/pytest/unit/mounts/test_agent_mounts.py
  • sdks/python/oss/tests/pytest/unit/agents/skills/test_skills_e2e.py
  • clients/python/agenta_client/types/session_turn_response.py
  • api/oss/src/dbs/postgres/sessions/records/dao.py
  • sdks/python/agenta/sdk/middlewares/running/normalizer.py
  • api/oss/src/dbs/postgres/tracing/mappings.py
  • api/oss/src/dbs/postgres/sessions/turns/dao.py
  • api/oss/src/utils/env.py
  • api/oss/src/core/sessions/turns/service.py
  • api/oss/tests/pytest/unit/sessions/test_heartbeat_is_current_turn.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000014_add_session_turns.py
  • clients/python/agenta_client/types/init.py
  • api/oss/tests/pytest/unit/sessions/test_records_turn_span_dao.py
  • api/oss/tests/pytest/unit/sessions/test_wp5_root_router.py
  • api/oss/src/core/sessions/streams/dtos.py
  • clients/python/agenta_client/types/session_interaction.py
  • api/oss/tests/pytest/unit/sessions/test_kill_runner_teardown.py
  • sdks/python/oss/tests/pytest/unit/test_normalizer_passthrough.py
  • api/oss/tests/pytest/unit/mounts/test_agent_id_backfill.py
  • sdks/python/agenta/sdk/agents/dtos.py
  • sdks/python/oss/tests/pytest/unit/agents/test_harness_adapters.py
  • api/oss/src/dbs/postgres/sessions/streams/dao.py
  • api/oss/src/apis/fastapi/sessions/models.py
  • sdks/python/oss/tests/pytest/unit/agents/test_dtos_capabilities_events.py
  • api/entrypoints/routers.py
  • sdks/python/oss/tests/pytest/unit/agents/test_harness_identity.py
  • api/oss/src/core/sessions/streams/service.py
  • api/oss/src/apis/fastapi/sessions/router.py
  • clients/python/agenta_client/sessions/client.py

Comment thread api/oss/src/core/tracing/service.py
Comment on lines +25 to +30
# Verbatim from the migration: `left(slug, 13) = '__ag__agent__'` guards, and
# `split_part(substr(slug, 14), '__', 1)` extracts.
_BACKFILL_EXPR = (
"CASE WHEN left(:slug, 13) = '__ag__agent__' "
"THEN split_part(substr(:slug, 14), '__', 1) ELSE NULL END"
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Exercise the migration rather than a copied SQL expression.

This test executes its own _BACKFILL_EXPR, so a later defect or drift in oss000000016_add_mounts_agent_id.py would still pass. Expose and reuse the migration SQL, or run the migration against a temporary mounts table.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
api/oss/src/core/mounts/service.py (1)

418-426: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

N+1 queries during session mount state transitions.

Both archive and unarchive methods iterate over mounts and issue sequential database update queries for each mount, resulting in an N+1 query pattern. Consider introducing bulk update operations in mounts_dao to process these transitions in a single database round-trip.

  • api/oss/src/core/mounts/service.py#L418-L426: Replace the sequential loop with a bulk archive_by_session_id database operation.
  • api/oss/src/core/mounts/service.py#L441-L450: Replace the sequential loop with a bulk unarchive_by_session_id database operation.
api/oss/tests/pytest/unit/sessions/test_runner_client_kill.py (1)

21-27: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Cover each partially configured runner state.

The (None, None) case would miss an incorrect and check that attempts /kill when only the URL or token is configured. Parameterize all missing-value combinations and verify no client is created.

Proposed test coverage
+@pytest.mark.parametrize(
+    ("internal_url", "token"),
+    [
+        (None, None),
+        ("http://runner:8765", None),
+        (None, "shared-secret"),
+    ],
+)
 `@pytest.mark.asyncio`
-async def test_returns_false_when_not_configured():
-    with patch("oss.src.core.sessions.streams.runner_client.env") as mock_env:
-        mock_env.runner = _FakeRunnerEnv(internal_url=None, token=None)
+async def test_returns_false_when_not_configured(internal_url, token):
+    with (
+        patch("oss.src.core.sessions.streams.runner_client.env") as mock_env,
+        patch(
+            "oss.src.core.sessions.streams.runner_client.httpx.AsyncClient"
+        ) as client_cls,
+    ):
+        mock_env.runner = _FakeRunnerEnv(internal_url=internal_url, token=token)
         result = await kill_runner_sandbox(project_id="proj-1", session_id="sess-1")
 
     assert result is False
+    client_cls.assert_not_called()

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 414064b1-3022-4e0a-8d8f-f0a8fac00980

📥 Commits

Reviewing files that changed from the base of the PR and between 3f975df and b90e9e8.

⛔ Files ignored due to path filters (51)
  • api/uv.lock is excluded by !**/*.lock
  • web/packages/agenta-api-client/src/generated/api/resources/mounts/client/Client.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/mounts/client/requests/MountQueryRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/Client.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/ArchiveSessionRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/DeleteSessionRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/FetchTurnRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionDetachRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionHeartbeatRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionQueryRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionRecordIngestRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionStreamCommandRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionStreamQueryRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionTurnAppendRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionTurnQueryRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SetSessionStreamHeaderRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/UnarchiveSessionRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/index.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/CommandMode.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/HarnessKind.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/HarnessSessionRecord.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/Mount.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/MountCreate.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/MountQuery.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionHeartbeatResponseModel.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionHeartbeatResult.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionInteraction.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionMount.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionMountQuery.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionRecord.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionState.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStateData.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStateFlags.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStateUpsertRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStream.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStreamCommandResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStreamHeaderEdit.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStreamResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStreamsResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionTurn.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionTurnQuery.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionTurnResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionTurnsResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionsResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SpanInput.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SpanOutput.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SpansNodeInput.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SpansNodeOutput.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/WorkflowRequestData.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/index.ts is excluded by !**/generated/**
📒 Files selected for processing (174)
  • api/entrypoints/routers.py
  • api/oss/databases/postgres/migrations/core/env.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000014_add_session_turns.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000015_add_session_streams_header.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000016_add_mounts_agent_id.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000017_drop_session_states.py
  • api/oss/databases/postgres/migrations/tracing_oss/versions/oss000000003_add_span_identity_columns.py
  • api/oss/databases/postgres/migrations/tracing_oss/versions/oss000000004_add_records_turn_span.py
  • api/oss/src/apis/fastapi/mounts/router.py
  • api/oss/src/apis/fastapi/mounts/utils.py
  • api/oss/src/apis/fastapi/otlp/extractors/adapters/logfire_adapter.py
  • api/oss/src/apis/fastapi/otlp/extractors/canonical_attributes.py
  • api/oss/src/apis/fastapi/otlp/extractors/span_data_builders.py
  • api/oss/src/apis/fastapi/otlp/utils/serialization.py
  • api/oss/src/apis/fastapi/sessions/models.py
  • api/oss/src/apis/fastapi/sessions/router.py
  • api/oss/src/apis/fastapi/tracing/router.py
  • api/oss/src/core/mounts/dtos.py
  • api/oss/src/core/mounts/interfaces.py
  • api/oss/src/core/mounts/service.py
  • api/oss/src/core/sessions/dtos.py
  • api/oss/src/core/sessions/interactions/dtos.py
  • api/oss/src/core/sessions/interactions/interfaces.py
  • api/oss/src/core/sessions/interactions/service.py
  • api/oss/src/core/sessions/records/dtos.py
  • api/oss/src/core/sessions/service.py
  • api/oss/src/core/sessions/states/dtos.py
  • api/oss/src/core/sessions/states/interfaces.py
  • api/oss/src/core/sessions/states/service.py
  • api/oss/src/core/sessions/streams/dtos.py
  • api/oss/src/core/sessions/streams/interfaces.py
  • api/oss/src/core/sessions/streams/runner_client.py
  • api/oss/src/core/sessions/streams/service.py
  • api/oss/src/core/sessions/turns/__init__.py
  • api/oss/src/core/sessions/turns/dtos.py
  • api/oss/src/core/sessions/turns/interfaces.py
  • api/oss/src/core/sessions/turns/service.py
  • api/oss/src/core/sessions/turns/types.py
  • api/oss/src/core/shared/dtos.py
  • api/oss/src/core/tracing/dtos.py
  • api/oss/src/core/tracing/service.py
  • api/oss/src/core/tracing/utils/filtering.py
  • api/oss/src/core/tracing/utils/trees.py
  • api/oss/src/dbs/postgres/mounts/dao.py
  • api/oss/src/dbs/postgres/mounts/dbas.py
  • api/oss/src/dbs/postgres/mounts/dbes.py
  • api/oss/src/dbs/postgres/mounts/mappings.py
  • api/oss/src/dbs/postgres/sessions/interactions/dao.py
  • api/oss/src/dbs/postgres/sessions/records/dao.py
  • api/oss/src/dbs/postgres/sessions/records/dbas.py
  • api/oss/src/dbs/postgres/sessions/records/dbes.py
  • api/oss/src/dbs/postgres/sessions/records/mappings.py
  • api/oss/src/dbs/postgres/sessions/states/dao.py
  • api/oss/src/dbs/postgres/sessions/states/dbes.py
  • api/oss/src/dbs/postgres/sessions/states/mappings.py
  • api/oss/src/dbs/postgres/sessions/streams/dao.py
  • api/oss/src/dbs/postgres/sessions/streams/dbes.py
  • api/oss/src/dbs/postgres/sessions/streams/mappings.py
  • api/oss/src/dbs/postgres/sessions/turns/__init__.py
  • api/oss/src/dbs/postgres/sessions/turns/dao.py
  • api/oss/src/dbs/postgres/sessions/turns/dbas.py
  • api/oss/src/dbs/postgres/sessions/turns/dbes.py
  • api/oss/src/dbs/postgres/sessions/turns/mappings.py
  • api/oss/src/dbs/postgres/sessions/turns/utils.py
  • api/oss/src/dbs/postgres/tracing/dao.py
  • api/oss/src/dbs/postgres/tracing/dbas.py
  • api/oss/src/dbs/postgres/tracing/dbes.py
  • api/oss/src/dbs/postgres/tracing/mappings.py
  • api/oss/src/dbs/postgres/tracing/utils.py
  • api/oss/src/utils/env.py
  • api/oss/tests/pytest/acceptance/session_states/test_harness_sessions_roundtrip.py
  • api/oss/tests/pytest/acceptance/session_states/test_session_states_basics.py
  • api/oss/tests/pytest/acceptance/sessions/__init__.py
  • api/oss/tests/pytest/acceptance/sessions/test_archive_unarchive.py
  • api/oss/tests/pytest/acceptance/sessions/test_records_ingest_contract.py
  • api/oss/tests/pytest/acceptance/sessions/test_stream_header_basics.py
  • api/oss/tests/pytest/acceptance/sessions/test_stream_header_roundtrip.py
  • api/oss/tests/pytest/unit/mounts/test_agent_id_backfill.py
  • api/oss/tests/pytest/unit/mounts/test_agent_mounts.py
  • api/oss/tests/pytest/unit/otlp/test_logfire_adapter.py
  • api/oss/tests/pytest/unit/session_states/__init__.py
  • api/oss/tests/pytest/unit/session_states/test_harness_sessions_mapping.py
  • api/oss/tests/pytest/unit/session_states/test_session_id_validation.py
  • api/oss/tests/pytest/unit/sessions/conftest.py
  • api/oss/tests/pytest/unit/sessions/test_command_matrix_inputs_data.py
  • api/oss/tests/pytest/unit/sessions/test_heartbeat_is_current_turn.py
  • api/oss/tests/pytest/unit/sessions/test_kill_runner_teardown.py
  • api/oss/tests/pytest/unit/sessions/test_mounts_agent_id_backfill.py
  • api/oss/tests/pytest/unit/sessions/test_record_ingest_endpoint.py
  • api/oss/tests/pytest/unit/sessions/test_records_mapping_upsert.py
  • api/oss/tests/pytest/unit/sessions/test_records_turn_span_dao.py
  • api/oss/tests/pytest/unit/sessions/test_runner_client_kill.py
  • api/oss/tests/pytest/unit/sessions/test_sessions_root_service.py
  • api/oss/tests/pytest/unit/sessions/test_stream_header_merge.py
  • api/oss/tests/pytest/unit/sessions/test_turns_dao.py
  • api/oss/tests/pytest/unit/sessions/test_wp5_dao_fanout.py
  • api/oss/tests/pytest/unit/sessions/test_wp5_mount_teardown.py
  • api/oss/tests/pytest/unit/sessions/test_wp5_root_router.py
  • api/oss/tests/pytest/unit/tracing/test_dao_ingest_identity_columns.py
  • api/oss/tests/pytest/unit/tracing/utils/test_trees.py
  • api/pyproject.toml
  • clients/python/agenta_client/__init__.py
  • clients/python/agenta_client/mounts/client.py
  • clients/python/agenta_client/mounts/raw_client.py
  • clients/python/agenta_client/sessions/client.py
  • clients/python/agenta_client/sessions/raw_client.py
  • clients/python/agenta_client/types/__init__.py
  • clients/python/agenta_client/types/harness_kind.py
  • clients/python/agenta_client/types/harness_session_record.py
  • clients/python/agenta_client/types/mount.py
  • clients/python/agenta_client/types/mount_create.py
  • clients/python/agenta_client/types/mount_query.py
  • clients/python/agenta_client/types/session_heartbeat_result.py
  • clients/python/agenta_client/types/session_interaction.py
  • clients/python/agenta_client/types/session_mount.py
  • clients/python/agenta_client/types/session_mount_query.py
  • clients/python/agenta_client/types/session_record.py
  • clients/python/agenta_client/types/session_response.py
  • clients/python/agenta_client/types/session_state.py
  • clients/python/agenta_client/types/session_state_data.py
  • clients/python/agenta_client/types/session_state_upsert_request.py
  • clients/python/agenta_client/types/session_stream.py
  • clients/python/agenta_client/types/session_stream_command_response.py
  • clients/python/agenta_client/types/session_stream_header_edit.py
  • clients/python/agenta_client/types/session_stream_response.py
  • clients/python/agenta_client/types/session_streams_response.py
  • clients/python/agenta_client/types/session_turn.py
  • clients/python/agenta_client/types/session_turn_query.py
  • clients/python/agenta_client/types/session_turn_response.py
  • clients/python/agenta_client/types/session_turns_response.py
  • clients/python/agenta_client/types/sessions_response.py
  • clients/python/agenta_client/types/span_input.py
  • clients/python/agenta_client/types/span_output.py
  • clients/python/agenta_client/types/spans_node_input.py
  • clients/python/agenta_client/types/spans_node_output.py
  • clients/python/agenta_client/types/workflow_request_data.py
  • docs/docs/self-host/reference/01-configuration.mdx
  • hosting/docker-compose/ee/docker-compose.dev.yml
  • hosting/docker-compose/ee/docker-compose.gh.yml
  • hosting/docker-compose/oss/docker-compose.dev.yml
  • hosting/docker-compose/oss/docker-compose.gh.yml
  • hosting/kubernetes/helm/templates/api-deployment.yaml
  • sdks/python/agenta/sdk/agents/__init__.py
  • sdks/python/agenta/sdk/agents/adapters/harnesses.py
  • sdks/python/agenta/sdk/agents/adapters/local.py
  • sdks/python/agenta/sdk/agents/adapters/sandbox_agent.py
  • sdks/python/agenta/sdk/agents/dtos.py
  • sdks/python/agenta/sdk/agents/errors.py
  • sdks/python/agenta/sdk/agents/interfaces.py
  • sdks/python/agenta/sdk/agents/utils/wire.py
  • sdks/python/agenta/sdk/engines/tracing/tracing.py
  • sdks/python/agenta/sdk/middlewares/running/normalizer.py
  • sdks/python/agenta/sdk/models/tracing.py
  • sdks/python/oss/tests/pytest/integration/agents/_fake_runner_backend.py
  • sdks/python/oss/tests/pytest/integration/agents/_qa_transcripts.py
  • sdks/python/oss/tests/pytest/unit/agents/conftest.py
  • sdks/python/oss/tests/pytest/unit/agents/connections/test_dtos_model_ref.py
  • sdks/python/oss/tests/pytest/unit/agents/skills/test_skills_e2e.py
  • sdks/python/oss/tests/pytest/unit/agents/test_agent_composition_seam.py
  • sdks/python/oss/tests/pytest/unit/agents/test_dtos_capabilities_events.py
  • sdks/python/oss/tests/pytest/unit/agents/test_environment_lifecycle.py
  • sdks/python/oss/tests/pytest/unit/agents/test_harness_adapters.py
  • sdks/python/oss/tests/pytest/unit/agents/test_harness_identity.py
  • sdks/python/oss/tests/pytest/unit/agents/test_wire_contract.py
  • sdks/python/oss/tests/pytest/unit/test_batch_fold_stream_contract_routing.py
  • sdks/python/oss/tests/pytest/unit/test_invoke_real_handlers_negotiation_routing.py
  • sdks/python/oss/tests/pytest/unit/test_normalizer_passthrough.py
  • sdks/python/oss/tests/pytest/unit/test_tracing_store_agent.py
  • services/oss/tests/pytest/unit/agent/conftest.py
  • web/oss/src/components/SessionInspector/api.ts
  • web/packages/agenta-entities/src/session/api/api.ts
  • web/packages/agenta-entities/src/session/core/liveness.ts
  • web/packages/agenta-entities/src/session/core/schema.ts
  • web/packages/agenta-entities/src/session/index.ts
💤 Files with no reviewable changes (17)
  • api/oss/tests/pytest/acceptance/session_states/test_harness_sessions_roundtrip.py
  • api/oss/tests/pytest/unit/session_states/test_harness_sessions_mapping.py
  • api/oss/src/core/sessions/states/dtos.py
  • web/packages/agenta-entities/src/session/core/schema.ts
  • clients/python/agenta_client/types/session_state.py
  • api/oss/src/dbs/postgres/sessions/states/mappings.py
  • api/oss/src/dbs/postgres/sessions/states/dbes.py
  • api/oss/src/dbs/postgres/sessions/states/dao.py
  • api/oss/src/core/sessions/states/service.py
  • api/oss/databases/postgres/migrations/core/env.py
  • clients/python/agenta_client/types/harness_session_record.py
  • clients/python/agenta_client/types/session_state_data.py
  • web/packages/agenta-entities/src/session/index.ts
  • clients/python/agenta_client/types/session_state_upsert_request.py
  • api/oss/tests/pytest/unit/session_states/test_session_id_validation.py
  • api/oss/src/core/sessions/states/interfaces.py
  • api/oss/tests/pytest/acceptance/session_states/test_session_states_basics.py
🚧 Files skipped from review as they are similar to previous changes (140)
  • clients/python/agenta_client/types/session_mount.py
  • clients/python/agenta_client/types/harness_kind.py
  • api/oss/databases/postgres/migrations/tracing_oss/versions/oss000000003_add_span_identity_columns.py
  • clients/python/agenta_client/types/session_heartbeat_result.py
  • api/oss/src/dbs/postgres/sessions/records/mappings.py
  • hosting/docker-compose/ee/docker-compose.dev.yml
  • hosting/kubernetes/helm/templates/api-deployment.yaml
  • clients/python/agenta_client/types/session_streams_response.py
  • api/oss/src/core/sessions/interactions/service.py
  • api/oss/src/core/sessions/dtos.py
  • api/oss/tests/pytest/unit/sessions/test_mounts_agent_id_backfill.py
  • api/oss/src/apis/fastapi/otlp/extractors/span_data_builders.py
  • clients/python/agenta_client/types/mount_query.py
  • sdks/python/oss/tests/pytest/unit/test_tracing_store_agent.py
  • api/oss/src/apis/fastapi/otlp/extractors/canonical_attributes.py
  • clients/python/agenta_client/types/spans_node_output.py
  • api/oss/src/core/sessions/interactions/interfaces.py
  • clients/python/agenta_client/types/mount_create.py
  • api/oss/src/dbs/postgres/sessions/turns/dbes.py
  • sdks/python/oss/tests/pytest/unit/agents/connections/test_dtos_model_ref.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000015_add_session_streams_header.py
  • api/oss/src/dbs/postgres/tracing/dbes.py
  • api/oss/tests/pytest/acceptance/sessions/test_stream_header_roundtrip.py
  • clients/python/agenta_client/types/session_turn_query.py
  • api/oss/src/dbs/postgres/sessions/records/dbas.py
  • api/oss/src/core/mounts/interfaces.py
  • web/oss/src/components/SessionInspector/api.ts
  • sdks/python/oss/tests/pytest/unit/test_invoke_real_handlers_negotiation_routing.py
  • clients/python/agenta_client/types/session_turns_response.py
  • clients/python/agenta_client/types/sessions_response.py
  • clients/python/agenta_client/types/session_stream_response.py
  • sdks/python/oss/tests/pytest/unit/test_batch_fold_stream_contract_routing.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000016_add_mounts_agent_id.py
  • hosting/docker-compose/oss/docker-compose.dev.yml
  • api/oss/src/core/mounts/dtos.py
  • web/packages/agenta-entities/src/session/core/liveness.ts
  • api/pyproject.toml
  • clients/python/agenta_client/types/session_stream_header_edit.py
  • api/oss/src/dbs/postgres/sessions/turns/utils.py
  • sdks/python/agenta/sdk/agents/adapters/sandbox_agent.py
  • clients/python/agenta_client/types/workflow_request_data.py
  • sdks/python/oss/tests/pytest/unit/test_normalizer_passthrough.py
  • api/oss/src/core/sessions/interactions/dtos.py
  • sdks/python/agenta/sdk/engines/tracing/tracing.py
  • api/oss/src/dbs/postgres/tracing/mappings.py
  • clients/python/agenta_client/types/session_stream_command_response.py
  • clients/python/agenta_client/types/span_input.py
  • clients/python/agenta_client/types/session_mount_query.py
  • api/oss/tests/pytest/acceptance/sessions/test_archive_unarchive.py
  • sdks/python/oss/tests/pytest/integration/agents/_qa_transcripts.py
  • sdks/python/oss/tests/pytest/unit/agents/test_agent_composition_seam.py
  • clients/python/agenta_client/types/session_turn.py
  • api/oss/src/dbs/postgres/mounts/dbes.py
  • sdks/python/agenta/sdk/agents/interfaces.py
  • hosting/docker-compose/ee/docker-compose.gh.yml
  • clients/python/agenta_client/types/spans_node_input.py
  • api/oss/src/dbs/postgres/tracing/utils.py
  • api/oss/src/apis/fastapi/mounts/utils.py
  • api/oss/tests/pytest/unit/sessions/conftest.py
  • api/oss/src/core/shared/dtos.py
  • api/oss/tests/pytest/unit/tracing/test_dao_ingest_identity_columns.py
  • api/oss/src/dbs/postgres/sessions/streams/mappings.py
  • sdks/python/agenta/sdk/agents/init.py
  • api/oss/tests/pytest/acceptance/sessions/test_stream_header_basics.py
  • api/oss/tests/pytest/unit/otlp/test_logfire_adapter.py
  • api/oss/src/dbs/postgres/mounts/dbas.py
  • clients/python/agenta_client/types/session_stream.py
  • api/oss/src/core/sessions/turns/types.py
  • api/oss/src/dbs/postgres/sessions/turns/dbas.py
  • api/oss/src/core/sessions/turns/interfaces.py
  • sdks/python/oss/tests/pytest/integration/agents/_fake_runner_backend.py
  • sdks/python/agenta/sdk/middlewares/running/normalizer.py
  • api/oss/src/dbs/postgres/sessions/records/dbes.py
  • clients/python/agenta_client/mounts/raw_client.py
  • api/oss/tests/pytest/acceptance/sessions/test_records_ingest_contract.py
  • api/oss/tests/pytest/unit/mounts/test_agent_mounts.py
  • hosting/docker-compose/oss/docker-compose.gh.yml
  • sdks/python/oss/tests/pytest/unit/agents/test_environment_lifecycle.py
  • api/oss/src/dbs/postgres/sessions/interactions/dao.py
  • sdks/python/agenta/sdk/agents/utils/wire.py
  • api/oss/tests/pytest/unit/mounts/test_agent_id_backfill.py
  • clients/python/agenta_client/types/session_turn_response.py
  • api/oss/src/dbs/postgres/sessions/streams/dbes.py
  • api/oss/src/dbs/postgres/tracing/dao.py
  • api/oss/src/core/sessions/turns/dtos.py
  • sdks/python/agenta/sdk/agents/adapters/local.py
  • sdks/python/oss/tests/pytest/unit/agents/conftest.py
  • api/oss/tests/pytest/unit/sessions/test_wp5_mount_teardown.py
  • api/oss/src/dbs/postgres/mounts/dao.py
  • sdks/python/agenta/sdk/agents/adapters/harnesses.py
  • clients/python/agenta_client/types/session_record.py
  • api/oss/tests/pytest/unit/sessions/test_record_ingest_endpoint.py
  • api/oss/tests/pytest/unit/sessions/test_records_mapping_upsert.py
  • api/oss/src/core/tracing/dtos.py
  • clients/python/agenta_client/types/session_interaction.py
  • sdks/python/oss/tests/pytest/unit/agents/test_dtos_capabilities_events.py
  • api/oss/src/dbs/postgres/tracing/dbas.py
  • sdks/python/agenta/sdk/models/tracing.py
  • api/oss/src/apis/fastapi/mounts/router.py
  • api/oss/src/dbs/postgres/mounts/mappings.py
  • docs/docs/self-host/reference/01-configuration.mdx
  • api/oss/src/core/sessions/streams/runner_client.py
  • sdks/python/agenta/sdk/agents/errors.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000014_add_session_turns.py
  • api/oss/src/core/tracing/utils/filtering.py
  • api/oss/src/core/tracing/utils/trees.py
  • clients/python/agenta_client/types/mount.py
  • api/oss/src/core/sessions/service.py
  • services/oss/tests/pytest/unit/agent/conftest.py
  • api/oss/tests/pytest/unit/tracing/utils/test_trees.py
  • api/oss/src/core/sessions/records/dtos.py
  • api/oss/tests/pytest/unit/sessions/test_heartbeat_is_current_turn.py
  • api/oss/src/dbs/postgres/sessions/turns/dao.py
  • sdks/python/oss/tests/pytest/unit/agents/test_harness_adapters.py
  • api/oss/src/apis/fastapi/otlp/extractors/adapters/logfire_adapter.py
  • clients/python/agenta_client/types/init.py
  • api/oss/tests/pytest/unit/sessions/test_kill_runner_teardown.py
  • api/oss/tests/pytest/unit/sessions/test_sessions_root_service.py
  • api/oss/src/core/tracing/service.py
  • api/oss/tests/pytest/unit/sessions/test_stream_header_merge.py
  • api/oss/src/core/sessions/streams/interfaces.py
  • api/oss/src/utils/env.py
  • api/oss/tests/pytest/unit/sessions/test_records_turn_span_dao.py
  • api/oss/src/dbs/postgres/sessions/turns/mappings.py
  • api/oss/src/dbs/postgres/sessions/streams/dao.py
  • sdks/python/agenta/sdk/agents/dtos.py
  • api/oss/tests/pytest/unit/sessions/test_command_matrix_inputs_data.py
  • sdks/python/oss/tests/pytest/unit/agents/test_wire_contract.py
  • api/oss/src/apis/fastapi/sessions/models.py
  • clients/python/agenta_client/mounts/client.py
  • api/oss/src/core/sessions/streams/dtos.py
  • api/oss/tests/pytest/unit/sessions/test_wp5_dao_fanout.py
  • api/oss/src/core/sessions/turns/service.py
  • api/oss/tests/pytest/unit/sessions/test_wp5_root_router.py
  • api/entrypoints/routers.py
  • api/oss/src/core/sessions/streams/service.py
  • api/oss/tests/pytest/unit/sessions/test_turns_dao.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000017_drop_session_states.py
  • clients/python/agenta_client/sessions/client.py
  • api/oss/src/apis/fastapi/sessions/router.py

Comment on lines +395 to +402
if self.mounts_store is not None and self.bucket:
for mount in mounts:
prefix = self._storage_key(project_id=project_id, mount=mount)
await self.mounts_store.delete_prefix(
bucket=self.bucket,
prefix=prefix,
)
return mounts

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Uncaught external call failures in a teardown flow.

If mounts_store.delete_prefix fails (e.g., due to a network timeout or missing permissions), the exception will propagate and halt the delete_session_mounts execution. Because this is called sequentially within the delete_session orchestration before streams_service.hard_delete, a failure here will prevent the streams row from being deleted, leaving a partially-deleted (zombie) session in the database.

Consider wrapping the external call in a try...except block and logging the error so the database deletion can complete, and/or use asyncio.gather(..., return_exceptions=True) to process multiple prefixes concurrently without failing the entire operation.

🛡️ Proposed defensive fix
+        import logging
         if self.mounts_store is not None and self.bucket:
             for mount in mounts:
                 prefix = self._storage_key(project_id=project_id, mount=mount)
-                await self.mounts_store.delete_prefix(
-                    bucket=self.bucket,
-                    prefix=prefix,
-                )
+                try:
+                    await self.mounts_store.delete_prefix(
+                        bucket=self.bucket,
+                        prefix=prefix,
+                    )
+                except Exception as e:
+                    logging.error("Failed to delete object store prefix %s for mount %s: %s", prefix, mount.id, e)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if self.mounts_store is not None and self.bucket:
for mount in mounts:
prefix = self._storage_key(project_id=project_id, mount=mount)
await self.mounts_store.delete_prefix(
bucket=self.bucket,
prefix=prefix,
)
return mounts
import logging
if self.mounts_store is not None and self.bucket:
for mount in mounts:
prefix = self._storage_key(project_id=project_id, mount=mount)
try:
await self.mounts_store.delete_prefix(
bucket=self.bucket,
prefix=prefix,
)
except Exception as e:
logging.error("Failed to delete object store prefix %s for mount %s: %s", prefix, mount.id, e)
return mounts

@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Railway Preview Environment

Preview URL https://gateway-production-fb80.up.railway.app/w
Project agenta-oss-pr-5375
Image tag pr-5375-4095ce6
Status Deployed
Railway logs Open logs
Workflow logs View workflow run
Updated at 2026-07-19T18:28:02.182Z

@mmabrouk

Copy link
Copy Markdown
Member Author

Decision from Mahmoud (2026-07-19) on the migration-017 question flagged in this PR: discarding the old session_states rows is approved. Nothing reads that table after the switch, so no conversion step is needed. The migration stands as written. (The other flagged item, the apply_windowing cursor choice for turns, remains JP's call.)

mmabrouk added 3 commits July 19, 2026 20:14
Rebases the backend two-thirds of JP's feat/sessions-extensions (PR #5363)
onto current main (v0.105.5). Covers api, SDK, Fern python client, and the
web generated client: the append-only session_turns domain replacing
session_states, the stream command discriminator rename (prompt -> inputs/data),
the root /sessions router and SessionsService, /kill teardown wiring, span
identity columns plus ag.agent.id, and mounts agent_id.

Ported from feat/sessions-extensions@1532ec7fe5 (JP).

Reconciliations with the release main:
- Kept main's pi-openai model_ref threading (PiHarness/AgentaHarness) and the
  EndpointResolutionError export alongside JP's HarnessType -> HarnessKind rename.
- Kept main's 0.105.5 version in api/pyproject.toml while re-adding JP's
  greenlet dependency; api/uv.lock updated for greenlet only.
- Kept main's sdks/python and services uv.lock (JP's were stale transitive bumps).

Claude-Session: https://claude.ai/code/session_01DnWRxU3dCJ11hgDidm26vW
The record-ingest span_id is an OpenTelemetry span id (64-bit / 16 hex chars),
not a UUID (128-bit / 32 hex). Typed as Optional[UUID], pydantic rejected every
runner ingest with a 422 and session records silently dropped. Model it as what
it is end to end: a validated 16-hex string (OTelSpanId) on the API model, core
DTOs, and DAO column; varchar in the two unreleased migrations. trace_id stays
UUID (genuinely the 32-hex OTel trace id). Adds contract + backfill + multi-turn
tests.

Claude-Session: https://claude.ai/code/session_01DnWRxU3dCJ11hgDidm26vW

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
clients/python/agenta_client/__init__.py (1)

23-41: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Invalid typing.Any elements in _dynamic_imports and __all__.

Both files contain unquoted typing.Any objects instead of strings in the __all__ lists and _dynamic_imports keys. In Python, __all__ must be a sequence of strings; including non-string objects causes a TypeError when from module import * is executed. Additionally, using typing.Any as a dictionary key repeatedly causes prior entries to be overwritten, breaking lazy imports and static analysis. This is likely a generator configuration issue where certain schemas (e.g., FullJsonInput, LabelJsonOutput) resolve to Any and are written verbatim.

  • clients/python/agenta_client/__init__.py#L23-L41: Fix the generator config or OpenAPI spec so that valid string aliases are produced instead of typing.Any.
  • clients/python/agenta_client/types/__init__.py#L779-L797: Update the generator configuration to avoid leaking typing.Any into _dynamic_imports and __all__ here as well.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1d493f9c-d17c-4a92-9730-cf62e98788f7

📥 Commits

Reviewing files that changed from the base of the PR and between 573e236 and 494cdd7.

⛔ Files ignored due to path filters (49)
  • api/uv.lock is excluded by !**/*.lock
  • web/packages/agenta-api-client/src/generated/api/resources/mounts/client/Client.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/mounts/client/requests/MountQueryRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/Client.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/ArchiveSessionRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/DeleteSessionRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/FetchTurnRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionDetachRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionHeartbeatRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionQueryRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionRecordIngestRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionStreamCommandRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionStreamQueryRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionTurnAppendRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SessionTurnQueryRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/SetSessionStreamHeaderRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/UnarchiveSessionRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/resources/sessions/client/requests/index.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/CommandMode.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/HarnessKind.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/HarnessSessionRecord.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/Mount.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/MountCreate.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/MountQuery.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionHeartbeatResponseModel.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionHeartbeatResult.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionInteraction.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionMount.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionMountQuery.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionRecord.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionState.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStateData.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStateFlags.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStateUpsertRequest.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStream.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStreamCommandResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStreamHeaderEdit.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStreamResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionStreamsResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionTurn.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionTurnQuery.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionTurnResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionTurnsResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SessionsResponse.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SpanInput.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SpanOutput.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SpansNodeInput.ts is excluded by !**/generated/**
  • web/packages/agenta-api-client/src/generated/api/types/SpansNodeOutput.ts is excluded by !**/generated/**
📒 Files selected for processing (171)
  • api/entrypoints/routers.py
  • api/oss/databases/postgres/migrations/core/env.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000014_add_session_turns.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000015_add_session_streams_header.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000016_add_mounts_agent_id.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000017_drop_session_states.py
  • api/oss/databases/postgres/migrations/tracing_oss/versions/oss000000003_add_span_identity_columns.py
  • api/oss/databases/postgres/migrations/tracing_oss/versions/oss000000004_add_records_turn_span.py
  • api/oss/src/apis/fastapi/mounts/router.py
  • api/oss/src/apis/fastapi/mounts/utils.py
  • api/oss/src/apis/fastapi/otlp/extractors/adapters/logfire_adapter.py
  • api/oss/src/apis/fastapi/otlp/extractors/canonical_attributes.py
  • api/oss/src/apis/fastapi/otlp/extractors/span_data_builders.py
  • api/oss/src/apis/fastapi/otlp/utils/serialization.py
  • api/oss/src/apis/fastapi/sessions/models.py
  • api/oss/src/apis/fastapi/sessions/router.py
  • api/oss/src/apis/fastapi/tracing/router.py
  • api/oss/src/core/mounts/dtos.py
  • api/oss/src/core/mounts/interfaces.py
  • api/oss/src/core/mounts/service.py
  • api/oss/src/core/sessions/dtos.py
  • api/oss/src/core/sessions/interactions/dtos.py
  • api/oss/src/core/sessions/interactions/interfaces.py
  • api/oss/src/core/sessions/interactions/service.py
  • api/oss/src/core/sessions/records/dtos.py
  • api/oss/src/core/sessions/service.py
  • api/oss/src/core/sessions/states/dtos.py
  • api/oss/src/core/sessions/states/interfaces.py
  • api/oss/src/core/sessions/states/service.py
  • api/oss/src/core/sessions/streams/dtos.py
  • api/oss/src/core/sessions/streams/interfaces.py
  • api/oss/src/core/sessions/streams/runner_client.py
  • api/oss/src/core/sessions/streams/service.py
  • api/oss/src/core/sessions/turns/__init__.py
  • api/oss/src/core/sessions/turns/dtos.py
  • api/oss/src/core/sessions/turns/interfaces.py
  • api/oss/src/core/sessions/turns/service.py
  • api/oss/src/core/sessions/turns/types.py
  • api/oss/src/core/shared/dtos.py
  • api/oss/src/core/tracing/dtos.py
  • api/oss/src/core/tracing/service.py
  • api/oss/src/core/tracing/utils/filtering.py
  • api/oss/src/core/tracing/utils/trees.py
  • api/oss/src/dbs/postgres/mounts/dao.py
  • api/oss/src/dbs/postgres/mounts/dbas.py
  • api/oss/src/dbs/postgres/mounts/dbes.py
  • api/oss/src/dbs/postgres/mounts/mappings.py
  • api/oss/src/dbs/postgres/sessions/interactions/dao.py
  • api/oss/src/dbs/postgres/sessions/records/dao.py
  • api/oss/src/dbs/postgres/sessions/records/dbas.py
  • api/oss/src/dbs/postgres/sessions/records/dbes.py
  • api/oss/src/dbs/postgres/sessions/records/mappings.py
  • api/oss/src/dbs/postgres/sessions/states/dao.py
  • api/oss/src/dbs/postgres/sessions/states/dbes.py
  • api/oss/src/dbs/postgres/sessions/states/mappings.py
  • api/oss/src/dbs/postgres/sessions/streams/dao.py
  • api/oss/src/dbs/postgres/sessions/streams/dbes.py
  • api/oss/src/dbs/postgres/sessions/streams/mappings.py
  • api/oss/src/dbs/postgres/sessions/turns/__init__.py
  • api/oss/src/dbs/postgres/sessions/turns/dao.py
  • api/oss/src/dbs/postgres/sessions/turns/dbas.py
  • api/oss/src/dbs/postgres/sessions/turns/dbes.py
  • api/oss/src/dbs/postgres/sessions/turns/mappings.py
  • api/oss/src/dbs/postgres/sessions/turns/utils.py
  • api/oss/src/dbs/postgres/tracing/dao.py
  • api/oss/src/dbs/postgres/tracing/dbas.py
  • api/oss/src/dbs/postgres/tracing/dbes.py
  • api/oss/src/dbs/postgres/tracing/mappings.py
  • api/oss/src/dbs/postgres/tracing/utils.py
  • api/oss/src/utils/env.py
  • api/oss/tests/pytest/acceptance/session_states/test_harness_sessions_roundtrip.py
  • api/oss/tests/pytest/acceptance/session_states/test_session_states_basics.py
  • api/oss/tests/pytest/acceptance/sessions/__init__.py
  • api/oss/tests/pytest/acceptance/sessions/test_archive_unarchive.py
  • api/oss/tests/pytest/acceptance/sessions/test_records_ingest_contract.py
  • api/oss/tests/pytest/acceptance/sessions/test_stream_header_basics.py
  • api/oss/tests/pytest/acceptance/sessions/test_stream_header_roundtrip.py
  • api/oss/tests/pytest/unit/mounts/test_agent_id_backfill.py
  • api/oss/tests/pytest/unit/mounts/test_agent_mounts.py
  • api/oss/tests/pytest/unit/otlp/test_logfire_adapter.py
  • api/oss/tests/pytest/unit/session_states/__init__.py
  • api/oss/tests/pytest/unit/session_states/test_harness_sessions_mapping.py
  • api/oss/tests/pytest/unit/session_states/test_session_id_validation.py
  • api/oss/tests/pytest/unit/sessions/conftest.py
  • api/oss/tests/pytest/unit/sessions/test_command_matrix_inputs_data.py
  • api/oss/tests/pytest/unit/sessions/test_heartbeat_is_current_turn.py
  • api/oss/tests/pytest/unit/sessions/test_kill_runner_teardown.py
  • api/oss/tests/pytest/unit/sessions/test_mounts_agent_id_backfill.py
  • api/oss/tests/pytest/unit/sessions/test_record_ingest_endpoint.py
  • api/oss/tests/pytest/unit/sessions/test_records_mapping_upsert.py
  • api/oss/tests/pytest/unit/sessions/test_records_turn_span_dao.py
  • api/oss/tests/pytest/unit/sessions/test_runner_client_kill.py
  • api/oss/tests/pytest/unit/sessions/test_sessions_root_service.py
  • api/oss/tests/pytest/unit/sessions/test_stream_header_merge.py
  • api/oss/tests/pytest/unit/sessions/test_turns_dao.py
  • api/oss/tests/pytest/unit/sessions/test_turns_dao_conflict.py
  • api/oss/tests/pytest/unit/sessions/test_wp5_dao_fanout.py
  • api/oss/tests/pytest/unit/sessions/test_wp5_mount_teardown.py
  • api/oss/tests/pytest/unit/sessions/test_wp5_root_router.py
  • api/oss/tests/pytest/unit/tracing/test_dao_ingest_identity_columns.py
  • api/oss/tests/pytest/unit/tracing/utils/test_trees.py
  • api/pyproject.toml
  • clients/python/agenta_client/__init__.py
  • clients/python/agenta_client/mounts/client.py
  • clients/python/agenta_client/mounts/raw_client.py
  • clients/python/agenta_client/sessions/client.py
  • clients/python/agenta_client/sessions/raw_client.py
  • clients/python/agenta_client/types/__init__.py
  • clients/python/agenta_client/types/harness_kind.py
  • clients/python/agenta_client/types/harness_session_record.py
  • clients/python/agenta_client/types/mount.py
  • clients/python/agenta_client/types/mount_create.py
  • clients/python/agenta_client/types/mount_query.py
  • clients/python/agenta_client/types/session_heartbeat_result.py
  • clients/python/agenta_client/types/session_interaction.py
  • clients/python/agenta_client/types/session_mount.py
  • clients/python/agenta_client/types/session_mount_query.py
  • clients/python/agenta_client/types/session_record.py
  • clients/python/agenta_client/types/session_response.py
  • clients/python/agenta_client/types/session_state.py
  • clients/python/agenta_client/types/session_state_data.py
  • clients/python/agenta_client/types/session_state_upsert_request.py
  • clients/python/agenta_client/types/session_stream.py
  • clients/python/agenta_client/types/session_stream_command_response.py
  • clients/python/agenta_client/types/session_stream_header_edit.py
  • clients/python/agenta_client/types/session_stream_response.py
  • clients/python/agenta_client/types/session_streams_response.py
  • clients/python/agenta_client/types/session_turn.py
  • clients/python/agenta_client/types/session_turn_query.py
  • clients/python/agenta_client/types/session_turn_response.py
  • clients/python/agenta_client/types/session_turns_response.py
  • clients/python/agenta_client/types/sessions_response.py
  • clients/python/agenta_client/types/span_input.py
  • clients/python/agenta_client/types/span_output.py
  • clients/python/agenta_client/types/spans_node_input.py
  • clients/python/agenta_client/types/spans_node_output.py
  • clients/python/agenta_client/types/workflow_request_data.py
  • docs/docs/self-host/reference/01-configuration.mdx
  • hosting/docker-compose/ee/docker-compose.dev.yml
  • hosting/docker-compose/ee/docker-compose.gh.yml
  • hosting/docker-compose/oss/docker-compose.dev.yml
  • hosting/docker-compose/oss/docker-compose.gh.yml
  • hosting/kubernetes/helm/templates/api-deployment.yaml
  • sdks/python/agenta/sdk/agents/__init__.py
  • sdks/python/agenta/sdk/agents/adapters/harnesses.py
  • sdks/python/agenta/sdk/agents/adapters/local.py
  • sdks/python/agenta/sdk/agents/adapters/sandbox_agent.py
  • sdks/python/agenta/sdk/agents/dtos.py
  • sdks/python/agenta/sdk/agents/errors.py
  • sdks/python/agenta/sdk/agents/interfaces.py
  • sdks/python/agenta/sdk/agents/utils/wire.py
  • sdks/python/agenta/sdk/engines/tracing/tracing.py
  • sdks/python/agenta/sdk/middlewares/running/normalizer.py
  • sdks/python/agenta/sdk/models/tracing.py
  • sdks/python/oss/tests/pytest/integration/agents/_fake_runner_backend.py
  • sdks/python/oss/tests/pytest/integration/agents/_qa_transcripts.py
  • sdks/python/oss/tests/pytest/unit/agents/conftest.py
  • sdks/python/oss/tests/pytest/unit/agents/connections/test_dtos_model_ref.py
  • sdks/python/oss/tests/pytest/unit/agents/skills/test_skills_e2e.py
  • sdks/python/oss/tests/pytest/unit/agents/test_agent_composition_seam.py
  • sdks/python/oss/tests/pytest/unit/agents/test_dtos_capabilities_events.py
  • sdks/python/oss/tests/pytest/unit/agents/test_environment_lifecycle.py
  • sdks/python/oss/tests/pytest/unit/agents/test_harness_adapters.py
  • sdks/python/oss/tests/pytest/unit/agents/test_harness_identity.py
  • sdks/python/oss/tests/pytest/unit/agents/test_wire_contract.py
  • sdks/python/oss/tests/pytest/unit/test_batch_fold_stream_contract_routing.py
  • sdks/python/oss/tests/pytest/unit/test_invoke_real_handlers_negotiation_routing.py
  • sdks/python/oss/tests/pytest/unit/test_normalizer_passthrough.py
  • sdks/python/oss/tests/pytest/unit/test_tracing_store_agent.py
  • services/oss/tests/pytest/unit/agent/conftest.py
  • web/oss/src/components/SessionInspector/api.ts
💤 Files with no reviewable changes (15)
  • api/oss/tests/pytest/unit/session_states/test_session_id_validation.py
  • clients/python/agenta_client/types/session_state.py
  • clients/python/agenta_client/types/harness_session_record.py
  • api/oss/src/core/sessions/states/service.py
  • api/oss/tests/pytest/acceptance/session_states/test_harness_sessions_roundtrip.py
  • clients/python/agenta_client/types/session_state_upsert_request.py
  • clients/python/agenta_client/types/session_state_data.py
  • api/oss/tests/pytest/acceptance/session_states/test_session_states_basics.py
  • api/oss/src/dbs/postgres/sessions/states/mappings.py
  • api/oss/databases/postgres/migrations/core/env.py
  • api/oss/src/core/sessions/states/interfaces.py
  • api/oss/tests/pytest/unit/session_states/test_harness_sessions_mapping.py
  • api/oss/src/dbs/postgres/sessions/states/dbes.py
  • api/oss/src/dbs/postgres/sessions/states/dao.py
  • api/oss/src/core/sessions/states/dtos.py
🚧 Files skipped from review as they are similar to previous changes (133)
  • api/oss/src/apis/fastapi/otlp/utils/serialization.py
  • clients/python/agenta_client/types/harness_kind.py
  • hosting/kubernetes/helm/templates/api-deployment.yaml
  • api/oss/src/dbs/postgres/sessions/records/mappings.py
  • api/oss/src/dbs/postgres/sessions/records/dao.py
  • api/oss/src/core/sessions/dtos.py
  • api/oss/src/dbs/postgres/mounts/dbas.py
  • api/oss/src/core/sessions/interactions/interfaces.py
  • api/oss/tests/pytest/unit/sessions/test_mounts_agent_id_backfill.py
  • clients/python/agenta_client/types/session_stream_command_response.py
  • api/oss/src/core/mounts/interfaces.py
  • clients/python/agenta_client/types/session_stream_response.py
  • sdks/python/agenta/sdk/agents/init.py
  • api/oss/tests/pytest/unit/sessions/conftest.py
  • clients/python/agenta_client/types/session_mount_query.py
  • sdks/python/oss/tests/pytest/unit/test_batch_fold_stream_contract_routing.py
  • sdks/python/oss/tests/pytest/unit/agents/test_dtos_capabilities_events.py
  • sdks/python/agenta/sdk/agents/utils/wire.py
  • clients/python/agenta_client/types/session_heartbeat_result.py
  • api/oss/src/apis/fastapi/tracing/router.py
  • api/oss/src/apis/fastapi/otlp/extractors/span_data_builders.py
  • api/oss/src/core/sessions/interactions/service.py
  • api/oss/src/apis/fastapi/otlp/extractors/adapters/logfire_adapter.py
  • api/pyproject.toml
  • api/oss/databases/postgres/migrations/tracing_oss/versions/oss000000003_add_span_identity_columns.py
  • clients/python/agenta_client/types/session_interaction.py
  • api/oss/databases/postgres/migrations/tracing_oss/versions/oss000000004_add_records_turn_span.py
  • clients/python/agenta_client/types/session_streams_response.py
  • clients/python/agenta_client/types/workflow_request_data.py
  • sdks/python/oss/tests/pytest/unit/test_tracing_store_agent.py
  • clients/python/agenta_client/types/session_response.py
  • hosting/docker-compose/ee/docker-compose.dev.yml
  • api/oss/tests/pytest/acceptance/sessions/test_archive_unarchive.py
  • sdks/python/oss/tests/pytest/unit/agents/connections/test_dtos_model_ref.py
  • api/oss/src/dbs/postgres/sessions/turns/mappings.py
  • api/oss/src/dbs/postgres/tracing/dao.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000015_add_session_streams_header.py
  • api/oss/tests/pytest/acceptance/sessions/test_records_ingest_contract.py
  • clients/python/agenta_client/types/spans_node_output.py
  • sdks/python/agenta/sdk/models/tracing.py
  • api/oss/tests/pytest/unit/sessions/test_records_mapping_upsert.py
  • api/oss/src/apis/fastapi/otlp/extractors/canonical_attributes.py
  • api/oss/src/dbs/postgres/sessions/turns/dbas.py
  • clients/python/agenta_client/types/sessions_response.py
  • api/oss/src/dbs/postgres/mounts/mappings.py
  • clients/python/agenta_client/types/spans_node_input.py
  • clients/python/agenta_client/types/session_turn_query.py
  • clients/python/agenta_client/types/mount_query.py
  • sdks/python/agenta/sdk/agents/adapters/local.py
  • web/oss/src/components/SessionInspector/api.ts
  • hosting/docker-compose/oss/docker-compose.dev.yml
  • hosting/docker-compose/oss/docker-compose.gh.yml
  • clients/python/agenta_client/types/mount.py
  • api/oss/src/dbs/postgres/sessions/turns/dbes.py
  • api/oss/tests/pytest/unit/sessions/test_turns_dao_conflict.py
  • clients/python/agenta_client/types/mount_create.py
  • sdks/python/oss/tests/pytest/unit/agents/conftest.py
  • clients/python/agenta_client/mounts/client.py
  • clients/python/agenta_client/types/session_turns_response.py
  • api/oss/src/core/sessions/turns/dtos.py
  • services/oss/tests/pytest/unit/agent/conftest.py
  • api/oss/tests/pytest/acceptance/sessions/test_stream_header_roundtrip.py
  • api/oss/src/core/sessions/turns/interfaces.py
  • api/oss/src/core/mounts/dtos.py
  • api/oss/tests/pytest/acceptance/sessions/test_stream_header_basics.py
  • docs/docs/self-host/reference/01-configuration.mdx
  • api/oss/src/utils/env.py
  • api/oss/src/core/shared/dtos.py
  • api/oss/src/dbs/postgres/tracing/mappings.py
  • sdks/python/oss/tests/pytest/integration/agents/_qa_transcripts.py
  • api/oss/tests/pytest/unit/tracing/utils/test_trees.py
  • clients/python/agenta_client/types/session_turn.py
  • sdks/python/oss/tests/pytest/unit/agents/test_environment_lifecycle.py
  • api/oss/src/dbs/postgres/tracing/dbas.py
  • api/oss/src/apis/fastapi/mounts/router.py
  • clients/python/agenta_client/types/session_record.py
  • sdks/python/oss/tests/pytest/unit/agents/test_harness_identity.py
  • sdks/python/agenta/sdk/agents/adapters/sandbox_agent.py
  • api/oss/src/dbs/postgres/sessions/records/dbes.py
  • api/oss/tests/pytest/unit/sessions/test_records_turn_span_dao.py
  • api/oss/src/dbs/postgres/sessions/streams/dbes.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000014_add_session_turns.py
  • clients/python/agenta_client/types/span_input.py
  • api/oss/src/core/sessions/streams/runner_client.py
  • sdks/python/agenta/sdk/engines/tracing/tracing.py
  • sdks/python/oss/tests/pytest/integration/agents/_fake_runner_backend.py
  • sdks/python/agenta/sdk/agents/adapters/harnesses.py
  • sdks/python/oss/tests/pytest/unit/agents/test_agent_composition_seam.py
  • api/oss/src/core/sessions/records/dtos.py
  • api/oss/tests/pytest/unit/sessions/test_wp5_dao_fanout.py
  • api/oss/src/dbs/postgres/sessions/interactions/dao.py
  • api/oss/tests/pytest/unit/sessions/test_heartbeat_is_current_turn.py
  • api/oss/src/apis/fastapi/mounts/utils.py
  • clients/python/agenta_client/types/session_mount.py
  • clients/python/agenta_client/mounts/raw_client.py
  • api/oss/tests/pytest/unit/tracing/test_dao_ingest_identity_columns.py
  • api/oss/tests/pytest/unit/sessions/test_wp5_mount_teardown.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000017_drop_session_states.py
  • api/oss/tests/pytest/unit/sessions/test_record_ingest_endpoint.py
  • api/oss/src/dbs/postgres/sessions/streams/mappings.py
  • api/oss/databases/postgres/migrations/core_oss/versions/oss000000016_add_mounts_agent_id.py
  • api/oss/tests/pytest/unit/sessions/test_wp5_root_router.py
  • api/oss/src/core/sessions/interactions/dtos.py
  • api/oss/src/dbs/postgres/mounts/dao.py
  • clients/python/agenta_client/types/session_turn_response.py
  • api/oss/tests/pytest/unit/sessions/test_sessions_root_service.py
  • sdks/python/oss/tests/pytest/unit/agents/test_harness_adapters.py
  • api/oss/tests/pytest/unit/mounts/test_agent_id_backfill.py
  • clients/python/agenta_client/types/session_stream_header_edit.py
  • api/oss/tests/pytest/unit/mounts/test_agent_mounts.py
  • api/oss/src/core/sessions/service.py
  • api/oss/src/core/tracing/service.py
  • sdks/python/agenta/sdk/agents/interfaces.py
  • api/oss/src/core/tracing/utils/trees.py
  • api/oss/tests/pytest/unit/sessions/test_kill_runner_teardown.py
  • api/oss/src/core/sessions/streams/interfaces.py
  • sdks/python/agenta/sdk/agents/dtos.py
  • api/oss/src/core/sessions/turns/service.py
  • api/oss/src/dbs/postgres/sessions/turns/dao.py
  • api/oss/tests/pytest/unit/sessions/test_command_matrix_inputs_data.py
  • sdks/python/oss/tests/pytest/unit/test_normalizer_passthrough.py
  • api/oss/tests/pytest/unit/otlp/test_logfire_adapter.py
  • sdks/python/oss/tests/pytest/unit/agents/test_wire_contract.py
  • api/oss/src/dbs/postgres/sessions/streams/dao.py
  • api/oss/src/core/mounts/service.py
  • api/oss/tests/pytest/unit/sessions/test_stream_header_merge.py
  • api/oss/src/apis/fastapi/sessions/models.py
  • api/oss/src/core/sessions/streams/service.py
  • api/oss/tests/pytest/unit/sessions/test_turns_dao.py
  • api/entrypoints/routers.py
  • api/oss/src/core/sessions/streams/dtos.py
  • api/oss/src/apis/fastapi/sessions/router.py
  • clients/python/agenta_client/sessions/client.py

Comment on lines +536 to +541
elif condition.field == Fields.SESSION_ID:
_parse_string_field_condition(condition)
elif condition.field == Fields.USER_ID:
_parse_string_field_condition(condition)
elif condition.field == Fields.AGENT_ID:
_parse_string_field_condition(condition)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use the actual field name in string-field validation errors.

These branches make _parse_string_field_condition() reachable for SESSION_ID, USER_ID, and AGENT_ID, but that helper hardcodes status_message in its error messages. Invalid filters for the new fields will therefore report the wrong field.

Proposed fix
-        "'status_message' only supports comparison, numeric, string, list, and existence operators.",
+        f"'{condition.field}' only supports comparison, numeric, string, list, and existence operators.",
...
-        "'status_message' value is required and thus never null for numeric, string, and list operators.",
+        f"'{condition.field}' value is required and thus never null for numeric, string, and list operators.",
...
-        "'status_message' value is not supported for existence operators.",
+        f"'{condition.field}' value is not supported for existence operators.",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
elif condition.field == Fields.SESSION_ID:
_parse_string_field_condition(condition)
elif condition.field == Fields.USER_ID:
_parse_string_field_condition(condition)
elif condition.field == Fields.AGENT_ID:
_parse_string_field_condition(condition)
f"'{condition.field}' only supports comparison, numeric, string, list, and existence operators.",
f"'{condition.field}' value is required and thus never null for numeric, string, and list operators.",
f"'{condition.field}' value is not supported for existence operators.",

Comment on lines +15 to +20
for reference in turn.references:
_key = reference.id or reference.slug
_references[_key] = reference.model_dump(
mode="json",
exclude_none=True,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Preserve reference versions during deduplication.

When id is absent, reference.id or reference.slug uses only the slug as the key. References such as the same slug at versions 1 and 2 therefore overwrite each other, causing the JSONB filter to omit one requested reference and return incorrect turns. Key by the complete (id, slug, version) identity or deduplicate only identical serialized dictionaries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Backend size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant