@wirecat/cli-core 0.498.0 → 0.500.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/dist/calendar/mcp/index.d.ts +12 -12
  3. package/dist/cli/messenger/hearing-command.js +1 -1
  4. package/dist/cli/messenger/models-command.js +2 -2
  5. package/dist/cli/messenger/transcribe-command.js +14 -10
  6. package/dist/cli/runs/command.js +2 -1
  7. package/dist/domain/knowledge.d.ts +1 -1
  8. package/dist/domain/knowledge.js +1 -1
  9. package/dist/entities/fact.d.ts +15 -1
  10. package/dist/entities/fact.js +6 -1
  11. package/dist/entities/fields.d.ts +11 -0
  12. package/dist/entities/fields.js +11 -0
  13. package/dist/entities/index.d.ts +25 -1
  14. package/dist/entities/memory.d.ts +14 -0
  15. package/dist/entities/memory.js +6 -1
  16. package/dist/errors/reasons.d.ts +1 -1
  17. package/dist/errors/reasons.js +8 -0
  18. package/dist/meetings/transcription.d.ts +5 -0
  19. package/dist/meetings/transcription.js +27 -6
  20. package/dist/speech/decode.d.ts +11 -1
  21. package/dist/speech/decode.js +20 -15
  22. package/dist/speech/hearing.d.ts +3 -1
  23. package/dist/speech/hearing.js +4 -4
  24. package/dist/speech/index.d.ts +5 -2
  25. package/dist/speech/index.js +4 -2
  26. package/dist/speech/local.d.ts +8 -0
  27. package/dist/speech/local.js +22 -1
  28. package/dist/speech/models.d.ts +2 -0
  29. package/dist/speech/models.js +2 -0
  30. package/dist/speech/openai.d.ts +54 -0
  31. package/dist/speech/openai.js +199 -0
  32. package/dist/speech/recognize.d.ts +25 -1
  33. package/dist/speech/recognize.js +52 -21
  34. package/dist/speech/transcribe.d.ts +25 -9
  35. package/dist/speech/transcribe.js +72 -13
  36. package/dist/speech/wav.d.ts +2 -0
  37. package/dist/speech/wav.js +20 -0
  38. package/dist/store/index.d.ts +1 -0
  39. package/dist/store/project-transfer/request.d.ts +1 -1
  40. package/dist/store/project-transfer/schema.d.ts +2 -2
  41. package/dist/store/project-transfer/snapshot-model.d.ts +2 -2
  42. package/dist/store/sqlite/evidence-sources.d.ts +23 -0
  43. package/dist/store/sqlite/evidence-sources.js +59 -0
  44. package/dist/store/sqlite/facts.d.ts +16 -0
  45. package/dist/store/sqlite/facts.js +39 -5
  46. package/dist/store/sqlite/memories.d.ts +28 -0
  47. package/dist/store/sqlite/memories.js +62 -3
  48. package/dist/store/sqlite/project-transfer/snapshot.d.ts +1 -1
  49. package/package.json +1 -1
@@ -2,6 +2,7 @@ import { CliError } from "@wirecat/cli-base";
2
2
  import { MEMORY_KINDS, MEMORY_SCOPES } from "../../domain/knowledge.js";
3
3
  import { normalize } from "../normalize.js";
4
4
  import { botNamed, ownerPerson } from "./actors.js";
5
+ import { evidenceSourcesOf } from "./evidence-sources.js";
5
6
  import { linkKind } from "./link-kinds.js";
6
7
  import { CORPORA, corpusIndexState, drainCorpus } from "./note-index.js";
7
8
  import { requiredThing } from "./notes.js";
@@ -42,6 +43,55 @@ export const evidenceOf = (context, from) => context.database
42
43
  .prepare(`SELECT to_type, to_id FROM links WHERE from_type = ? AND from_id = ? AND kind = ${linkKind("evidence")} AND to_id IS NOT NULL ORDER BY id`)
43
44
  .all(from.type, from.id)
44
45
  .flatMap((row) => referenceOfThing(context.database, storedThing(row.to_type, row.to_id)) ?? []);
