@avantf/dsh-mem 0.6.4 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -10
- package/lib/client.js +1665 -3466
- package/lib/dsh-build.json +6 -5
- package/lib/engine/graph-recall/in-memory.d.ts +93 -0
- package/lib/engine/graph-recall/index.d.ts +22 -0
- package/lib/engine/graph-recall/traverse.d.ts +119 -0
- package/lib/engine/graph-recall/types.d.ts +188 -0
- package/lib/engine/mem/config/config_files.d.ts +1 -1
- package/lib/engine/mem/config/loader.d.ts +2 -3
- package/lib/engine/mem/config/paths.d.ts +2 -13
- package/lib/engine/mem/db/dao/contradictions.d.ts +4 -22
- package/lib/engine/mem/db/dao/entities.d.ts +80 -7
- package/lib/engine/mem/db/dao/fact_sources.d.ts +3 -13
- package/lib/engine/mem/db/dao/facts.d.ts +311 -56
- package/lib/engine/mem/db/dao/triples.d.ts +1 -26
- package/lib/engine/mem/db/graph.d.ts +249 -0
- package/lib/engine/mem/db/journal_notes.d.ts +35 -0
- package/lib/engine/mem/db/migrations.d.ts +9 -0
- package/lib/engine/mem/db/port.d.ts +22 -3
- package/lib/engine/mem/db/schema.d.ts +119 -0
- package/lib/engine/mem/db/tokenizer.d.ts +9 -0
- package/lib/engine/mem/dbdrivers/fake/driver.d.ts +75 -0
- package/lib/engine/mem/dbdrivers/fake/index.d.ts +7 -0
- package/lib/engine/mem/dbdrivers/fake/surface.d.ts +34 -0
- package/lib/engine/mem/dbdrivers/fake/transport.d.ts +61 -0
- package/lib/engine/mem/dbdrivers/sqlite/connection.d.ts +14 -0
- package/lib/engine/mem/dbdrivers/sqlite/contradictions.d.ts +35 -0
- package/lib/engine/mem/dbdrivers/sqlite/dao/index.d.ts +16 -0
- package/lib/engine/mem/dbdrivers/sqlite/driver.d.ts +54 -0
- package/lib/engine/mem/dbdrivers/sqlite/facts.d.ts +117 -0
- package/lib/engine/mem/dbdrivers/sqlite/index.d.ts +6 -0
- package/lib/engine/mem/dbdrivers/sqlite/migrations.d.ts +15 -0
- package/lib/engine/mem/dbdrivers/sqlite/relations.d.ts +62 -0
- package/lib/engine/mem/dbdrivers/sqlite/search.d.ts +56 -0
- package/lib/engine/mem/dbdrivers/sqlite/sources.d.ts +37 -0
- package/lib/engine/mem/defaults.d.ts +3 -4
- package/lib/engine/mem/dispatch.d.ts +7 -32
- package/lib/engine/mem/entities/extract.d.ts +44 -47
- package/lib/engine/mem/eval/derived_runner.d.ts +6 -1
- package/lib/engine/mem/eval/relation_gold.d.ts +251 -0
- package/lib/engine/mem/eval/write_metrics.d.ts +1 -1
- package/lib/engine/mem/facts_io.d.ts +328 -0
- package/lib/engine/mem/index.d.ts +10 -2
- package/lib/engine/mem/interfaces/capabilities.d.ts +30 -0
- package/lib/engine/mem/interfaces/common.d.ts +11 -0
- package/lib/engine/mem/interfaces/errors.d.ts +65 -0
- package/lib/engine/mem/interfaces/index.d.ts +18 -0
- package/lib/engine/mem/interfaces/migrations.d.ts +21 -0
- package/lib/engine/mem/interfaces/repositories.d.ts +471 -0
- package/lib/engine/mem/interfaces/search_index.d.ts +113 -0
- package/lib/engine/mem/interfaces/storage_backend.d.ts +84 -0
- package/lib/engine/mem/interfaces/storage_driver.d.ts +43 -0
- package/lib/engine/mem/interfaces/version.d.ts +34 -0
- package/lib/engine/mem/lifecycle/contradiction.d.ts +2 -2
- package/lib/engine/mem/maintenance_paths.d.ts +41 -0
- package/lib/engine/mem/modelBootstrap.d.ts +1 -1
- package/lib/engine/mem/relations/confidence.d.ts +39 -0
- package/lib/engine/mem/relations/extract.d.ts +128 -0
- package/lib/engine/mem/relations/index.d.ts +32 -0
- package/lib/engine/mem/relations/name-quality.d.ts +78 -0
- package/lib/engine/mem/relations/normalize.d.ts +275 -0
- package/lib/engine/mem/relations/patterns.d.ts +67 -0
- package/lib/engine/mem/relations/statement.d.ts +88 -0
- package/lib/engine/mem/relations/types.d.ts +79 -0
- package/lib/engine/mem/runtime.d.ts +117 -90
- package/lib/engine/mem/storage/create.d.ts +42 -0
- package/lib/engine/mem/storage/errors.d.ts +65 -0
- package/lib/engine/mem/storage/index.d.ts +15 -0
- package/lib/engine/mem/storage/ports.d.ts +472 -0
- package/lib/engine/mem/storage/registry.d.ts +37 -0
- package/lib/engine/mem/storage/sqlite.d.ts +28 -0
- package/lib/engine/mem/store/common.d.ts +1 -1
- package/lib/engine/mem/store/entity_leg.d.ts +59 -2
- package/lib/engine/mem/store/entity_sweep.d.ts +4 -3
- package/lib/engine/mem/store/explicit_relations.d.ts +52 -0
- package/lib/engine/mem/store/facts_restore.d.ts +124 -0
- package/lib/engine/mem/store/floors.d.ts +4 -1
- package/lib/engine/mem/store/graph_reader.d.ts +146 -0
- package/lib/engine/mem/store/hybrid.d.ts +50 -13
- package/lib/engine/mem/store/kinds.d.ts +47 -0
- package/lib/engine/mem/store/legs.d.ts +24 -29
- package/lib/engine/mem/store/lexical.d.ts +36 -45
- package/lib/engine/mem/store/memory.d.ts +486 -82
- package/lib/engine/mem/store/recall_policy.d.ts +49 -0
- package/lib/engine/mem/store/relation_backfill.d.ts +210 -0
- package/lib/engine/mem/store/relation_planner.d.ts +191 -0
- package/lib/engine/mem/store/secret_guard.d.ts +0 -1
- package/lib/engine/mem/store/self_query.d.ts +4 -2
- package/lib/engine/mem/store/time_filter.d.ts +121 -0
- package/lib/engine/mem/store/titles.d.ts +52 -0
- package/lib/engine/mem/store/vector_repair.d.ts +44 -54
- package/lib/engine/mem-contract/config.d.ts +44 -38
- package/lib/engine/mem-contract/text.d.ts +1 -1
- package/lib/engine/mem-contract/tools.d.ts +184 -117
- package/lib/engine/mem-contract/types.d.ts +364 -288
- package/lib/index.js +13898 -11500
- package/lib/interface-version.json +1 -1
- package/lib/types/client/index.d.ts +2 -2
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/paging.d.ts +3 -12
- package/lib/types/client/paging.d.ts.map +1 -1
- package/lib/types/client/summarize.d.ts.map +1 -1
- package/lib/types/command.d.ts +61 -0
- package/lib/types/command.d.ts.map +1 -0
- package/lib/types/envinit-bootstrap.d.ts +1 -1
- package/lib/types/envinit.d.ts +2 -6
- package/lib/types/envinit.d.ts.map +1 -1
- package/lib/types/hints.d.ts +28 -24
- package/lib/types/hints.d.ts.map +1 -1
- package/lib/types/index.d.ts +21 -40
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/inject.d.ts +3 -2
- package/lib/types/inject.d.ts.map +1 -1
- package/lib/types/interface_gate.d.ts +9 -9
- package/lib/types/prompt.d.ts +17 -41
- package/lib/types/prompt.d.ts.map +1 -1
- package/lib/types/provision.d.ts +3 -0
- package/lib/types/provision.d.ts.map +1 -1
- package/lib/types/remote.d.ts +23 -9
- package/lib/types/remote.d.ts.map +1 -1
- package/lib/types/render.d.ts +3 -3
- package/lib/types/tool_schema.d.ts +4 -0
- package/lib/types/tool_schema.d.ts.map +1 -1
- package/lib/types/vectorMigration.d.ts +5 -7
- package/lib/types/vectorMigration.d.ts.map +1 -1
- package/package.json +16 -15
- package/lib/engine/mem/config/domains.d.ts +0 -20
- package/lib/engine/mem/db/dao/chunks.d.ts +0 -231
- package/lib/engine/mem/db/dao/documents.d.ts +0 -51
- package/lib/engine/mem/db/hash.d.ts +0 -2
- package/lib/engine/mem/db/knowledge.d.ts +0 -17
- package/lib/engine/mem/eval/index.d.ts +0 -4
- package/lib/engine/mem/git.d.ts +0 -73
- package/lib/engine/mem/router.d.ts +0 -51
- package/lib/engine/mem/store/doc_files.d.ts +0 -125
- package/lib/engine/mem/store/document_text.d.ts +0 -47
- package/lib/engine/mem/store/ingest_guard.d.ts +0 -25
- package/lib/engine/mem/store/knowledge.d.ts +0 -598
- package/lib/engine/mem/store/source_picker.d.ts +0 -43
- package/lib/engine/mem-retrieval/adapters/local_reranker.d.ts +0 -52
- package/lib/engine/mem-retrieval/adapters/none_reranker.d.ts +0 -10
- package/lib/engine/mem-retrieval/rerank.d.ts +0 -13
- package/lib/types/client/domains.d.ts +0 -53
- package/lib/types/client/domains.d.ts.map +0 -1
- package/lib/types/client/ingest.d.ts +0 -24
- package/lib/types/client/ingest.d.ts.map +0 -1
- package/lib/types/open.d.ts +0 -77
- package/lib/types/open.d.ts.map +0 -1
- package/lib/types/reconcile.d.ts +0 -64
- package/lib/types/reconcile.d.ts.map +0 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The async SURFACE a mock-remote backend exposes (DB-4, docs/DB_DRIVER_LAYOUT.md §五).
|
|
3
|
+
*
|
|
4
|
+
* A `StorageBackend` is a tree of objects (`facts`, `relations.entities`, `search`, `lifecycle`, …).
|
|
5
|
+
* This module turns that tree into the same tree where every METHOD is one hop over
|
|
6
|
+
* {@link StorageTransport}: the call returns a promise, the transport may delay or fail it, and the
|
|
7
|
+
* result is the wrapped object's result unchanged.
|
|
8
|
+
*
|
|
9
|
+
* Why a proxy instead of ~90 hand-written delegating methods: the point of DB-4 is that NO method may
|
|
10
|
+
* accidentally bypass the boundary. A hand-written list can forget the method a future port adds and
|
|
11
|
+
* the suite would not notice; deriving the surface from the object means every method that exists is
|
|
12
|
+
* routed by construction. What it deliberately does NOT do: touch data properties
|
|
13
|
+
* (`migrations.from`, `migrations.applied`), arrays, or the one method the port declares synchronous
|
|
14
|
+
* ({@link AsyncSurfaceOptions.synchronous}) — those carry no I/O to simulate.
|
|
15
|
+
*
|
|
16
|
+
* @module dbdrivers/fake/surface
|
|
17
|
+
*/
|
|
18
|
+
import type { StorageTransport } from './transport.js';
|
|
19
|
+
export interface AsyncSurfaceOptions {
|
|
20
|
+
/**
|
|
21
|
+
* Methods the PORT declares synchronous. There is exactly one today
|
|
22
|
+
* (`ContradictionRepository.configure`, which only supplies knobs); wrapping it in a promise would
|
|
23
|
+
* make the store's fire-and-forget call race the next check, so it is called through directly.
|
|
24
|
+
*/
|
|
25
|
+
readonly synchronous?: readonly string[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Wrap `target` so every method call is one {@link StorageTransport.request}.
|
|
29
|
+
*
|
|
30
|
+
* `label` prefixes each operation (`facts.insertRevision`), which is what makes a failure message and
|
|
31
|
+
* a test's operation log readable. Nested service objects (`relations.entities`) are wrapped lazily
|
|
32
|
+
* and cached, so the property keeps a stable identity across calls.
|
|
33
|
+
*/
|
|
34
|
+
export declare function asyncSurface<T extends object>(label: string, target: T, transport: StorageTransport, options?: AsyncSurfaceOptions): T;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/** One simulated hop. `1` is the connect (see {@link StorageTransport.connect}). */
|
|
2
|
+
export interface MockRemoteTurnaround {
|
|
3
|
+
/** Simulated round-trip latency per operation, in milliseconds (default `0`). */
|
|
4
|
+
readonly latencyMs?: number;
|
|
5
|
+
/** Fail operation number `failAfter` (1-based, connect included). */
|
|
6
|
+
readonly failAfter?: number | null;
|
|
7
|
+
/** The injected failure's message; a generic one is used when absent. */
|
|
8
|
+
readonly failMessage?: string | null;
|
|
9
|
+
}
|
|
10
|
+
/** What one operation did — the audit trail a test asserts on ("this really went through the hop"). */
|
|
11
|
+
export interface TransportRequestRecord {
|
|
12
|
+
/** 1-based order across ALL operations, the connect included. */
|
|
13
|
+
readonly sequence: number;
|
|
14
|
+
/** `facts.insertRevision`, `lifecycle.restore`, … — path + method name in the backend surface. */
|
|
15
|
+
readonly operation: string;
|
|
16
|
+
readonly latencyMs: number;
|
|
17
|
+
/** The injected failure hit this operation (the wrapped work did NOT run). */
|
|
18
|
+
failed: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The hop every backend call crosses. `connect()` is the open-time handshake: a remote that cannot be
|
|
22
|
+
* reached must fail `open()`, before any store exists.
|
|
23
|
+
*/
|
|
24
|
+
export interface StorageTransport {
|
|
25
|
+
/** A label for diagnostics (`mock-remote`). */
|
|
26
|
+
readonly kind: string;
|
|
27
|
+
connect(): Promise<void>;
|
|
28
|
+
request<T>(operation: string, work: () => T | Promise<T>): Promise<T>;
|
|
29
|
+
}
|
|
30
|
+
/** The error code an injected failure carries, so a caller can tell it from a driver's own failure. */
|
|
31
|
+
export declare const MOCK_REMOTE_FAILURE_CODE = "MOCK_REMOTE_TRANSPORT";
|
|
32
|
+
/**
|
|
33
|
+
* The in-process simulation of the hop (docs/DB_DRIVER_LAYOUT.md §五).
|
|
34
|
+
*
|
|
35
|
+
* Deterministic by default: no latency, no failure, so a suite that does not opt in behaves exactly
|
|
36
|
+
* like a local backend — which is what lets the SHARED contract run against it unchanged.
|
|
37
|
+
*/
|
|
38
|
+
export declare class MockRemoteTransport implements StorageTransport {
|
|
39
|
+
readonly kind = "mock-remote";
|
|
40
|
+
/** Every operation this transport served, in order (assertions and diagnostics). */
|
|
41
|
+
readonly requests: TransportRequestRecord[];
|
|
42
|
+
private sequence;
|
|
43
|
+
private pendingFailures;
|
|
44
|
+
private failMessageOverride;
|
|
45
|
+
private readonly latencyMs;
|
|
46
|
+
private readonly failAfter;
|
|
47
|
+
private readonly failMessage;
|
|
48
|
+
constructor(turnaround?: MockRemoteTurnaround);
|
|
49
|
+
/** The open-time handshake: a remote that cannot be reached fails `open()`. */
|
|
50
|
+
connect(): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Fail the next `count` operations.
|
|
53
|
+
*
|
|
54
|
+
* The imperative twin of {@link MockRemoteTurnaround.failAfter}: a test that wants a SPECIFIC call
|
|
55
|
+
* to fail injects it right before that call, instead of counting every operation an implementation
|
|
56
|
+
* happens to make (a count that would break on an unrelated refactor).
|
|
57
|
+
*/
|
|
58
|
+
injectFailure(count?: number, message?: string): void;
|
|
59
|
+
request<T>(operation: string, work: () => T | Promise<T>): Promise<T>;
|
|
60
|
+
private operate;
|
|
61
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SQLite driver's CONNECTION (open, PRAGMAs, WAL, busy_timeout, probe).
|
|
3
|
+
*
|
|
4
|
+
* The implementation still lives in `db/conn.ts` + `db/sqlite.ts` — `docs/DB_DRIVER_LAYOUT.md` §三
|
|
5
|
+
* allows the existing physical modules to be re-exported first and moved later. What this file fixes
|
|
6
|
+
* is the dependency direction: from here on, a driver module imports its connection from THIS module,
|
|
7
|
+
* so the physical move never touches a repository or the backend.
|
|
8
|
+
*
|
|
9
|
+
* @module dbdrivers/sqlite/connection
|
|
10
|
+
*/
|
|
11
|
+
export { openMemoryStore } from '../../db/conn.js';
|
|
12
|
+
export type { OpenedStore, StoreSchema } from '../../db/store.js';
|
|
13
|
+
export { describeSqlite, openSqlite, sqliteProbe } from '../../db/sqlite.js';
|
|
14
|
+
export type { Db } from '../../db/port.js';
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SQLite CONTRADICTION façade (log + detector).
|
|
3
|
+
*
|
|
4
|
+
* The detector itself (`lifecycle/contradiction.ts`) is domain policy; this class supplies it the
|
|
5
|
+
* connection, the configured threshold and the store's runtime knobs, and exposes the log reads the
|
|
6
|
+
* `mem_admin` surfaces use.
|
|
7
|
+
*
|
|
8
|
+
* @module dbdrivers/sqlite/contradictions
|
|
9
|
+
*/
|
|
10
|
+
import type { ContradictionRecord, MemoryKind } from '../../../mem-contract/index.js';
|
|
11
|
+
import type { Db } from '../../db/port.js';
|
|
12
|
+
import { ContradictDetector } from '../../lifecycle/contradiction.js';
|
|
13
|
+
import type { EntitiesDao } from './dao/index.js';
|
|
14
|
+
import type { ConflictPair, ContradictionRepository, StoredConflict } from '../../interfaces/repositories.js';
|
|
15
|
+
export declare class SqliteContradictionRepository implements ContradictionRepository {
|
|
16
|
+
private readonly db;
|
|
17
|
+
private readonly entities;
|
|
18
|
+
private detector;
|
|
19
|
+
private threshold;
|
|
20
|
+
private fetchVectors;
|
|
21
|
+
constructor(db: Db, entities: EntitiesDao, threshold: number);
|
|
22
|
+
configure(options: {
|
|
23
|
+
threshold?: number;
|
|
24
|
+
fetchVectors?: (ids: number[]) => Map<number, Float32Array>;
|
|
25
|
+
}): void;
|
|
26
|
+
private get instance();
|
|
27
|
+
checkOne(factId: number): ReturnType<ContradictDetector['checkOne']>;
|
|
28
|
+
checkMany(factIds: readonly number[]): ReturnType<ContradictDetector['checkMany']>;
|
|
29
|
+
openConflictsFor(factId: number): ConflictPair[];
|
|
30
|
+
resolveForFact(factId: number): number;
|
|
31
|
+
resolveForFacts(factIds: readonly number[]): number;
|
|
32
|
+
get(id: number): StoredConflict | undefined;
|
|
33
|
+
resolve(id: number, resolution: 'true_positive' | 'false_positive', loserFactId?: number): void;
|
|
34
|
+
list(resolved?: number, kind?: MemoryKind, threshold?: number, limit?: number): ContradictionRecord[];
|
|
35
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SQLite DAOs, re-exported under the driver (docs/DB_DRIVER_LAYOUT.md §三).
|
|
3
|
+
*
|
|
4
|
+
* The DAOs are SQLite-specific by construction (FTS5, PRAGMA, `INDEXED BY`), and they physically
|
|
5
|
+
* live in `db/dao/*` today. This barrel is the only place the driver reaches for them, so the
|
|
6
|
+
* eventual physical move is a change to these export paths and nothing else — and no repository,
|
|
7
|
+
* backend or store file grows a new import of a DAO.
|
|
8
|
+
*
|
|
9
|
+
* @module dbdrivers/sqlite/dao
|
|
10
|
+
*/
|
|
11
|
+
export { FactsDao } from '../../../db/dao/facts.js';
|
|
12
|
+
export { EntitiesDao } from '../../../db/dao/entities.js';
|
|
13
|
+
export { TriplesDao } from '../../../db/dao/triples.js';
|
|
14
|
+
export { StatsDao } from '../../../db/dao/stats.js';
|
|
15
|
+
export { classifySourceRef, FACT_SOURCE_FALLBACK_KIND, FACT_SOURCE_KINDS, FactSourcesDao, } from '../../../db/dao/fact_sources.js';
|
|
16
|
+
export type { ConflictPair, StoredConflict } from '../../../interfaces/repositories.js';
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SQLite storage DRIVER (docs/DB_DRIVER_LAYOUT.md §二/§三).
|
|
3
|
+
*
|
|
4
|
+
* `sqliteDriver.open()` is the one place a SQLite backend is created: it opens (or creates) the file,
|
|
5
|
+
* applies the schema's migrations, wires the repository objects over the ONE connection and returns
|
|
6
|
+
* the portable {@link StorageBackend}. Everything above the boundary gets that object, never the
|
|
7
|
+
* `Db` — except through {@link SqliteStorageBackend.relationalHandle}, the documented transition hole
|
|
8
|
+
* for the CLI's SQL-speaking operator commands.
|
|
9
|
+
*
|
|
10
|
+
* The driver declares `contractVersion: STORAGE_CONTRACT_VERSION` and its capabilities; the registry
|
|
11
|
+
* refuses it on a host whose contract major does not match (never a silent fallback).
|
|
12
|
+
*
|
|
13
|
+
* @module dbdrivers/sqlite/driver
|
|
14
|
+
*/
|
|
15
|
+
import type { StorageConfig } from '../../../mem-contract/index.js';
|
|
16
|
+
import type { StorageCapabilities } from '../../interfaces/capabilities.js';
|
|
17
|
+
import type { MigrationRunner } from '../../interfaces/migrations.js';
|
|
18
|
+
import type { ContradictionRepository, KeyValueRepository, MemoryRepository, RelationRepository, SourceRepository } from '../../interfaces/repositories.js';
|
|
19
|
+
import type { SearchIndex } from '../../interfaces/search_index.js';
|
|
20
|
+
import type { LifecycleService, StorageBackend } from '../../interfaces/storage_backend.js';
|
|
21
|
+
import type { StorageDriver } from '../../interfaces/storage_driver.js';
|
|
22
|
+
/** What this driver can do. Declared once, so the host never probes for it with a failing query. */
|
|
23
|
+
export declare const SQLITE_CAPABILITIES: StorageCapabilities;
|
|
24
|
+
/** The open SQLite database plus the repository objects built over its one connection. */
|
|
25
|
+
export declare class SqliteStorageBackend implements StorageBackend {
|
|
26
|
+
readonly kind = "sqlite";
|
|
27
|
+
readonly capabilities: StorageCapabilities;
|
|
28
|
+
/** The facts aggregate — named `facts` per the HAL layout (`docs/DB_DRIVER_LAYOUT.md` §二). */
|
|
29
|
+
readonly facts: MemoryRepository;
|
|
30
|
+
readonly relations: RelationRepository;
|
|
31
|
+
readonly sources: SourceRepository;
|
|
32
|
+
readonly contradictions: ContradictionRepository;
|
|
33
|
+
readonly search: SearchIndex;
|
|
34
|
+
readonly keyValue: KeyValueRepository;
|
|
35
|
+
readonly lifecycle: LifecycleService;
|
|
36
|
+
readonly migrations: MigrationRunner;
|
|
37
|
+
/** The one connection. Kept private to the driver; see {@link relationalHandle}. */
|
|
38
|
+
private readonly db;
|
|
39
|
+
constructor(path: string, options?: {
|
|
40
|
+
contradictionThreshold?: number;
|
|
41
|
+
});
|
|
42
|
+
/**
|
|
43
|
+
* The driver's relational handle, for the CLI's relation-backfill commands and `AvantfRuntime.db`.
|
|
44
|
+
*
|
|
45
|
+
* These operator paths still speak SQL (`proposeRelations`, `relationBackfill`, the export
|
|
46
|
+
* reader). The STORE and every retrieval/lifecycle path go through the repositories; the type is
|
|
47
|
+
* `unknown` on the port because a portable interface cannot name `Db`, and the host casts at the
|
|
48
|
+
* one place it asks.
|
|
49
|
+
*/
|
|
50
|
+
relationalHandle(): unknown;
|
|
51
|
+
close(): void;
|
|
52
|
+
}
|
|
53
|
+
/** The SQLite driver: the one thing `storage.driver: sqlite` selects. */
|
|
54
|
+
export declare const sqliteDriver: StorageDriver<StorageConfig>;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SQLite FACTS repository (`MemoryRepository`).
|
|
3
|
+
*
|
|
4
|
+
* A thin delegation layer in front of `FactsDao`: the SQL and its plan comments stay in the DAO, so
|
|
5
|
+
* moving the driver did not change a query. What this file owns is the CONTRACT conversions:
|
|
6
|
+
* `TimeRange` (the domain's normalized window) → the DAO's bound `TimeSql`, and the DAO's
|
|
7
|
+
* `{ changes, lastInsertRowid }` → `{ inserted, factId }` (the backend assigns ids; DB-3).
|
|
8
|
+
*
|
|
9
|
+
* @module dbdrivers/sqlite/facts
|
|
10
|
+
*/
|
|
11
|
+
import type { MemoryKind } from '../../../mem-contract/index.js';
|
|
12
|
+
import { type TimeRange } from '../../store/time_filter.js';
|
|
13
|
+
import type { FactHitMeta, FactRow, FactVectorRow, FactVectorSpaceRow, HrrVectorRow, InsertRevisionOutcome, MemoryRepository } from '../../interfaces/repositories.js';
|
|
14
|
+
import type { FactsDao } from './dao/index.js';
|
|
15
|
+
export declare class SqliteMemoryRepository implements MemoryRepository {
|
|
16
|
+
private readonly dao;
|
|
17
|
+
constructor(dao: FactsDao);
|
|
18
|
+
activeIds(ids: readonly number[]): number[];
|
|
19
|
+
getById(factId: number): FactRow | undefined;
|
|
20
|
+
rowsByIds(ids: readonly number[]): FactRow[];
|
|
21
|
+
textsByIds(ids: readonly number[]): Map<number, string>;
|
|
22
|
+
hitMetaByIds(ids: readonly number[]): Map<number, FactHitMeta>;
|
|
23
|
+
minSettleClock(): number | null;
|
|
24
|
+
maxSettleClock(): number | null;
|
|
25
|
+
countByStatus(): {
|
|
26
|
+
active: number;
|
|
27
|
+
archived: number;
|
|
28
|
+
};
|
|
29
|
+
countActive(): number;
|
|
30
|
+
countPinnedActive(): number;
|
|
31
|
+
countInStatus(status: string, kind?: MemoryKind, source?: string): number;
|
|
32
|
+
countActiveWithValidFrom(): number;
|
|
33
|
+
countForgettingWithin(p: {
|
|
34
|
+
step: number;
|
|
35
|
+
clock: number;
|
|
36
|
+
withinDays: number;
|
|
37
|
+
}): number;
|
|
38
|
+
countIdleCandidates(days: number): number;
|
|
39
|
+
countArchiveBacklog(p: {
|
|
40
|
+
forgetThreshold: number;
|
|
41
|
+
idleCalendarDays: number;
|
|
42
|
+
}): number;
|
|
43
|
+
countPendingConflicts(): number;
|
|
44
|
+
countStaleEntities(version: number): number;
|
|
45
|
+
vectorCounts(): {
|
|
46
|
+
total: number;
|
|
47
|
+
withSemantic: number;
|
|
48
|
+
missing: number;
|
|
49
|
+
};
|
|
50
|
+
activeVectorRows(): FactVectorRow[];
|
|
51
|
+
activeVectorSpaces(): FactVectorSpaceRow[];
|
|
52
|
+
archivedByReason(): {
|
|
53
|
+
reason: string;
|
|
54
|
+
n: number;
|
|
55
|
+
}[];
|
|
56
|
+
embeddingModels(): {
|
|
57
|
+
model: string | null;
|
|
58
|
+
n: number;
|
|
59
|
+
}[];
|
|
60
|
+
assertCount(factId: number): number;
|
|
61
|
+
supersededBy(factId: number): number | null;
|
|
62
|
+
statusOf(factId: number): string | undefined;
|
|
63
|
+
bonusStatedToday(): {
|
|
64
|
+
count: number;
|
|
65
|
+
granted: number;
|
|
66
|
+
};
|
|
67
|
+
page(status: string, kind: MemoryKind | undefined, limit: number, offset: number, source?: string): FactRow[];
|
|
68
|
+
pageTimeWindow(status: string, kind: MemoryKind | undefined, time: TimeRange, limit: number, offset: number, source?: string): FactRow[];
|
|
69
|
+
countStatusTimeWindow(status: string, kind: MemoryKind | undefined, time: TimeRange, source?: string): number;
|
|
70
|
+
findByContent(content: string): FactRow | undefined;
|
|
71
|
+
windowRows(from: string, to: string, kind: MemoryKind | undefined, cap: number, source?: string): number[];
|
|
72
|
+
staleEntityRows(version: number, limit: number): {
|
|
73
|
+
fact_id: number;
|
|
74
|
+
content: string;
|
|
75
|
+
kind: string;
|
|
76
|
+
}[];
|
|
77
|
+
pendingConflictRows(limit: number, after?: number): {
|
|
78
|
+
fact_id: number;
|
|
79
|
+
content: string;
|
|
80
|
+
}[];
|
|
81
|
+
missingVectorRows(): {
|
|
82
|
+
fact_id: number;
|
|
83
|
+
content: string;
|
|
84
|
+
}[];
|
|
85
|
+
activeHrrRows(kind?: MemoryKind, limit?: number, source?: string, time?: TimeRange): HrrVectorRow[];
|
|
86
|
+
hrrRowsForFacts(ids: readonly number[], kind?: MemoryKind, source?: string): HrrVectorRow[];
|
|
87
|
+
activeIdsIn(ids: readonly number[], kind?: MemoryKind, source?: string, time?: TimeRange): number[];
|
|
88
|
+
insertRevision(v: Parameters<FactsDao['insertRevision']>[0]): InsertRevisionOutcome;
|
|
89
|
+
applyValidity(factId: number, validFrom: Parameters<FactsDao['applyValidity']>[1], validTo: Parameters<FactsDao['applyValidity']>[2]): void;
|
|
90
|
+
applyValues(factId: number, kind: MemoryKind, ttlDays: number): void;
|
|
91
|
+
setTitle(factId: number, title: string): void;
|
|
92
|
+
insertTitleAlias(factId: number, title: string): void;
|
|
93
|
+
copyTitleAliases(fromFactId: number, toFactId: number, currentTitle: string): void;
|
|
94
|
+
dropTitleAlias(factId: number, title: string): void;
|
|
95
|
+
incrementAssertCount(factId: number): number;
|
|
96
|
+
markValidTo(factId: number, at: string, atMs?: number | null): void;
|
|
97
|
+
linkSupersede(factId: number, supersedesId: number): void;
|
|
98
|
+
archiveSuperseded(factId: number, clock: number): number;
|
|
99
|
+
revive(factId: number, kind: MemoryKind, ttlDays: number, trust: number, clock: number): number;
|
|
100
|
+
archive(factId: number, clock: number, reason: string): number;
|
|
101
|
+
restore(factId: number, trust: number, clock: number): number;
|
|
102
|
+
bumpHelpful(factId: number, delta: number): void;
|
|
103
|
+
pin(factId: number, clock: number): number;
|
|
104
|
+
unpin(factId: number, clock: number): number;
|
|
105
|
+
pinOutcome(factId: number, clock: number, bonusCount: number, windowAt: string): void;
|
|
106
|
+
forgetOutcome(factId: number, trust: number, clock: number, bonusCount: number, windowAt: string): void;
|
|
107
|
+
reinforceOutcome(factId: number, trust: number, clock: number, bonusCount: number, windowAt: string): void;
|
|
108
|
+
touchUsage(ids: readonly number[]): void;
|
|
109
|
+
settleTrust(factId: number, trust: number, clock: number): void;
|
|
110
|
+
reinforce(factId: number, trust: number, clock: number, bonusCount: number, windowAt: string): void;
|
|
111
|
+
setSemanticVector(factId: number, vector: Uint8Array, model: string, store: string): void;
|
|
112
|
+
clearVectors(ids: readonly number[]): number;
|
|
113
|
+
setHrrVector(factId: number, bytes: Uint8Array): void;
|
|
114
|
+
setEntitiesVersion(ids: readonly number[], version: number): number;
|
|
115
|
+
markConflictChecked(ids: readonly number[]): number;
|
|
116
|
+
requeueConflictCheck(ids: readonly number[]): number;
|
|
117
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { StorageBackend } from '../../interfaces/storage_backend.js';
|
|
2
|
+
import { SqliteStorageBackend } from './driver.js';
|
|
3
|
+
export { SqliteStorageBackend, sqliteDriver, SQLITE_CAPABILITIES } from './driver.js';
|
|
4
|
+
export { describeSqlite, sqliteProbe } from './connection.js';
|
|
5
|
+
/** Whether a backend was opened by THIS driver (the only driver this build ships). */
|
|
6
|
+
export declare function isSqliteStorageBackend(backend: StorageBackend): backend is SqliteStorageBackend;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SQLite driver's MIGRATION boundary (DB-3).
|
|
3
|
+
*
|
|
4
|
+
* The schema, the ordered steps and `PRAGMA user_version` handling stay in `db/conn.ts` +
|
|
5
|
+
* `db/migrations.ts` (the schema is SQLite DDL). This module turns one OPEN's result into the
|
|
6
|
+
* portable {@link MigrationRunner}: what this open applied, and a way to re-read the backend's own
|
|
7
|
+
* version without applying anything.
|
|
8
|
+
*
|
|
9
|
+
* @module dbdrivers/sqlite/migrations
|
|
10
|
+
*/
|
|
11
|
+
import { type MigrationResult } from '../../db/migrations.js';
|
|
12
|
+
import type { Db } from '../../db/port.js';
|
|
13
|
+
import type { MigrationRunner } from '../../interfaces/migrations.js';
|
|
14
|
+
/** The runner for one open connection. `migration` is what the open itself reports. */
|
|
15
|
+
export declare function createMigrationRunner(db: Db, migration: MigrationResult): MigrationRunner;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SQLite RELATION graph repositories (entities, triples, edges).
|
|
3
|
+
*
|
|
4
|
+
* The graph's SQL lives in `db/graph.ts` (shared with the migration/backfill code) and in
|
|
5
|
+
* `EntitiesDao`/`TriplesDao`; this file is the driver's implementation of the port shapes, including
|
|
6
|
+
* the `GraphReader` the relation planner walks (built in-memory over this connection).
|
|
7
|
+
*
|
|
8
|
+
* @module dbdrivers/sqlite/relations
|
|
9
|
+
*/
|
|
10
|
+
import type { MemoryKind, TimeFilter } from '../../../mem-contract/index.js';
|
|
11
|
+
import type { Db } from '../../db/port.js';
|
|
12
|
+
import { deleteEdgesForFact, graphCoverage, rebuildEdgesForFact, reextractEdges, writeEdgesForFact, writeExplicitEdgesForFact } from '../../db/graph.js';
|
|
13
|
+
import { type TimeRange } from '../../store/time_filter.js';
|
|
14
|
+
import { MemoryGraphReader } from '../../store/graph_reader.js';
|
|
15
|
+
import { registerEntityAliasesFromText, type RelationCandidate } from '../../relations/index.js';
|
|
16
|
+
import { explicitRelationTriples } from '../../store/explicit_relations.js';
|
|
17
|
+
import type { EntitiesDao, TriplesDao } from './dao/index.js';
|
|
18
|
+
import type { EntityRepository, FactContainingPage, FactsContainingAllQuery, RelationRepository, TripleRepository } from '../../interfaces/repositories.js';
|
|
19
|
+
export declare class SqliteEntityRepository implements EntityRepository {
|
|
20
|
+
private readonly dao;
|
|
21
|
+
constructor(dao: EntitiesDao);
|
|
22
|
+
linkFact(factId: number, entities: Parameters<EntitiesDao['linkFact']>[1]): void;
|
|
23
|
+
unlinkFact(factId: number): void;
|
|
24
|
+
namesForFact(factId: number): string[];
|
|
25
|
+
bagsForFacts(ids: readonly number[]): Map<number, string[]>;
|
|
26
|
+
activeDocFrequency(names: readonly string[]): Map<string, number>;
|
|
27
|
+
candidateFactsForAnyEntity(names: readonly string[], kind: MemoryKind | undefined, limit: number, queryWidth: number, widthCap: number, source?: string, time?: TimeRange): number[];
|
|
28
|
+
factEntitiesIn(text: string): ReturnType<EntitiesDao['factEntitiesIn']>;
|
|
29
|
+
factsContainingAll(query: FactsContainingAllQuery): FactContainingPage;
|
|
30
|
+
}
|
|
31
|
+
export declare class SqliteTripleRepository implements TripleRepository {
|
|
32
|
+
private readonly dao;
|
|
33
|
+
constructor(dao: TriplesDao);
|
|
34
|
+
insertMany(factId: number, triples: Parameters<TriplesDao['insertMany']>[1]): void;
|
|
35
|
+
listForFact(factId: number): ReturnType<TriplesDao['listForFact']>;
|
|
36
|
+
deleteForFact(factId: number): void;
|
|
37
|
+
}
|
|
38
|
+
export declare class SqliteRelationRepository implements RelationRepository {
|
|
39
|
+
private readonly db;
|
|
40
|
+
readonly entities: EntityRepository;
|
|
41
|
+
readonly triples: TripleRepository;
|
|
42
|
+
constructor(db: Db, entities: EntitiesDao, triples: TriplesDao);
|
|
43
|
+
explicitRelationTriples(kind: MemoryKind, relations: Parameters<typeof explicitRelationTriples>[2]): RelationCandidate[];
|
|
44
|
+
registerEntityAliasesFromText(text: string, knownNames: readonly string[]): ReturnType<typeof registerEntityAliasesFromText>;
|
|
45
|
+
explicitRelationsForFact(factId: number): {
|
|
46
|
+
subject: string;
|
|
47
|
+
predicate: string;
|
|
48
|
+
object: string;
|
|
49
|
+
}[];
|
|
50
|
+
writeEdgesForFact(factId: number, triples: Parameters<typeof writeEdgesForFact>[2], options?: Parameters<typeof writeEdgesForFact>[3]): ReturnType<typeof writeEdgesForFact>;
|
|
51
|
+
writeExplicitEdgesForFact(factId: number, relations: Parameters<typeof writeExplicitEdgesForFact>[2]): ReturnType<typeof writeExplicitEdgesForFact>;
|
|
52
|
+
deleteEdgesForFact(factId: number, options?: Parameters<typeof deleteEdgesForFact>[2]): number;
|
|
53
|
+
rebuildEdgesForFact(factId: number, kind: string): ReturnType<typeof rebuildEdgesForFact>;
|
|
54
|
+
reextractEdges(options?: Parameters<typeof reextractEdges>[1]): ReturnType<typeof reextractEdges>;
|
|
55
|
+
ensureVocabulary(): void;
|
|
56
|
+
coverage(options?: Parameters<typeof graphCoverage>[1]): ReturnType<typeof graphCoverage>;
|
|
57
|
+
graphReader(filter?: {
|
|
58
|
+
kind?: MemoryKind;
|
|
59
|
+
source?: string;
|
|
60
|
+
time?: TimeFilter;
|
|
61
|
+
}): MemoryGraphReader;
|
|
62
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SQLite FULL-TEXT/TITLE search index (DB-3).
|
|
3
|
+
*
|
|
4
|
+
* Everything the store is not allowed to know lives here: the FTS5 tables, their tokenizers, the
|
|
5
|
+
* `MATCH` expression builder and the short-query `LIKE` fallback. The store hands over the QUERY and
|
|
6
|
+
* receives hits whose `rank` is already normalized to "higher is better" — SQLite's `bm25` is
|
|
7
|
+
* negative, the substring predicate's term count is positive, and both leave this class in one
|
|
8
|
+
* convention so the store's floors and the fusion never branch on which path answered.
|
|
9
|
+
*
|
|
10
|
+
* The tokenizer of each table is DETECTED from the table's own DDL: `CREATE VIRTUAL TABLE IF NOT
|
|
11
|
+
* EXISTS` never rebuilds an existing table, so a database carried across SQLite builds keeps the
|
|
12
|
+
* tokenizer it was born with (see `db/tokenizer.ts`).
|
|
13
|
+
*
|
|
14
|
+
* @module dbdrivers/sqlite/search
|
|
15
|
+
*/
|
|
16
|
+
import type { Db } from '../../db/port.js';
|
|
17
|
+
import type { FactsDao } from './dao/index.js';
|
|
18
|
+
import type { ExactContentQuery, ExactTitleQuery, SearchHit, SearchIndex, SearchScope, TitleMatch, TitleQuery, TimeWindowQuery } from '../../interfaces/search_index.js';
|
|
19
|
+
export declare class SqliteSearchIndex implements SearchIndex {
|
|
20
|
+
private readonly db;
|
|
21
|
+
private readonly dao;
|
|
22
|
+
private readonly contentTokenizer;
|
|
23
|
+
private readonly titleTokenizer;
|
|
24
|
+
constructor(db: Db, dao: FactsDao);
|
|
25
|
+
/**
|
|
26
|
+
* The content leg: the FTS index when the table's tokenizer can express the query, the substring
|
|
27
|
+
* fallback when the query has no term the trigram vocabulary can hold (a 2-char CJK run — see
|
|
28
|
+
* `db/tokenizer.ts#buildFtsQuery` and `store/lexical.ts#substringTerms`).
|
|
29
|
+
*/
|
|
30
|
+
searchContent(query: string, scope?: SearchScope, limit?: number): SearchHit[];
|
|
31
|
+
countContentContaining(query: ExactContentQuery): number;
|
|
32
|
+
contentContainingRows(query: ExactContentQuery & {
|
|
33
|
+
limit: number;
|
|
34
|
+
offset: number;
|
|
35
|
+
}): number[];
|
|
36
|
+
countTitleEqual(query: ExactTitleQuery): number;
|
|
37
|
+
titleEqualRows(query: ExactTitleQuery & {
|
|
38
|
+
limit: number;
|
|
39
|
+
offset: number;
|
|
40
|
+
}): TitleMatch[];
|
|
41
|
+
/**
|
|
42
|
+
* The pure time window: the DAO owns both halves (the predicate AND the ORDER BY axis), so the
|
|
43
|
+
* domain `TimeRange` travels through untouched instead of being compiled here.
|
|
44
|
+
*/
|
|
45
|
+
countInTimeWindow(query: TimeWindowQuery): number;
|
|
46
|
+
timeWindowRows(query: TimeWindowQuery & {
|
|
47
|
+
limit: number;
|
|
48
|
+
offset: number;
|
|
49
|
+
}): number[];
|
|
50
|
+
/**
|
|
51
|
+
* The title index, with its own fallback: an FTS5 MATCH when `titleFtsQuery` can express the
|
|
52
|
+
* query, the `title LIKE` scan otherwise (a 1–2 character keyword, or a unicode61 table).
|
|
53
|
+
*/
|
|
54
|
+
searchTitles(query: TitleQuery): TitleMatch[];
|
|
55
|
+
rebuild(): void;
|
|
56
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SQLite PROVENANCE repository (`fact_sources`).
|
|
3
|
+
*
|
|
4
|
+
* `classifyRef` is pure (`kind:` prefix → kind + ref) and stays with the rows it classifies, so the
|
|
5
|
+
* classification a write performs and the rows it lands cannot drift.
|
|
6
|
+
*
|
|
7
|
+
* @module dbdrivers/sqlite/sources
|
|
8
|
+
*/
|
|
9
|
+
import { type FactSourcesDao } from './dao/index.js';
|
|
10
|
+
import type { FactSource, FactSourceKind, SourceRepository } from '../../interfaces/repositories.js';
|
|
11
|
+
export declare class SqliteSourceRepository implements SourceRepository {
|
|
12
|
+
private readonly dao;
|
|
13
|
+
constructor(dao: FactSourcesDao);
|
|
14
|
+
classifyRef(sourceRef: string): {
|
|
15
|
+
kind: FactSourceKind;
|
|
16
|
+
ref: string;
|
|
17
|
+
};
|
|
18
|
+
insert(factId: number, kind: FactSourceKind, ref: string): void;
|
|
19
|
+
listForFact(factId: number): FactSource[];
|
|
20
|
+
activeCoverage(): {
|
|
21
|
+
active: number;
|
|
22
|
+
facts_with_source: number;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The full-text/exact search adapter (DB-3).
|
|
27
|
+
*
|
|
28
|
+
* Everything the store is not allowed to know lives here: the FTS5 tables, their tokenizers, the
|
|
29
|
+
* `MATCH` expression builder and the short-query `LIKE` fallback. The store hands over the QUERY and
|
|
30
|
+
* receives hits whose `rank` is already normalized to "higher is better" — SQLite's `bm25` is
|
|
31
|
+
* negative, the substring predicate's term count is positive, and both leave this class in one
|
|
32
|
+
* convention so the store's floors and the fusion never branch on which path answered.
|
|
33
|
+
*
|
|
34
|
+
* The tokenizer of each table is DETECTED from the table's own DDL: `CREATE VIRTUAL TABLE IF NOT
|
|
35
|
+
* EXISTS` never rebuilds an existing table, so a database carried across SQLite builds keeps the
|
|
36
|
+
* tokenizer it was born with (see `db/tokenizer.ts`).
|
|
37
|
+
*/
|
|
@@ -7,9 +7,8 @@
|
|
|
7
7
|
* - `DEFAULT_SEARCH_LIMIT` — `query`'s own input schema carries `.default(10)`
|
|
8
8
|
* (`contract/src/tools.ts`), and the recall actions' descriptions say "默认 10"; the recall union
|
|
9
9
|
* itself is `.optional()`, so the engine is what applies it. It reaches `hybridSearch` (a
|
|
10
|
-
* non-finite limit)
|
|
11
|
-
* - `DEFAULT_LIST_LIMIT` — the documented page for `admin list`
|
|
12
|
-
* "缺省 50", same file).
|
|
10
|
+
* non-finite limit).
|
|
11
|
+
* - `DEFAULT_LIST_LIMIT` — the documented page for `admin list` ("默认 50").
|
|
13
12
|
*
|
|
14
13
|
* The cross-layer equation is pinned by `test/hybrid.spec.ts` against the contract's parsed schema,
|
|
15
14
|
* so a contract default moving and this constant not moving is a red test rather than a silent
|
|
@@ -21,5 +20,5 @@
|
|
|
21
20
|
*/
|
|
22
21
|
/** Page of a recall/query result when the caller gave no usable `limit`. */
|
|
23
22
|
export declare const DEFAULT_SEARCH_LIMIT = 10;
|
|
24
|
-
/** Page of a listing surface (`admin list
|
|
23
|
+
/** Page of a listing surface (`admin list`) when the caller gave no `limit`. */
|
|
25
24
|
export declare const DEFAULT_LIST_LIMIT = 50;
|
|
@@ -4,41 +4,16 @@
|
|
|
4
4
|
*
|
|
5
5
|
* It lives here rather than in each adapter because the key set is owned by the contract's
|
|
6
6
|
* `TOOL_SPECS`, and an adapter that hand-writes its own switch rots silently when a spec is added.
|
|
7
|
-
* That is a measured failure, not a hypothetical:
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* "every advertised key dispatches" instead of trusting a hand-maintained list.
|
|
7
|
+
* That is a measured failure, not a hypothetical: a tool advertised by one surface's tool list while
|
|
8
|
+
* its dispatcher knew only the older keys answers `unknown tool key` — a tool that is listed,
|
|
9
|
+
* callable, and always broken. One table keyed by the contract, plus {@link supportsToolKey} so a
|
|
10
|
+
* spec test can assert "every advertised key dispatches" instead of trusting a hand-maintained list.
|
|
12
11
|
*
|
|
13
12
|
* `ToolSpec.key` is typed `string` (not a literal union), so exhaustiveness cannot be checked at
|
|
14
13
|
* compile time — the spec assertion is the gate.
|
|
15
14
|
*/
|
|
16
|
-
import type {
|
|
17
|
-
import type { AvantfRuntime } from './runtime.js';
|
|
18
|
-
/**
|
|
19
|
-
* The default page for a model-facing `kb_list` — the SAME page the operator's `admin list` uses.
|
|
20
|
-
*
|
|
21
|
-
* Without one, `kb_list` on a large library read and parsed EVERY managed file (resolving a path
|
|
22
|
-
* needs the file's frontmatter to detect collisions) to answer a question nobody asked in full. The
|
|
23
|
-
* two surfaces were separate literals; the contract documents both as 50, so they are one constant
|
|
24
|
-
* (`src/defaults.ts`).
|
|
25
|
-
*/
|
|
26
|
-
export declare const KB_LIST_DEFAULT_LIMIT = 50;
|
|
27
|
-
/**
|
|
28
|
-
* The `kb_add` handler: a thin shell over the runtime's ADD-ONLY face (`rt.kbAdd`), which shares the
|
|
29
|
-
* store's plan/classify/dispatch entry with the UI's 入库 (`rt.kb`) and differs only in the mode.
|
|
30
|
-
*
|
|
31
|
-
* This is the fix for a measured failure: told to "update the KB", a model called the old all-in-one
|
|
32
|
-
* tool with a *new* title, which silently created a sibling document (《… · 补遗》) while the
|
|
33
|
-
* original stayed behind — two overlapping documents, and the reader left to reconcile them.
|
|
34
|
-
* Replacing is now an explicit file edit.
|
|
35
|
-
*
|
|
36
|
-
* The refusal itself lives in the STORE (the plan stage), not here: a pre-check in this handler used
|
|
37
|
-
* to derive the title as `req.title ?? req.source`, which is exactly the fallback the store no
|
|
38
|
-
* longer uses — so once the store derives an untitled paste from its body, a local pre-check would
|
|
39
|
-
* check a different identity than the one the store actually writes.
|
|
40
|
-
*/
|
|
41
|
-
export declare function kbAdd(rt: AvantfRuntime, data: KbAddRequest): Promise<unknown>;
|
|
15
|
+
import type { ToolEnvelope, ToolSpec } from '../mem-contract/index.js';
|
|
16
|
+
import type { AvantfRuntime, RememberWriteRules } from './runtime.js';
|
|
42
17
|
/** Whether {@link dispatchToolKey} can answer this contract tool key. */
|
|
43
18
|
export declare function supportsToolKey(key: string): boolean;
|
|
44
19
|
/**
|
|
@@ -50,7 +25,7 @@ export declare function supportsToolKey(key: string): boolean;
|
|
|
50
25
|
* rather than returning a payload, so a surface cannot mistake it for a successful empty result —
|
|
51
26
|
* both adapters route the throw through their structured error envelope.
|
|
52
27
|
*/
|
|
53
|
-
export declare function dispatchToolKey(rt: AvantfRuntime, key: string, args: Record<string, unknown
|
|
28
|
+
export declare function dispatchToolKey(rt: AvantfRuntime, key: string, args: Record<string, unknown>, rules?: RememberWriteRules): Promise<unknown>;
|
|
54
29
|
/**
|
|
55
30
|
* The ONE model-facing boundary: validate against the contract spec, dispatch the key, and shape the
|
|
56
31
|
* result into the agent envelope.
|