Merge pull request #1543 from deepseek-harness/stack/agent-profiles-8-authoring
feat(web): author agent presets from a settings page
This commit is contained in:
@@ -162,6 +162,7 @@ interface SessionHeaderRow {
|
||||
parent_session: string | null
|
||||
seed_length: number | null
|
||||
delegation_depth: number | null
|
||||
agent_preset: string | null
|
||||
}
|
||||
|
||||
interface SearchRow extends SessionHeaderRow {
|
||||
@@ -552,16 +553,10 @@ export class SessionQuerySqlite extends SessionQueryService {
|
||||
const db = this._requireDb()
|
||||
db.prepare(`
|
||||
INSERT INTO persisted_sessions
|
||||
(id, version, created_at, cwd, parent_session, seed_length, delegation_depth, revision, generation)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
(id, version, created_at, cwd, parent_session, seed_length, delegation_depth, agent_preset, revision, generation)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`).run(
|
||||
entry.header.id,
|
||||
entry.header.version,
|
||||
entry.header.createdAt,
|
||||
entry.header.cwd ?? null,
|
||||
entry.header.parentSession ?? null,
|
||||
entry.header.seedLength ?? null,
|
||||
entry.header.delegationDepth ?? null,
|
||||
...headerBindings(entry.header),
|
||||
revision,
|
||||
generation,
|
||||
)
|
||||
@@ -588,16 +583,10 @@ export class SessionQuerySqlite extends SessionQueryService {
|
||||
const db = this._requireDb()
|
||||
db.prepare(`
|
||||
INSERT INTO temp.live_sessions
|
||||
(id, version, created_at, cwd, parent_session, seed_length, delegation_depth, fingerprint, persisted, generation)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
(id, version, created_at, cwd, parent_session, seed_length, delegation_depth, agent_preset, fingerprint, persisted, generation)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`).run(
|
||||
entry.header.id,
|
||||
entry.header.version,
|
||||
entry.header.createdAt,
|
||||
entry.header.cwd ?? null,
|
||||
entry.header.parentSession ?? null,
|
||||
entry.header.seedLength ?? null,
|
||||
entry.header.delegationDepth ?? null,
|
||||
...headerBindings(entry.header),
|
||||
entry.fingerprint,
|
||||
persisted ? 1 : 0,
|
||||
generation,
|
||||
@@ -692,7 +681,7 @@ export class SessionQuerySqlite extends SessionQueryService {
|
||||
const db = this._requireDb()
|
||||
const live = db.prepare(
|
||||
`SELECT
|
||||
id AS session_id, version, created_at, cwd, parent_session, seed_length, delegation_depth, generation
|
||||
id AS session_id, version, created_at, cwd, parent_session, seed_length, delegation_depth, agent_preset, generation
|
||||
FROM temp.live_sessions
|
||||
WHERE id = ?`,
|
||||
).get(sessionId) as (SessionHeaderRow & { generation: number }) | undefined
|
||||
@@ -702,7 +691,7 @@ export class SessionQuerySqlite extends SessionQueryService {
|
||||
if (persistenceBinding.service !== undefined) {
|
||||
const persisted = db.prepare(
|
||||
`SELECT
|
||||
id AS session_id, version, created_at, cwd, parent_session, seed_length, delegation_depth, generation
|
||||
id AS session_id, version, created_at, cwd, parent_session, seed_length, delegation_depth, agent_preset, generation
|
||||
FROM persisted_sessions
|
||||
WHERE id = ?`,
|
||||
).get(sessionId) as (SessionHeaderRow & { generation: number }) | undefined
|
||||
@@ -750,6 +739,25 @@ export class SessionQuerySqlite extends SessionQueryService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The header columns both session upserts bind, in the order their INSERT
|
||||
* lists them. The two statements differ only in what they append after these.
|
||||
* @param header - the session header being written.
|
||||
* @returns one bound value per header column.
|
||||
*/
|
||||
function headerBindings(header: SessionHeader): (string | number | null)[] {
|
||||
return [
|
||||
header.id,
|
||||
header.version,
|
||||
header.createdAt,
|
||||
header.cwd ?? null,
|
||||
header.parentSession ?? null,
|
||||
header.seedLength ?? null,
|
||||
header.delegationDepth ?? null,
|
||||
header.agentPreset ?? null,
|
||||
]
|
||||
}
|
||||
|
||||
function selectedDocumentsSql(): { sql: string } {
|
||||
return {
|
||||
sql: `WITH candidates AS (
|
||||
@@ -761,6 +769,7 @@ function selectedDocumentsSql(): { sql: string } {
|
||||
ps.parent_session AS parent_session,
|
||||
ps.seed_length AS seed_length,
|
||||
ps.delegation_depth AS delegation_depth,
|
||||
ps.agent_preset AS agent_preset,
|
||||
0 AS live,
|
||||
1 AS persisted,
|
||||
CAST(pd.seq AS INTEGER) AS seq,
|
||||
@@ -783,6 +792,7 @@ function selectedDocumentsSql(): { sql: string } {
|
||||
ls.parent_session AS parent_session,
|
||||
ls.seed_length AS seed_length,
|
||||
ls.delegation_depth AS delegation_depth,
|
||||
ls.agent_preset AS agent_preset,
|
||||
1 AS live,
|
||||
CASE WHEN ? = 1 THEN ls.persisted ELSE 0 END AS persisted,
|
||||
CAST(ld.seq AS INTEGER) AS seq,
|
||||
@@ -891,6 +901,7 @@ function sameHeader(a: SessionHeader, b: SessionHeader): boolean {
|
||||
&& a.parentSession === b.parentSession
|
||||
&& a.seedLength === b.seedLength
|
||||
&& (a.delegationDepth ?? 0) === (b.delegationDepth ?? 0)
|
||||
&& a.agentPreset === b.agentPreset
|
||||
}
|
||||
|
||||
function rowHeader(row: SessionHeaderRow): SessionHeader {
|
||||
@@ -902,6 +913,7 @@ function rowHeader(row: SessionHeaderRow): SessionHeader {
|
||||
...row.parent_session === null ? {} : { parentSession: row.parent_session as SessionId },
|
||||
...row.seed_length === null ? {} : { seedLength: row.seed_length },
|
||||
...row.delegation_depth === null ? {} : { delegationDepth: row.delegation_depth },
|
||||
...row.agent_preset === null ? {} : { agentPreset: row.agent_preset },
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { mkdir, open } from 'node:fs/promises'
|
||||
import { dirname, resolve } from 'node:path'
|
||||
|
||||
/** Current derived-index schema version. Incompatible versions reset in place. */
|
||||
export const SESSION_QUERY_SQLITE_SCHEMA_VERSION = 7
|
||||
export const SESSION_QUERY_SQLITE_SCHEMA_VERSION = 8
|
||||
|
||||
/** SQLite application id protecting unrelated databases from derived resets. */
|
||||
export const SESSION_QUERY_SQLITE_APPLICATION_ID = 0x44534851
|
||||
@@ -118,6 +118,7 @@ function ensurePersistentSchema(db: DatabaseSync): void {
|
||||
parent_session TEXT,
|
||||
seed_length INTEGER,
|
||||
delegation_depth INTEGER,
|
||||
agent_preset TEXT,
|
||||
revision TEXT NOT NULL,
|
||||
generation INTEGER NOT NULL
|
||||
) STRICT
|
||||
@@ -147,6 +148,7 @@ function ensureTemporarySchema(db: DatabaseSync): void {
|
||||
parent_session TEXT,
|
||||
seed_length INTEGER,
|
||||
delegation_depth INTEGER,
|
||||
agent_preset TEXT,
|
||||
fingerprint TEXT NOT NULL,
|
||||
persisted INTEGER NOT NULL CHECK (persisted IN (0, 1)),
|
||||
generation INTEGER NOT NULL
|
||||
|
||||
@@ -280,7 +280,10 @@ describe('SQLite session search', () => {
|
||||
it('searches two-character Unicode61 tokens in live-only sessions', async () => {
|
||||
const ctx = await liveContext({ path: ':memory:', snippetChars: 20 })
|
||||
const session = ctx.sessions.create(SessionId('live'), {
|
||||
meta: { cwd: '/work', createdAt: 10, seedLength: 1, delegationDepth: 2 },
|
||||
// agentPreset rides along: the index rebuilds the header a caller reads,
|
||||
// and a session listed under the wrong composition is a lie about what it
|
||||
// ran. The full-header comparison below is what pins every column.
|
||||
meta: { cwd: '/work', createdAt: 10, seedLength: 1, delegationDepth: 2, agentPreset: 'minimal' },
|
||||
})
|
||||
session.append(
|
||||
'user/message',
|
||||
|
||||
Reference in New Issue
Block a user