Skip to content

feat: add table for session inbound events - #805

Open
heerambavi1998 wants to merge 13 commits into
mainfrom
ha/inbox
Open

heerambavi1998 wants to merge 13 commits into
mainfrom
ha/inbox

Conversation

@heerambavi1998

@heerambavi1998 heerambavi1998 commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Summary

add table for session inbound events

Changes

durable session_inbound_events inbox + ISessionStore API (Postgres / SQLite / InMemory) for the upcoming session send-event path.

Table: session_inbound_events
PK: (session_id, event_id) — caller-minted monotonic ULID (same contract as session_event)
turn_id column is nullable (reserved for future session-scoped policies)
No idempotency_key, we will add this later if needed.
Event
SendTurnEventItem = user.tool_approval | user.tool_response. We will add approval policies later.

Store

insertSessionInboundEvents / listUnconsumedSessionInboundEvents / markSessionInboundEventsConsumed
Duplicate event_id → SessionInboundEventAlreadyExistsError
Cascades with deleteSession

How was this tested?

Store contract tests.

Checklist

  • I have read the contributing guidelines
  • pnpm build, pnpm test, pnpm typecheck, pnpm lint:ci, and pnpm format:check pass locally
  • Tests added/updated where it makes sense
  • No hand-edits to generated code (packages/trueforge-sdk, python/trueforge_sdk, .github/fern/openapi/openapi.json, docs/openapi.json) — fork PRs omit SDK regen; maintainers regenerate after merge
  • Docs / .env.example updated if configuration or behavior changed

Note

Medium Risk
Adds session-store schema and write paths on the agent turn lifecycle with concurrency checks; no public HTTP surface yet, but incorrect consumption semantics could affect upcoming HITL flows.

Overview
Introduces a turn-scoped durable inbox for client→harness send events during the active tip (tool approvals/responses), separate from the turn event stream log.

Store contract: ISessionStore gains insertTurnInboundEvents, listUnconsumedTurnInboundEvents, and markTurnInboundEventsConsumed. Payloads are validated TurnInboundEventItem (user.tool_approval | user.tool_response). Inserts require a running tip; duplicate caller-minted event_id per (session_id, turn_id) raises TurnEventAlreadyExistsError. Listing returns unconsumed rows ordered by event_id; mark-consumed is idempotent for unknown/already-consumed ids.

Persistence: New turn_inbound_events table (PK session_id, turn_id, event_id, consumed, partial index for unconsumed) with Postgres and SQLite migrations, wired through InMemory, Postgres, and SQLite session stores (transaction + assertTurnRunning on insert). Rows cascade on session delete.

Tests: Shared store contract suite covers ordering, duplicates, terminal-turn rejection, turn isolation, session delete, and a freeze-vs-insert race.

OpenAPI package version bumps to 0.2.1; no new HTTP routes in this diff (store-only groundwork for a future POST …/turns/{turn_id}/events path).

Reviewed by Cursor Bugbot for commit 3c19e60. Bugbot is set up for automated code reviews on this repo. Configure here.

@changeset-bot

changeset-bot Bot commented Sep 18, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3c19e60

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@truefoundry/trueforge-core Patch
@truefoundry/trueforge Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@cursor cursor 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.

Stale Bugbot comment from a previous run.

Comment thread .changeset/session-inbound-events.md Outdated
@heerambavi1998
heerambavi1998 added this pull request to stack #808 September 18, 2026 09:40

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 3c19e60. Configure here.

.where('event_id', 'in', ids)
.execute();
return firstCollidingEventId(events, new Set(rows.map(r => r.event_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.

Positional string helper parameters

Low Severity

resolveCollidingEventId takes sessionId and turnId as two positional strings. New functions with more than one parameter of the same type need a single options object. A TurnKeys object is already built in the same insert path for assertTurnRunning.

Additional Locations (1)
Fix in Cursor Fix in Web

Triggered by project rule: TrueForge review rules

Reviewed by Cursor Bugbot for commit 3c19e60. Configure here.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant