Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1954,6 +1954,16 @@ projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => {
0,
'2026-05-01T00:00:16.000Z',
'2026-05-01T00:00:16.000Z'
),
(
'message-assistant-decoy',
'thread-percent-decoy',
NULL,
'assistant',
'Unreferenced assistant needle must not be searchable.',
0,
'2026-05-01T00:00:17.000Z',
'2026-05-01T00:00:17.000Z'
)
`;

Expand Down Expand Up @@ -2009,6 +2019,10 @@ projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => {
(yield* snapshotQuery.searchThreads({ query: "system needle" })).matches,
[],
);
assert.deepStrictEqual(
(yield* snapshotQuery.searchThreads({ query: "unreferenced assistant needle" })).matches,
[],
);
assert.deepStrictEqual(
(yield* snapshotQuery.searchThreads({ query: "hidden needle" })).matches,
[],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -904,10 +904,10 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
messages.role = 'user'
OR (
messages.role = 'assistant'
AND messages.message_id IN (
SELECT turns.assistant_message_id
AND EXISTS (
SELECT 1
FROM projection_turns AS turns
WHERE turns.assistant_message_id IS NOT NULL
WHERE turns.assistant_message_id = messages.message_id
)
)
)
Expand Down
2 changes: 2 additions & 0 deletions apps/server/src/persistence/Migrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import Migration0044 from "./Migrations/044_ClearAutomaticProjectModelDefaults.t
import Migration0045 from "./Migrations/045_ProjectionProjectsAutoPull.ts";
import Migration0046 from "./Migrations/046_RepairAutomaticSettlementTimestamps.ts";
import Migration0047 from "./Migrations/047_ProjectionProjectIcon.ts";
import Migration0048 from "./Migrations/048_ProjectionTurnsAssistantMessageIndex.ts";

/**
* Migration loader with all migrations defined inline.
Expand Down Expand Up @@ -118,6 +119,7 @@ export const migrationEntries = [
[45, "ProjectionProjectsAutoPull", Migration0045],
[46, "RepairAutomaticSettlementTimestamps", Migration0046],
[47, "ProjectionProjectIcon", Migration0047],
[48, "ProjectionTurnsAssistantMessageIndex", Migration0048],
] as const;

export const migrationManifest = migrationEntries.map(([id, name]) => [id, name] as const);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { assert, it } from "@effect/vitest";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import * as SqlClient from "effect/unstable/sql/SqlClient";

import { runMigrations } from "../Migrations.ts";
import * as NodeSqliteClient from "@t3tools/shared/nodeSqliteClient";

const layer = it.layer(Layer.mergeAll(NodeSqliteClient.layerMemory()));

layer("048_ProjectionTurnsAssistantMessageIndex", (it) => {
it.effect("indexes correlated canonical assistant lookups", () =>
Effect.gen(function* () {
const sql = yield* SqlClient.SqlClient;

yield* runMigrations({ toMigrationInclusive: 47 });
yield* runMigrations({ toMigrationInclusive: 48 });

const indexes = yield* sql<{
readonly seq: number;
readonly name: string;
readonly unique: number;
readonly origin: string;
readonly partial: number;
}>`
PRAGMA index_list(projection_turns)
`;
const assistantMessageIndex = indexes.find(
(index) => index.name === "idx_projection_turns_assistant_message_id",
);
assert.equal(assistantMessageIndex?.partial, 1);

const indexColumns = yield* sql<{
readonly seqno: number;
readonly cid: number;
readonly name: string;
}>`
PRAGMA index_info('idx_projection_turns_assistant_message_id')
`;
assert.deepStrictEqual(
indexColumns.map((column) => column.name),
["assistant_message_id"],
);

const plan = yield* sql<{ readonly detail: string }>`
EXPLAIN QUERY PLAN
SELECT messages.message_id
FROM projection_thread_messages AS messages
WHERE messages.role = 'assistant'
AND EXISTS (
SELECT 1
FROM projection_turns AS turns
WHERE turns.assistant_message_id = messages.message_id
)
`;
assert.ok(
plan.some((step) => step.detail.includes("idx_projection_turns_assistant_message_id")),
);
assert.ok(plan.every((step) => !step.detail.includes("SCAN turns")));
assert.ok(plan.every((step) => !step.detail.includes("LIST SUBQUERY")));
}),
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as Effect from "effect/Effect";
import * as SqlClient from "effect/unstable/sql/SqlClient";

export default Effect.gen(function* () {
const sql = yield* SqlClient.SqlClient;
yield* sql`
CREATE INDEX IF NOT EXISTS idx_projection_turns_assistant_message_id
ON projection_turns(assistant_message_id)
WHERE assistant_message_id IS NOT NULL
`;
});
Loading