@dxos/assistant 0.9.1-staging.ee54ba693a → 0.11.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 (45) hide show
  1. package/dist/lib/extraction.mjs +169 -0
  2. package/dist/lib/extraction.mjs.map +1 -0
  3. package/dist/lib/index.mjs +1958 -0
  4. package/dist/lib/index.mjs.map +1 -0
  5. package/dist/types/src/request/AiRequest.d.ts +6 -3
  6. package/dist/types/src/request/AiRequest.d.ts.map +1 -1
  7. package/dist/types/src/request/AiRequest.test.d.ts +2 -0
  8. package/dist/types/src/request/AiRequest.test.d.ts.map +1 -0
  9. package/dist/types/src/request/format.d.ts +2 -2
  10. package/dist/types/src/request/format.d.ts.map +1 -1
  11. package/dist/types/src/request/format.test.d.ts +2 -0
  12. package/dist/types/src/request/format.test.d.ts.map +1 -0
  13. package/dist/types/src/session/AiContext.d.ts +1 -1
  14. package/dist/types/src/session/AiContext.d.ts.map +1 -1
  15. package/dist/types/src/session/AiSession.d.ts +25 -4
  16. package/dist/types/src/session/AiSession.d.ts.map +1 -1
  17. package/dist/types/src/session/harness-control.d.ts +4 -0
  18. package/dist/types/src/session/harness-control.d.ts.map +1 -1
  19. package/dist/types/src/tool-runtime/services.d.ts +7 -0
  20. package/dist/types/src/tool-runtime/services.d.ts.map +1 -1
  21. package/dist/types/src/tool-runtime/services.test.d.ts +2 -0
  22. package/dist/types/src/tool-runtime/services.test.d.ts.map +1 -0
  23. package/dist/types/src/util/execution-graph.d.ts.map +1 -1
  24. package/dist/types/src/util/tracing.d.ts +10 -0
  25. package/dist/types/src/util/tracing.d.ts.map +1 -1
  26. package/dist/types/tsconfig.tsbuildinfo +1 -1
  27. package/package.json +25 -25
  28. package/src/extraction/quotes.test.ts +4 -4
  29. package/src/request/AiRequest.test.ts +110 -0
  30. package/src/request/AiRequest.ts +11 -4
  31. package/src/request/format.test.ts +93 -0
  32. package/src/request/format.ts +48 -11
  33. package/src/session/AiContext.ts +1 -1
  34. package/src/session/AiSession.test.ts +124 -0
  35. package/src/session/AiSession.ts +81 -8
  36. package/src/tool-runtime/services.test.ts +41 -0
  37. package/src/tool-runtime/services.ts +16 -1
  38. package/src/util/execution-graph.ts +1 -1
  39. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +0 -10
  40. package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +0 -7
  41. package/dist/lib/neutral/extraction/index.mjs +0 -197
  42. package/dist/lib/neutral/extraction/index.mjs.map +0 -7
  43. package/dist/lib/neutral/index.mjs +0 -2047
  44. package/dist/lib/neutral/index.mjs.map +0 -7
  45. package/dist/lib/neutral/meta.json +0 -1
