@sigrun/knowledge 0.0.0-stage → 0.1.1
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/CHANGELOG.md +82 -0
- package/LICENSE +21 -0
- package/README.md +83 -2
- package/dist/apply.d.ts +56 -0
- package/dist/apply.js +554 -0
- package/dist/audience.d.ts +12 -0
- package/dist/audience.js +26 -0
- package/dist/card.d.ts +15 -0
- package/dist/card.js +83 -0
- package/dist/config.d.ts +15 -0
- package/dist/config.js +44 -0
- package/dist/db.d.ts +18 -0
- package/dist/db.js +156 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +52 -0
- package/dist/maintain.d.ts +21 -0
- package/dist/maintain.js +585 -0
- package/dist/mirror.d.ts +41 -0
- package/dist/mirror.js +59 -0
- package/dist/prompts.d.ts +6 -0
- package/dist/prompts.js +16 -0
- package/dist/research.d.ts +46 -0
- package/dist/research.js +81 -0
- package/dist/schema.d.ts +44 -0
- package/dist/schema.js +145 -0
- package/dist/target.d.ts +23 -0
- package/dist/target.js +29 -0
- package/dist/tools.d.ts +45 -0
- package/dist/tools.js +357 -0
- package/dist/undo.d.ts +16 -0
- package/dist/undo.js +335 -0
- package/package.json +57 -5
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Everything below, released as 0.1.0: the full knowledge extension —
|
|
13
|
+
store, atomic versioned apply/undo, tools, the curation target, the
|
|
14
|
+
research flag, recall mirroring and the idle pass.
|
|
15
|
+
|
|
16
|
+
### Fixed (post-merge follow-ups)
|
|
17
|
+
|
|
18
|
+
- Idle pass: a kept child type's identity-key rows re-root by its
|
|
19
|
+
entities, not by the child's own type id — a child type's rows live at
|
|
20
|
+
its family root (the grandparent), so the old select missed them and a
|
|
21
|
+
later record for the same key minted a duplicate entity.
|
|
22
|
+
- Mirroring: a rejected `recall.index` call logs one line (the silent
|
|
23
|
+
skip hid every mirror failure — including the card-date format bug the
|
|
24
|
+
e2e later caught).
|
|
25
|
+
|
|
26
|
+
## [0.1.1] - 2026-11-05
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- First registry release. 0.1.0 was consumed by the npm stage
|
|
31
|
+
bootstrap (the name-claiming placeholder) and never published; 0.1.1
|
|
32
|
+
is the identical tree.
|
|
33
|
+
|
|
34
|
+
### Added
|
|
35
|
+
|
|
36
|
+
- Package scaffold: `createKnowledge(host, deps?)` factory returning
|
|
37
|
+
`defineExtension({ name: "@sigrun/knowledge" })`, arity 1, with lazily
|
|
38
|
+
opened per-user databases closed on `harnessShutdown`.
|
|
39
|
+
- `src/schema.ts`: the field-schema subset (`FieldType`, `FieldDef`,
|
|
40
|
+
`TypeDef`, `TypeDefSchema`, `validateValue`).
|
|
41
|
+
- `src/db.ts`: `KnowledgeDb` — types / entities / entity_keys / inquiries /
|
|
42
|
+
roles / versions / applied / maintenance tables plus
|
|
43
|
+
`transaction` (BEGIN IMMEDIATE / COMMIT / ROLLBACK) and `close`.
|
|
44
|
+
- `src/config.ts`: `resolveUserSettings` (researchTools glob list with
|
|
45
|
+
warn-once fallback) and `matchesGlob` (`*` only).
|
|
46
|
+
- `src/apply.ts` / `src/undo.ts` / `src/card.ts`: `applyRecord` (one
|
|
47
|
+
transaction, whole-record validation, entity de-duplication by
|
|
48
|
+
identity-key pairs within a type family, idempotent replay by call id),
|
|
49
|
+
`undoChange` (newest-first row-equality restores, versioned under
|
|
50
|
+
`undo:<changeId>`, create-archive and skip reporting), `retypeEntities`,
|
|
51
|
+
and `renderCard` (stale marks past `horizonDays`).
|
|
52
|
+
- `src/tools.ts`: `knowledge_record` (target tool, replay-safe, idempotent
|
|
53
|
+
by call id; inquiry records the reviewed parent conversation through the
|
|
54
|
+
fork-ancestry paging lookup) and `knowledge_find` (read tool — batched
|
|
55
|
+
type/field/inquiry/text queries; text via `recall.search` with LIKE
|
|
56
|
+
fallback; audience rule first; local-only entities never shown).
|
|
57
|
+
- `src/target.ts`: the `knowledge` curation target — guidance, undo
|
|
58
|
+
(revert + re-mirror), wantsReview/reviewed on the research flag,
|
|
59
|
+
`maintain` (the idle pass: re-index pending/stale entities, continue
|
|
60
|
+
unfinished re-typing, propose one generalization per pass — ≥3
|
|
61
|
+
overlapping siblings into a shared parent, folding field-less
|
|
62
|
+
children, ≤50 retypes per pass).
|
|
63
|
+
- `src/research.ts`: the `afterTool` research flag (`<user
|
|
64
|
+
state>/research.json`) with the 15-minute single-request window.
|
|
65
|
+
- `src/mirror.ts`: recall mirroring after apply/undo — `recall.index`
|
|
66
|
+
(kind `record`) or `recall.remove` for archived entities; failure
|
|
67
|
+
leaves `indexedAt` behind the last version for the idle pass.
|
|
68
|
+
- `src/audience.ts`: the audience rule (private copy of recall's).
|
|
69
|
+
- `src/prompts.ts`: the review guidance bullets.
|
|
70
|
+
- `src/maintain.ts`: the idle pass implementation (generalize sibling
|
|
71
|
+
types into a hierarchy with versioned key re-roots, declined-group
|
|
72
|
+
memory, collision-drop cleanup).
|
|
73
|
+
|
|
74
|
+
### Dependencies
|
|
75
|
+
|
|
76
|
+
- `@sigrun/shared` peer accepts `0.5.0 || 0.6.0 || 0.6.1 || 0.7.0 ||
|
|
77
|
+
0.8.0` (the runtime value imports landed on 0.5.0; recall made the
|
|
78
|
+
same widening).
|
|
79
|
+
|
|
80
|
+
<!-- TODO at release time: pin `@sigrun/sigrun` and `@sigrun/shared` to
|
|
81
|
+
the releases carrying published hooks and curation targets (core
|
|
82
|
+
0.9.0 line, when cut). -->
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Michael MacLeod
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,84 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @sigrun/knowledge
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Curated per-user knowledge extension for [sigrun](https://github.com/sigrun-ai/sigrun).
|
|
4
|
+
|
|
5
|
+
This package owns one SQLite store per directory user
|
|
6
|
+
(`<user data dir>/knowledge.db`) holding typed knowledge entities, identity
|
|
7
|
+
keys, inquiries, and the version history that makes every change undoable.
|
|
8
|
+
|
|
9
|
+
## Tools
|
|
10
|
+
|
|
11
|
+
- **`knowledge_record`** (curation target tool, `replay: "safe"`,
|
|
12
|
+
idempotent by call id): one call carries the whole update from a review —
|
|
13
|
+
the inquiry (question, why, outcome), any new or extended types, and the
|
|
14
|
+
entities with identity keys, cited fields (`{value, source, observedAt}`
|
|
15
|
+
where `source` is a recall handle), and per-inquiry roles. Applied
|
|
16
|
+
atomically; validation errors roll everything back and are reported as
|
|
17
|
+
text with no `details.curation`. Success returns the one-line summary
|
|
18
|
+
(`recorded Biscuit's knee: 3 vet clinics`) as the output text and
|
|
19
|
+
`details.curation: { changeId, summary }` — the undo unit.
|
|
20
|
+
|
|
21
|
+
The user is the conversation's acting user (the review fork's owner).
|
|
22
|
+
The inquiry records the *reviewed parent* conversation, resolved by
|
|
23
|
+
paging the fork's entries newest-first until an entry stamped with a
|
|
24
|
+
different conversation id appears.
|
|
25
|
+
|
|
26
|
+
- **`knowledge_find`** (read tool, never a target tool): batched queries
|
|
27
|
+
(≤ 10) by `type` (child types included), by `field` comparison
|
|
28
|
+
(`eq`/`lt`/`gt`/`contains`; money compares amounts within one currency
|
|
29
|
+
only), by `inquiry` question text, or by free `text`. Text search goes
|
|
30
|
+
through the optional `recall.search` hook (keeping only knowledge's own
|
|
31
|
+
hits) and falls back to a `LIKE` scan when recall is absent or fails.
|
|
32
|
+
Entities with class `local-only` are never shown.
|
|
33
|
+
|
|
34
|
+
The audience rule (spec delta 7) runs first: in a shared conversation
|
|
35
|
+
the tool answers "Not available here." unless every reader may see the
|
|
36
|
+
user's knowledge — the user's own records are private to their
|
|
37
|
+
conversations.
|
|
38
|
+
|
|
39
|
+
## The curation target
|
|
40
|
+
|
|
41
|
+
The factory result declares one target:
|
|
42
|
+
`{ name: "knowledge", tools: ["knowledge_record"], readTools: ["knowledge_find"] }`.
|
|
43
|
+
|
|
44
|
+
- `guidance` — the review prompt bullets (record the inquiry and its why;
|
|
45
|
+
find before creating; cite every field; give fields that go out of date a
|
|
46
|
+
`horizonDays` — prices ~30, opening hours ~180, addresses none; record
|
|
47
|
+
the user's verdicts, never the agent's guesses).
|
|
48
|
+
- `undo` — reverts a change (row-level equality: only rows still equal to
|
|
49
|
+
what the change wrote are restored) and re-mirrors every touched entity.
|
|
50
|
+
- `wantsReview` / `reviewed` — drive the research flag (below).
|
|
51
|
+
- `maintain` — the idle pass: re-indexes up to 50 pending or
|
|
52
|
+
horizon-stale entities (mirroring them into recall), continues an
|
|
53
|
+
unfinished re-typing before proposing anything new, and proposes at
|
|
54
|
+
most ONE generalization per pass — ≥ 3 sibling types whose field
|
|
55
|
+
names overlap (pairwise Jaccard ≥ 0.5) become children of a new shared
|
|
56
|
+
parent type; a child left with no distinct fields is folded (its
|
|
57
|
+
entities re-typed, ≤ 50 per pass, extra values preserved in
|
|
58
|
+
`attributes`); identity-key rows re-root (versioned) so records keep
|
|
59
|
+
merging; declined groups are remembered for 30 days. The digest-run
|
|
60
|
+
budget bounds the pass and its runs.
|
|
61
|
+
|
|
62
|
+
## The research trigger
|
|
63
|
+
|
|
64
|
+
An `afterTool` hook watches non-internal conversations with an owner: when
|
|
65
|
+
a tool whose name matches the owner's `researchTools` globs (defaults to
|
|
66
|
+
web search/fetch/crawl tool names) runs, the conversation is flagged in
|
|
67
|
+
`<user state>/research.json`. The curator asks `wantsReview` at settle;
|
|
68
|
+
a flag with no request in the last 15 minutes answers true once (stamping
|
|
69
|
+
the request), `reviewed` clears it, and a review that never completes is
|
|
70
|
+
re-requested after the window. Errors are logged, never thrown, and the
|
|
71
|
+
hook never alters tool results.
|
|
72
|
+
|
|
73
|
+
The glob list is the per-user `researchTools` setting (`*` is the only
|
|
74
|
+
wildcard), e.g. `["searxng/search*", "web_fetch"]`.
|
|
75
|
+
|
|
76
|
+
## Recall mirroring (optional dependency)
|
|
77
|
+
|
|
78
|
+
After each apply or undo, every touched entity is mirrored into recall
|
|
79
|
+
through the published `recall.index` hook (`kind: "record"`, id = entity
|
|
80
|
+
id, title/text/date/sources from the review card); archived entities are
|
|
81
|
+
removed through `recall.remove`. On `ok` the returned class and the index
|
|
82
|
+
instant are stored; on `absent` nothing happens (knowledge works fully
|
|
83
|
+
without recall); on `failed`/`rejected` the entity's `indexedAt` stays
|
|
84
|
+
behind its last version so the next idle pass retries.
|
package/dist/apply.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { KnowledgeDb } from "./db.js";
|
|
2
|
+
import { type TypeDef } from "./schema.js";
|
|
3
|
+
declare const ENTITY_ROLES: readonly ["candidate", "shortlisted", "rejected", "chosen"];
|
|
4
|
+
export interface RecordInput {
|
|
5
|
+
inquiry?: {
|
|
6
|
+
id?: string;
|
|
7
|
+
question: string;
|
|
8
|
+
why?: string;
|
|
9
|
+
outcome?: {
|
|
10
|
+
status: "open" | "decided" | "abandoned";
|
|
11
|
+
what?: string;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
types?: TypeDef[];
|
|
15
|
+
entities: {
|
|
16
|
+
id?: string;
|
|
17
|
+
type: string;
|
|
18
|
+
name: string;
|
|
19
|
+
keys: Record<string, string>;
|
|
20
|
+
fields: Record<string, {
|
|
21
|
+
value: unknown;
|
|
22
|
+
source: string;
|
|
23
|
+
observedAt: string;
|
|
24
|
+
}>;
|
|
25
|
+
attributes?: Record<string, unknown>;
|
|
26
|
+
role?: (typeof ENTITY_ROLES)[number];
|
|
27
|
+
reason?: string;
|
|
28
|
+
}[];
|
|
29
|
+
}
|
|
30
|
+
export interface ApplyResult {
|
|
31
|
+
changeId: string;
|
|
32
|
+
summary: string;
|
|
33
|
+
/** Entity ids created or updated. */
|
|
34
|
+
touched: string[];
|
|
35
|
+
errors: string[];
|
|
36
|
+
}
|
|
37
|
+
export interface ApplyContext {
|
|
38
|
+
conversationId?: number;
|
|
39
|
+
callId: string;
|
|
40
|
+
now: number;
|
|
41
|
+
}
|
|
42
|
+
/** Normalize an identity key value for matching within a type family. */
|
|
43
|
+
export declare function normalizeKey(key: string, value: string): string;
|
|
44
|
+
/**
|
|
45
|
+
* Apply one knowledge record atomically. Any validation error rolls the
|
|
46
|
+
* whole record back and is reported in `errors`. Replaying an already
|
|
47
|
+
* applied `callId` returns the stored result unchanged.
|
|
48
|
+
*/
|
|
49
|
+
export declare function applyRecord(db: KnowledgeDb, input: RecordInput, ctx: ApplyContext): ApplyResult;
|
|
50
|
+
/**
|
|
51
|
+
* Move entities to a different type: field values the new type does not
|
|
52
|
+
* declare move into attributes, and identity keys re-root at the new
|
|
53
|
+
* type's family.
|
|
54
|
+
*/
|
|
55
|
+
export declare function retypeEntities(db: KnowledgeDb, entityIds: readonly string[], toType: string, changeId: string, now: number): void;
|
|
56
|
+
export {};
|