fix(tui): isolate each process query index

This commit is contained in:
Turtle
2026-07-29 18:21:14 +08:00
parent fdd113ce5e
commit 984830c940
4 changed files with 23 additions and 9 deletions

View File

@@ -19,6 +19,7 @@
import { randomUUID } from 'node:crypto'
import { join, resolve } from 'node:path'
import { tmpdir } from 'node:os'
import { fileURLToPath } from 'node:url'
import {
addHarnessSourceSection,
@@ -31,6 +32,7 @@ import {
} from '@deepseek-ai/dsh-app-boot'
import { resolveDshHome, resolveSessionsRoot } from '@deepseek-ai/dsh-paths'
import { SessionId } from '@deepseek-ai/dsh-session'
import { SESSION_QUERY_SQLITE_PATH_KEY } from '@deepseek-ai/dsh-session-query-sqlite'
import { CONFIGURED_AGENT_IDENTITIES_KEY } from '@deepseek-ai/dsh-agent-loop'
import type { Context } from 'cordis'
import {
@@ -57,8 +59,8 @@ const TUI_OVERLAY = fileURLToPath(new URL('../tui.cordis.yml', import.meta.url))
// session identity by this config id.
const MAIN_AGENT_ID = 'main'
/** Filename of the derived `/resume` index, kept beside the session logs. */
const SESSION_QUERY_DB = 'session-query.db'
/** Per-process filename of the disposable `/resume` index. */
const SESSION_QUERY_DB = `session-query-${String(process.pid)}-${randomUUID()}.db`
// The harness checkout root: three hops up from apps/cli/{src,lib}, resolved
// from this bin's location so it holds however `dsh` is launched (a PATH
@@ -242,9 +244,9 @@ export async function runTui(
// same id, so a personal overlay repointing the model route cannot drop
// the session identity or desynchronise the two.
hostCtx.provide(CONFIGURED_AGENT_IDENTITIES_KEY, { [MAIN_AGENT_ID]: identity })
// The launcher owns the session store location, so it also owns the
// derived index path that must sit beside those logs.
hostCtx.provide('launcherSessionQueryPath', join(launcherSessionsRoot(), SESSION_QUERY_DB))
// The query database is a disposable derived index with single-process
// ownership. Keep it process-local while it indexes the shared logs.
hostCtx.provide(SESSION_QUERY_SQLITE_PATH_KEY, join(tmpdir(), SESSION_QUERY_DB))
if (resumeHost !== undefined) hostCtx.provide('tuiResumeHost', resumeHost)
// Seed the first turn only for a fresh session, so resuming never
// re-invokes the skill.

View File

@@ -29,6 +29,9 @@
{
"path": "../../packages/util/paths"
},
{
"path": "../../packages/session-query/session-query-sqlite"
},
{
"path": "../../packages/client/connection"
},

View File

@@ -82,10 +82,9 @@
- id: session-checkpoint-policy
name: '@deepseek-ai/dsh-session-checkpoint-policy'
# The derived query index behind `/resume`. The launcher owns the session
# store location, so it provides the resolved index path on the boot context
# (`launcherSessionQueryPath`); the index and the logs it indexes therefore
# cannot diverge. The project-local fallback applies when no launcher sets it.
# The derived query index behind `/resume`. The launcher provides a unique
# process-local path because this SQLite backend has one writer owner; the
# project-local fallback applies when no launcher sets the typed slot.
- id: session-query-sqlite
name: '@deepseek-ai/dsh-session-query-sqlite'
config:

View File

@@ -62,6 +62,16 @@ export {
type JournalMode,
} from './schema.ts'
/** Boot-context slot for a launcher-owned absolute path to this process's derived query index. */
export const SESSION_QUERY_SQLITE_PATH_KEY = 'launcherSessionQueryPath'
declare module 'cordis' {
interface Context {
/** Launcher-owned absolute path to this process's disposable derived query index. */
launcherSessionQueryPath?: string
}
}
/** Default result page size. */
export const SESSION_QUERY_SQLITE_DEFAULT_LIMIT = 20
/** Maximum accepted result page size. */