@@ -0,0 +1,169 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Schema from "effect/Schema";
3
+ import { AiService } from "@dxos/ai";
4
+ import { Filter, Obj, Query } from "@dxos/echo";
5
+ import { EID as EID$1, EntityId } from "@dxos/keys";
6
+ import { log } from "@dxos/log";
7
+ import { Message } from "@dxos/types";
8
+ import * as LanguageModel from "@effect/ai/LanguageModel";
9
+ import { pipeline } from "@xenova/transformers";
10
+ //#region src/extraction/quotes.ts
11
+ var ReferencedQuotes = Schema.Struct({ references: Schema.Array(Schema.Struct({
12
+ id: Schema.String,
13
+ quote: Schema.String
14
+ })).pipe(Schema.mutable).annotations({ description: `
15
+ The references to the context objects that are mentioned in the transcript.
16
+ Quote should match the original transcript text exactly, while id is the id of the context object.
17
+ ` }) });
18
+ /**
19
+ * Finds the best-matching context object for each noun and returns it as a reference.
20
+ */
21
+ var findReferences = async (nouns, db, { searchKind = "full-text" } = {}) => {
22
+ const normalizedNouns = Array.from(new Set(nouns.map((noun) => noun.trim()).filter((noun) => noun.length > 0))).sort((leftNoun, rightNoun) => rightNoun.length - leftNoun.length);
23
+ return { references: (await Promise.all(normalizedNouns.map(async (noun) => {
24
+ const objects = await db.query(Query.select(Filter.text(noun, { type: searchKind }))).run();
25
+ return objects.length > 0 ? [{
26
+ id: objects[0].id.toString(),
27
+ quote: noun
28
+ }] : [];
29
+ }))).flat() };
30
+ };
31
+ /**
32
+ * Finds and replaces all quotes with DXNs references.
33
+ */
34
+ var insertReferences = (text, quotes) => {
35
+ const references = quotes.references.filter((quote) => EntityId.isValid(quote.id)).sort((left, right) => right.quote.length - left.quote.length);
36
+ for (const quote of references) {
37
+ const regex = new RegExp(quote.quote.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "gi");
38
+ text = replaceOutsideLinks(text, regex, `[${quote.quote}](${EID$1.make({ entityId: quote.id })})`);
39
+ }
40
+ return text;
41
+ };
42
+ var MARKDOWN_LINK = /\[[^\]]*\]\([^)]*\)/g;
43
+ /** Applies a replacement to every span of `text` that is not already inside a `[label](url)` link. */
44
+ var replaceOutsideLinks = (text, regex, replacement) => {
45
+ let result = "";
46
+ let plainStart = 0;
47
+ for (const link of text.matchAll(MARKDOWN_LINK)) {
48
+ const index = link.index ?? 0;
49
+ result += text.slice(plainStart, index).replace(regex, replacement) + link[0];
50
+ plainStart = index + link[0].length;
51
+ }
52
+ return result + text.slice(plainStart).replace(regex, replacement);
53
+ };
54
+ //#endregion
55
+ //#region src/extraction/extraction-llm-function/proper-noun-extraction.ts
56
+ var EXTRACTION_MODEL = "com.anthropic.model.claude-haiku-4-5.default";
57
+ /**
58
+ * Proper nouns extracted from transcript text.
59
+ */
60
+ var ProperNouns = Schema.Struct({ properNouns: Schema.Array(Schema.String).annotations({ description: "Proper nouns (names of people, organizations, places, products) mentioned in the text." }) });
61
+ /**
62
+ * Extracts proper nouns from transcript text using a small LLM (Haiku). Provides the LanguageModel
63
+ * internally so the residual requirement is just {@link AiService.AiService}.
64
+ */
65
+ var extractProperNouns = (text) => Effect.gen(function* () {
66
+ const { value } = yield* Effect.scoped(LanguageModel.generateObject({
67
+ schema: ProperNouns,
68
+ prompt: [
69
+ "Extract every proper noun (people, organizations, places, products) mentioned in the transcript text below.",
70
+ "Return only the surface strings exactly as they appear. Exclude common nouns and pronouns.",
71
+ "",
72
+ "Transcript:",
73
+ text
74
+ ].join("\n")
75
+ }));
76
+ return value.properNouns.map((noun) => noun.trim()).filter((noun) => noun.length >= 3);
77
+ }).pipe(Effect.provide(AiService.model(EXTRACTION_MODEL)));
78
+ /**
79
+ * Enriches a transcript message: for each transcript block, extracts proper nouns, links them to
80
+ * objects in the space via full-text search, and rewrites the text with `[noun](dxn)` references.
81
+ * Requires {@link AiService.AiService}; takes the space database handle.
82
+ */
83
+ var enrichTranscriptMessage = (message, { db }) => Effect.gen(function* () {
84
+ const blocks = yield* Effect.forEach(message.blocks, (block) => Effect.gen(function* () {
85
+ if (block._tag !== "transcript") return block;
86
+ const nouns = yield* extractProperNouns(block.text);
87
+ const references = yield* Effect.promise(() => findReferences([...nouns], db));
88
+ return {
89
+ ...block,
90
+ text: insertReferences(block.text, references)
91
+ };
92
+ }));
93
+ return Obj.make(Message.Message, {
94
+ id: message.id,
95
+ sender: message.sender,
96
+ created: message.created,
97
+ properties: message.properties,
98
+ blocks
99
+ });
100
+ });
101
+ //#endregion
102
+ //#region src/extraction/extraction-ner-function/named-entity-recognition.ts
103
+ var __dxlog_file = "/__w/dxos/dxos/packages/core/compute/assistant/src/extraction/extraction-ner-function/named-entity-recognition.ts";
104
+ var _ner;
105
+ /**
106
+ * Named Entity Recognition pipeline.
107
+ * Initializes the pipeline on first call.
108
+ * @returns The singleton promise that resolves to a token classification pipeline.
109
+ */
110
+ var getNer = () => {
111
+ if (!_ner) _ner = pipeline("ner", "Xenova/bert-base-NER").then((ner) => {
112
+ log.info("NER model is ready", void 0, {
113
+ "~LogMeta": "~LogMeta",
114
+ F: __dxlog_file,
115
+ L: 24,
116
+ S: void 0
117
+ });
118
+ return ner;
119
+ });
120
+ return _ner;
121
+ };
122
+ /**
123
+ * Extracts entities from text using the named entity recognition pipeline and does simple grouping of tokens.
124
+ */
125
+ var extractFullEntities = async (text) => {
126
+ return createTokenGroups(await (await getNer())(text)).map(combineNerTokens);
127
+ };
128
+ var createTokenGroups = (tokens) => {
129
+ const tokenGroups = [];
130
+ const canBeCombined = (prevToken, currentToken) => {
131
+ const [currentState, currentEntity] = currentToken.entity.split("-");
132
+ const [prevState, prevEntity] = prevToken.entity.split("-");
133
+ if (prevEntity !== currentEntity) return false;
134
+ if (prevState === "O") return false;
135
+ if (currentState === "I") return true;
136
+ if ((prevState === "B" || prevState === "I") && currentState === "B") return currentToken.word.startsWith("#");
137
+ return false;
138
+ };
139
+ for (const token of tokens) {
140
+ if (tokenGroups.length === 0) {
141
+ tokenGroups.push([token]);
142
+ continue;
143
+ }
144
+ const lastTokenGroup = tokenGroups.at(-1);
145
+ if (canBeCombined(lastTokenGroup.at(-1), token)) {
146
+ lastTokenGroup.push(token);
147
+ continue;
148
+ }
149
+ tokenGroups.push([token]);
150
+ }
151
+ return tokenGroups;
152
+ };
153
+ var combineNerTokens = (group) => {
154
+ const combinedToken = {
155
+ entity: group.at(0).entity.split("-")[1],
156
+ score: group.reduce((acc, token) => acc + token.score, 0) / group.length,
157
+ index: group.at(0).index,
158
+ word: group.at(0).word,
159
+ start: group.at(0).start,
160
+ end: group.at(-1).end
161
+ };
162
+ for (const token of group.slice(1)) if (token.word.startsWith("#")) combinedToken.word += token.word.replace(/^#+/, "");
163
+ else combinedToken.word += " " + token.word;
164
+ return combinedToken;
165
+ };
166
+ //#endregion
167
+ export { ProperNouns, ReferencedQuotes, combineNerTokens, createTokenGroups, enrichTranscriptMessage, extractFullEntities, extractProperNouns, findReferences, getNer, insertReferences };
168
+
169
+ //# sourceMappingURL=extraction.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extraction.mjs","names":[],"sources":["../../src/extraction/quotes.ts","../../src/extraction/extraction-llm-function/proper-noun-extraction.ts","../../src/extraction/extraction-ner-function/named-entity-recognition.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Schema from 'effect/Schema';\n\nimport { type Database, Filter, Query } from '@dxos/echo';\nimport { EID, EntityId } from '@dxos/keys';\n\nexport const ReferencedQuotes = Schema.Struct({\n references: Schema.Array(\n Schema.Struct({\n id: Schema.String,\n quote: Schema.String, // TODO(burdon): Quote?\n }),\n )\n .pipe(Schema.mutable)\n .annotations({\n // TODO(burdon): Does this description make sense?\n description: `\n The references to the context objects that are mentioned in the transcript. \n Quote should match the original transcript text exactly, while id is the id of the context object.\n `,\n }),\n});\nexport type ReferencedQuotes = Schema.Schema.Type<typeof ReferencedQuotes>;\n\nexport type FindReferencesOptions = {\n /** Search backend. Full-text matches proper nouns precisely; vector matches semantically. */\n searchKind?: 'full-text' | 'vector';\n};\n\n/**\n * Finds the best-matching context object for each noun and returns it as a reference.\n */\nexport const findReferences = async (\n nouns: string[],\n db: Database.Database,\n { searchKind = 'full-text' }: FindReferencesOptions = {},\n): Promise<ReferencedQuotes> => {\n // Deduplicate and process longer nouns first: `insertReferences` rewrites case-insensitive\n // substrings, so a repeated or shorter overlapping noun would re-replace already-linked text and\n // produce nested/broken markdown links.\n const normalizedNouns = Array.from(new Set(nouns.map((noun) => noun.trim()).filter((noun) => noun.length > 0))).sort(\n (leftNoun, rightNoun) => rightNoun.length - leftNoun.length,\n );\n\n const references = await Promise.all(\n normalizedNouns.map(async (noun) => {\n const objects = await db.query(Query.select(Filter.text(noun, { type: searchKind }))).run();\n return objects.length > 0 ? [{ id: objects[0].id.toString(), quote: noun }] : [];\n }),\n );\n return { references: references.flat() };\n};\n\n/**\n * Finds and replaces all quotes with DXNs references.\n */\n// TODO(dmaretskyi): Lookup and verifiy ids from provided context.\nexport const insertReferences = (text: string, quotes: ReferencedQuotes): string => {\n // Process longer quotes first so e.g. \"Sarah Johnson\" is linked before \"Sarah\". Combined with the\n // link-aware replacement below this stops a shorter or overlapping quote from rewriting text that\n // is already part of an inserted link (which would produce nested `[[..](..)](..)` markdown).\n const references = quotes.references\n .filter((quote) => EntityId.isValid(quote.id))\n .sort((left, right) => right.quote.length - left.quote.length);\n\n for (const quote of references) {\n // Case-insensitive match of the (regex-escaped) quote.\n const regex = new RegExp(quote.quote.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'), 'gi');\n text = replaceOutsideLinks(text, regex, `[${quote.quote}](${EID.make({ entityId: quote.id })})`);\n }\n\n return text;\n};\n\nconst MARKDOWN_LINK = /\\[[^\\]]*\\]\\([^)]*\\)/g;\n\n/** Applies a replacement to every span of `text` that is not already inside a `[label](url)` link. */\nconst replaceOutsideLinks = (text: string, regex: RegExp, replacement: string): string => {\n let result = '';\n let plainStart = 0;\n for (const link of text.matchAll(MARKDOWN_LINK)) {\n const index = link.index ?? 0;\n result += text.slice(plainStart, index).replace(regex, replacement) + link[0];\n plainStart = index + link[0].length;\n }\n return result + text.slice(plainStart).replace(regex, replacement);\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as LanguageModel from '@effect/ai/LanguageModel';\nimport * as Effect from 'effect/Effect';\nimport * as Schema from 'effect/Schema';\n\nimport { AiService } from '@dxos/ai';\nimport { type Database, Obj } from '@dxos/echo';\nimport { Message } from '@dxos/types';\n\nimport { findReferences, insertReferences } from '../quotes';\n\nconst EXTRACTION_MODEL = 'com.anthropic.model.claude-haiku-4-5.default';\n\n/**\n * Proper nouns extracted from transcript text.\n */\nexport const ProperNouns = Schema.Struct({\n properNouns: Schema.Array(Schema.String).annotations({\n description: 'Proper nouns (names of people, organizations, places, products) mentioned in the text.',\n }),\n});\nexport type ProperNouns = Schema.Schema.Type<typeof ProperNouns>;\n\n/**\n * Extracts proper nouns from transcript text using a small LLM (Haiku). Provides the LanguageModel\n * internally so the residual requirement is just {@link AiService.AiService}.\n */\nexport const extractProperNouns = (text: string) =>\n Effect.gen(function* () {\n const { value } = yield* Effect.scoped(\n LanguageModel.generateObject({\n schema: ProperNouns,\n prompt: [\n 'Extract every proper noun (people, organizations, places, products) mentioned in the transcript text below.',\n 'Return only the surface strings exactly as they appear. Exclude common nouns and pronouns.',\n '',\n 'Transcript:',\n text,\n ].join('\\n'),\n }),\n );\n\n // Drop short tokens (e.g. \"IT\"): insertReferences replaces case-insensitive substrings, so a\n // short noun would match inside unrelated words (\"secur[IT]y\") and corrupt neighbouring links.\n return value.properNouns.map((noun) => noun.trim()).filter((noun) => noun.length >= 3);\n }).pipe(Effect.provide(AiService.model(EXTRACTION_MODEL)));\n\n/**\n * Enriches a transcript message: for each transcript block, extracts proper nouns, links them to\n * objects in the space via full-text search, and rewrites the text with `[noun](dxn)` references.\n * Requires {@link AiService.AiService}; takes the space database handle.\n */\nexport const enrichTranscriptMessage = (message: Message.Message, { db }: { db: Database.Database }) =>\n Effect.gen(function* () {\n const blocks = yield* Effect.forEach(message.blocks, (block) =>\n Effect.gen(function* () {\n if (block._tag !== 'transcript') {\n return block;\n }\n\n const nouns = yield* extractProperNouns(block.text);\n const references = yield* Effect.promise(() => findReferences([...nouns], db));\n return { ...block, text: insertReferences(block.text, references) };\n }),\n );\n\n // Preserve the message identity and metadata; enrichment only rewrites transcript block text.\n return Obj.make(Message.Message, {\n id: message.id,\n sender: message.sender,\n created: message.created,\n properties: message.properties,\n blocks,\n });\n });\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport {\n type TokenClassificationOutput,\n type TokenClassificationPipelineType,\n type TokenClassificationSingle,\n pipeline,\n} from '@xenova/transformers';\n\nimport { log } from '@dxos/log';\n\nlet _ner: Promise<TokenClassificationPipelineType>;\n\n/**\n * Named Entity Recognition pipeline.\n * Initializes the pipeline on first call.\n * @returns The singleton promise that resolves to a token classification pipeline.\n */\nexport const getNer = () => {\n if (!_ner) {\n _ner = pipeline('ner', 'Xenova/bert-base-NER').then((ner) => {\n log.info('NER model is ready');\n return ner;\n });\n }\n\n return _ner;\n};\n\n/**\n * Extracts entities from text using the named entity recognition pipeline and does simple grouping of tokens.\n */\nexport const extractFullEntities = async (text: string): Promise<TokenClassificationSingle[]> => {\n const ner = await getNer();\n const entities = (await ner(text)) as TokenClassificationOutput;\n const tokenGroups = createTokenGroups(entities);\n const combinedEntities = tokenGroups.map(combineNerTokens);\n return combinedEntities;\n};\n\nexport const createTokenGroups = (tokens: TokenClassificationSingle[]): TokenClassificationSingle[][] => {\n const tokenGroups: TokenClassificationSingle[][] = [];\n\n const canBeCombined = (prevToken: TokenClassificationSingle, currentToken: TokenClassificationSingle) => {\n const [currentState, currentEntity] = currentToken.entity.split('-'); // B, I, O\n const [prevState, prevEntity] = prevToken.entity.split('-'); // B, I, O\n if (prevEntity !== currentEntity) {\n return false;\n }\n if (prevState === 'O') {\n return false;\n }\n if (currentState === 'I') {\n return true;\n }\n if ((prevState === 'B' || prevState === 'I') && currentState === 'B') {\n return currentToken.word.startsWith('#');\n }\n return false;\n };\n\n for (const token of tokens) {\n if (tokenGroups.length === 0) {\n tokenGroups.push([token]);\n continue;\n }\n const lastTokenGroup = tokenGroups.at(-1)!;\n if (canBeCombined(lastTokenGroup.at(-1)!, token)) {\n lastTokenGroup.push(token);\n continue;\n }\n tokenGroups.push([token]);\n }\n\n return tokenGroups;\n};\n\nexport const combineNerTokens = (group: TokenClassificationSingle[]): TokenClassificationSingle => {\n const combinedToken: TokenClassificationSingle = {\n entity: group.at(0)!.entity.split('-')[1],\n score: group.reduce((acc, token) => acc + token.score, 0) / group.length,\n index: group.at(0)!.index,\n word: group.at(0)!.word,\n start: group.at(0)!.start,\n end: group.at(-1)!.end,\n };\n\n for (const token of group.slice(1)) {\n if (token.word.startsWith('#')) {\n combinedToken.word += token.word.replace(/^#+/, '');\n } else {\n combinedToken.word += ' ' + token.word;\n }\n }\n\n return combinedToken;\n};\n"],"mappings":"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"}