46
+ const SUBJECT_NAMES = {
47
+ person: "SELECT p.owner, coalesce(p.name, (SELECT a.name FROM aliases a WHERE a.aliasable_type = 'person' " +
48
+ "AND a.aliasable_id = p.id ORDER BY a.display DESC, a.id LIMIT 1), (SELECT i.name FROM identity_links l " +
49
+ "JOIN identities i ON i.id = l.identity_id WHERE l.person_id = p.id AND i.name IS NOT NULL ORDER BY i.id LIMIT 1)) " +
50
+ "AS name FROM persons p WHERE p.id = ?",
51
+ project: "SELECT 0 AS owner, name FROM projects WHERE id = ?",
52
+ organization: "SELECT 0 AS owner, name FROM organizations WHERE id = ?",
53
+ };
54
+ /** What a memory's or fact's subject is called, for a reader who should not have to look the reference up. */
55
+ export const subjectOf = (database, row) => {
56
+ if (row.subject_type == null)
57
+ return { subject: null, subjectName: null, subjectIsOwner: false };
58
+ const thing = storedThing(row.subject_type, row.subject_id);
59
+ const read = SUBJECT_NAMES[thing.type];
60
+ const named = read === undefined ? undefined : database.prepare(read).get(thing.id);
61
+ return {
62
+ subject: referenceOfThing(database, thing) ?? null,
63
+ subjectName: named?.name == null ? null : String(named.name),
64
+ subjectIsOwner: Number(named?.owner) === 1,
65
+ };
66
+ };
67
+ /** Counts every link from or to a row and drops the ones its delete trigger does not: those pointing at it. */
68
+ export const dropLinksOf = (database, thing) => {
69
+ const count = Number(database
70
+ .prepare("SELECT count(*) AS n FROM links WHERE (from_type = ? AND from_id = ?) OR (to_type = ? AND to_id = ?)")
71
+ .get(thing.type, thing.id, thing.type, thing.id)?.n);
72
+ database.prepare("DELETE FROM links WHERE to_type = ? AND to_id = ?").run(thing.type, thing.id);
73
+ return count;
74
+ };
75
+ /**
76
+ * Runs a delete so the text does not linger in the file: freed pages are zeroed, the words indexes merged so no
77
+ * segment still holds the erased words, and the write-ahead log emptied when no reader holds it.
78
+ */
79
+ export const erase = (database, work) => {
80
+ database.exec("PRAGMA secure_delete = ON");
81
+ try {
82
+ const done = write(database, () => {
83
+ const result = work();
84
+ for (const index of ["memory_words", "memory_stems"])
85
+ database.prepare(`INSERT INTO ${index} (${index}) VALUES ('optimize')`).run();
86
+ return result;
87
+ });
88
+ database.exec("PRAGMA wal_checkpoint(TRUNCATE)");
89
+ return done;
90
+ }
91
+ finally {
92
+ database.exec("PRAGMA secure_delete = OFF");
93
+ }
94
+ };
45
95
  export const memoriesStoreOver = (context) => {
46
96
  const { database, now } = context;
47
97
  const stemmerFor = stemmerCache();
@@ -50,9 +100,7 @@ export const memoriesStoreOver = (context) => {
50
100
  ref: `memory:${row.id}`,
51
101
  kind: row.kind,
52
102
  body: String(row.body),
53
- subject: row.subject_type == null
54
- ? null
55
- : (referenceOfThing(database, storedThing(row.subject_type, row.subject_id)) ?? null),
103
+ ...subjectOf(database, row),
56
104
  author: authorOf(row),
57
105
  model: row.model == null ? null : String(row.model),
58
106
  confidence: row.confidence == null ? null : Number(row.confidence),
@@ -127,6 +175,17 @@ export const memoriesStoreOver = (context) => {
127
175
  },
128
176
  confirm: async (reference) => setStatus(reference, "confirmed", true),
129
177
  markStale: async (reference) => setStatus(reference, "stale", false),
178
+ remove: async (reference) => {
179
+ const id = Number(rowOf(reference).id);
180
+ const links = erase(database, () => {
181
+ database.prepare("UPDATE memories SET supersedes_id = NULL WHERE supersedes_id = ?").run(id);
182
+ const count = dropLinksOf(database, { type: "memory", id });
183
+ database.prepare("DELETE FROM memories WHERE id = ?").run(id);
184
+ return count;
185
+ });
186
+ return { ref: `memory:${id}`, removed: true, links };
187
+ },
188
+ sources: async (reference) => evidenceSourcesOf(database, { type: "memory", id: Number(rowOf(reference).id) }),
130
189
  search: async (text, { subject: subjectRef, scope, limit = 20 } = {}) => {
131
190
  const subject = subjectRef === undefined ? undefined : requiredThing(database, subjectRef);
132
191
  drainCorpus(database, CORPORA.memory, stemmerFor);
@@ -7,7 +7,7 @@ export declare const projectAnnotationSnapshot: (database: CacheDatabase, projec
7
7
  ref: string;
8
8
  type: "decision" | "fact" | "promise" | "question" | "statement";
9
9
  statement: string;
10
- status: "accepted" | "proposed" | "reversed" | "superseded";
10
+ status: "accepted" | "proposed" | "rejected" | "reversed" | "superseded";
11
11
  subject: string | null;
12
12
  occurred_at: number | null;
13
13
  supersedes: string | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wirecat/cli-core",
3
- "version": "0.498.0",
3
+ "version": "0.500.0",
4
4
  "description": "The messenger-neutral half of a messaging CLI: domain model, message locators, rendering, name resolution, the SQLite seam, the command skeleton and shared read commands, the send guard, run records and the message store",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Viacheslav Ptsarev",