Repository navigation
feat(ai-harness): session lifecycle with handles, observe, retention, host plugins, and a purging delete - #1813
AlemTuzlak wants to merge 14 commits into
Conversation
…tion, the feed, and the log tail
…ession handles with idle close and maxOpen
… and OAuth cancel
…iew, and read routes on it
…ce per host, and delete that purges a thread
|
| Name | Type |
|---|---|
| @tanstack/ai-harness-cli | Minor |
| @tanstack/ai-harness | Minor |
| @tanstack/ai-mcp | Minor |
| @tanstack/ai-acp | Minor |
| @tanstack/ai-code-mode | Patch |
| @tanstack/ai-sandbox | Patch |
| @tanstack/ai-skills | Patch |
| @tanstack/ai-grok-build | Patch |
Click here to learn what changesets are, and how to add one.
Click here if you're a maintainer who wants to add a changeset to this PR
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
|
View your CI Pipeline Execution ↗ for commit 2123a0f
☁️ Nx Cloud last updated this comment at |
@tanstack/ai
@tanstack/ai-acp
@tanstack/ai-angular
@tanstack/ai-anthropic
@tanstack/ai-bedrock
@tanstack/ai-byteplus
@tanstack/ai-claude-code
@tanstack/ai-client
@tanstack/ai-cloudflare
@tanstack/ai-code-mode
@tanstack/ai-code-mode-snippets
@tanstack/ai-codex
@tanstack/ai-cohere
@tanstack/ai-compaction
@tanstack/ai-devtools-core
@tanstack/ai-durable-stream
@tanstack/ai-elevenlabs
@tanstack/ai-event-client
@tanstack/ai-fal
@tanstack/ai-gemini
@tanstack/ai-grok
@tanstack/ai-grok-build
@tanstack/ai-groq
@tanstack/ai-harness
@tanstack/ai-harness-cli
@tanstack/ai-isolate-cloudflare
@tanstack/ai-isolate-daytona
@tanstack/ai-isolate-e2b
@tanstack/ai-isolate-node
@tanstack/ai-isolate-quickjs
@tanstack/ai-isolate-quickjs-bun
@tanstack/ai-llmgateway
@tanstack/ai-lovable
@tanstack/ai-mcp
@tanstack/ai-memory
@tanstack/ai-mistral
@tanstack/ai-octane
@tanstack/ai-ollama
@tanstack/ai-ollaya
@tanstack/ai-openai
@tanstack/ai-opencode
@tanstack/ai-openrouter
@tanstack/ai-perplexity
@tanstack/ai-persistence
@tanstack/ai-preact
@tanstack/ai-react
@tanstack/ai-react-ui
@tanstack/ai-reactor
@tanstack/ai-remix
@tanstack/ai-sandbox
@tanstack/ai-sandbox-blaxel
@tanstack/ai-sandbox-boxd
@tanstack/ai-sandbox-cloudflare
@tanstack/ai-sandbox-daytona
@tanstack/ai-sandbox-docker
@tanstack/ai-sandbox-e2b
@tanstack/ai-sandbox-local-process
@tanstack/ai-sandbox-railway
@tanstack/ai-sandbox-sprites
@tanstack/ai-sandbox-upstash-box
@tanstack/ai-sandbox-vercel
@tanstack/ai-skills
@tanstack/ai-solid
@tanstack/ai-solid-ui
@tanstack/ai-svelte
@tanstack/ai-typesafe
@tanstack/ai-utils
@tanstack/ai-vercel-gateway
@tanstack/ai-vertex
@tanstack/ai-vue
@tanstack/ai-vue-ui
@tanstack/ai-worldlabs
@tanstack/openai-base
@tanstack/preact-ai-devtools
@tanstack/react-ai-devtools
@tanstack/solid-ai-devtools
@tanstack/svelte-ai-devtools
commit: |
Coverage✅ Coverage held across 30 compared package(s). Each package is measured twice in this job — on this PR and on its merge-base with
|
Every session that opens also closes, and memory per session has a set limit.
host.openreturns a handle that you release, and the session closes when no handle holds it and it is idle. Read routes use a new read-onlyhost.observe, so a read never starts plugins or writes. This is PR 4 of the harness redesign stack for #1755. It targets #1812 (feat/harness-access).🎯 Changes
await session.close()releases only your handle, andawait using session = await host.open(...)does it for you.lifecycle.idleCloseMs(default 60 000) with no handle. A handle that its holder dropped is released by garbage collection, with one warning.lifecycle.maxOpen(default 500) closes the least recently used idle sessions first.host.close()refuses later opens.harnessText, the stdio worker, ACPsession/close, and MCP calls.host.observe(harness, { threadId, principal }).ObservedSessionwithevents,transcript,snapshot,agentTranscript, media reads,usage,entry, andlogState.describestill opens the session.lifecycle.retention: { settledOperations, settledAgentRuns, eventBytes }bounds the inputs, operations, agent runs, the feed, and the log tail. One record per input is trimmed in one step. This fixes B5: asettled()no longer hangs when agent runs push out turn entries.definePlugin({ lifetime: 'host', setup })is set up once per host and harness, and shared by a reference count. Itssessionpart adds what each session needs.mcp()runs stdio servers once per host this way, and OAuth servers stay per user.host.sessions.deletepurges the open sessions, the logs or messages, the index rows, uploads and generated artifacts, the harness metadata, and every child thread, depth first.signal, and the loopback deadline isunref'd. A cancel or a session close stops a running/connectat once.OAuthConfig.issuerchecks theissof a callback.runCli({ signals })option takes the signal source.Docs: a new
docs/harness/lifecycle.md, and changes insessions,plugins,mcp,cli,auth,durable-sessions,connect,custom-ui, andoverview. Changesets are edited in place.Decisions made while building:
deletepurges, so there is no secondpurgename. Plugin state, runs, interrupts, the inbox, and work claims stay for now: PR 5 moves them into the log or removes them.FinalizationRegistryreleases dropped handles.events()already retries a 404, so a new chat works.refreshCredentialtakes an options object ({ fetch, signal }) as its third argument, to matchexchangeCode.definePlugininfers its definition only from the argument (NoInfer). A plugins array around the call no longer breaks the inference of an inline plugin.✅ Checklist
pnpm run test:pr, or these tests do not apply to this pull request.docs/for this change, or this change is not user-facing.pnpm changeset), or this PR does not change a published package.🚀 Release Impact
Testing
Commands run:
test:typesofai-harness,ai-mcp,ai-acp, andai-harness-cli, plustest:typesof the otherdefinePluginusers (ai-skills,ai-code-mode,ai-sandbox). All pass.--maxWorkers=2:handles,observe,retention,host-plugins,purge,signals, the OAuth tests, and the touched MCP, ACP, and CLI tests. All pass.oxfmt --checkon every changed file,pnpm test:docs, andkiira checkon the changed docs pages.Not run locally: the full suites,
test:oxlint, knip, E2E (including the newharness-lifecycle.spec.ts), and coverage. CI runs them.Manual test:
pnpm --dir packages/ai-harness exec vitest run tests/handles.test.ts tests/observe.test.ts tests/purge.test.ts.tests/handles.test.ts: 10 000 sessions open and close through the handler, and the host ends with 0 open sessions.tests/observe.test.ts: a read route on a thread with a plugin that counts its setups mounts nothing.How this PR makes testing easy: the new test files pin each part:
handles,observe,retention,host-plugins,purge, and the CLIsignals.testing/e2e/tests/harness-lifecycle.spec.tscovers a delete that removes media and messages, and reads after an idle close.Risk / rollback
Medium.
session.close()now releases only a handle, and every read route moved toobserve. The harness is not released yet, and all callers in this repo are moved. To undo, revert this PR.Public API change
Before
After