@dxos/assistant 0.8.4-main.d05539e30a → 0.8.4-main.d9fc60f731

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 (39) hide show
  1. package/dist/lib/neutral/extraction/index.mjs +17 -13
  2. package/dist/lib/neutral/extraction/index.mjs.map +3 -3
  3. package/dist/lib/neutral/index.mjs +112 -80
  4. package/dist/lib/neutral/index.mjs.map +3 -3
  5. package/dist/lib/neutral/meta.json +1 -1
  6. package/dist/types/src/extraction/extraction.d.ts +623 -55
  7. package/dist/types/src/extraction/extraction.d.ts.map +1 -1
  8. package/dist/types/src/extraction/quotes.d.ts.map +1 -1
  9. package/dist/types/src/request/AiRequest.d.ts +203 -1
  10. package/dist/types/src/request/AiRequest.d.ts.map +1 -1
  11. package/dist/types/src/request/artifact-diff.d.ts +3 -3
  12. package/dist/types/src/request/format.d.ts +2 -2
  13. package/dist/types/src/request/version-pin.d.ts +1 -1
  14. package/dist/types/src/session/AiContext.d.ts +43 -19
  15. package/dist/types/src/session/AiContext.d.ts.map +1 -1
  16. package/dist/types/src/session/AiSession.d.ts +6 -1
  17. package/dist/types/src/session/AiSession.d.ts.map +1 -1
  18. package/dist/types/src/templates/system.d.ts +12 -2
  19. package/dist/types/src/templates/system.d.ts.map +1 -1
  20. package/dist/types/src/util/artifact.d.ts +7 -16
  21. package/dist/types/src/util/artifact.d.ts.map +1 -1
  22. package/dist/types/src/util/tracing.d.ts +60 -4
  23. package/dist/types/src/util/tracing.d.ts.map +1 -1
  24. package/dist/types/tsconfig.tsbuildinfo +1 -1
  25. package/package.json +28 -28
  26. package/src/extraction/extraction.ts +10 -9
  27. package/src/extraction/quotes.test.ts +2 -2
  28. package/src/extraction/quotes.ts +3 -4
  29. package/src/request/AiRequest.ts +2 -1
  30. package/src/request/artifact-diff.ts +3 -3
  31. package/src/request/format.ts +7 -7
  32. package/src/request/version-pin.ts +2 -2
  33. package/src/session/AiContext.test.ts +3 -7
  34. package/src/session/AiContext.ts +70 -53
  35. package/src/session/AiSession.ts +3 -2
  36. package/src/util/artifact.ts +42 -34
  37. package/src/util/diff.test.ts +1 -1
  38. package/src/util/execution-graph.test.ts +3 -3
  39. package/src/util/execution-graph.ts +8 -7
@@ -3,12 +3,13 @@ import "../chunk-J5LGTIGS.mjs";
3
3
  // src/extraction/extraction.ts
4
4
  import * as Schema from "effect/Schema";
5
5
  import { Operation } from "@dxos/compute";
6
- import { Obj } from "@dxos/echo";
6
+ import { Obj, Type } from "@dxos/echo";
7
+ import { DXN } from "@dxos/keys";
7
8
  import { log } from "@dxos/log";
8
9
  import { Message } from "@dxos/types";
9
10
  var __dxlog_file = "/__w/dxos/dxos/packages/core/compute/assistant/src/extraction/extraction.ts";
10
11
  var ExtractionInput = Schema.Struct({
11
- message: Message.Message,
12
+ message: Type.getSchema(Message.Message),
12
13
  objects: Schema.optional(Schema.Array(Obj.Unknown)),
13
14
  options: Schema.optional(Schema.Struct({
14
15
  timeout: Schema.optional(Schema.Number),
@@ -16,23 +17,25 @@ var ExtractionInput = Schema.Struct({
16
17
  }))
17
18
  });
18
19
  var ExtractionOutput = Schema.Struct({
19
- message: Message.Message,
20
+ message: Type.getSchema(Message.Message),
20
21
  timeElapsed: Schema.Number
21
22
  });
22
23
  var extractionAnthropicFunction = Operation.make({
23
24
  meta: {
24
- key: "org.dxos.function.extraction.anthropic",
25
+ key: DXN.make("org.dxos.function.extraction.anthropic"),
25
26
  name: "Entity Extraction (Anthropic)",
26
- description: "Extract entities from transcript using Anthropic LLM."
27
+ description: "Extract entities from transcript using Anthropic LLM.",
28
+ icon: "ph--text-t--regular"
27
29
  },
28
30
  input: ExtractionInput,
29
31
  output: ExtractionOutput
30
32
  });
31
33
  var extractionNerFunction = Operation.make({
32
34
  meta: {
33
- key: "org.dxos.function.extraction.ner",
35
+ key: DXN.make("org.dxos.function.extraction.ner"),
34
36
  name: "Entity Extraction (NER)",
35
- description: "Extract entities from transcript using Named Entity Recognition."
37
+ description: "Extract entities from transcript using Named Entity Recognition.",
38
+ icon: "ph--text-t--regular"
36
39
  },
37
40
  input: ExtractionInput,
38
41
  output: ExtractionOutput
@@ -46,7 +49,7 @@ var processTranscriptMessage = async (params) => {
46
49
  if (params.options?.fallbackToRaw) {
47
50
  log.warn("failed to process message, falling back to raw text", {
48
51
  error
49
- }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 57, S: void 0 });
52
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 60, S: void 0 });
50
53
  return {
51
54
  message: params.input.message,
52
55
  timeElapsed: 0
@@ -141,8 +144,7 @@ var combineNerTokens = (group) => {
141
144
  // src/extraction/quotes.ts
142
145
  import * as Schema2 from "effect/Schema";
143
146
  import { Filter, Query } from "@dxos/echo";
144
- import { ObjectId } from "@dxos/keys";
145
- import { DXN } from "@dxos/keys";
147
+ import { EID, EntityId } from "@dxos/keys";
146
148
  import { log as log3 } from "@dxos/log";
147
149
  var __dxlog_file3 = "/__w/dxos/dxos/packages/core/compute/assistant/src/extraction/quotes.ts";
148
150
  var ReferencedQuotes = Schema2.Struct({
@@ -165,7 +167,7 @@ var findQuotes = async (quotes, db) => {
165
167
  log3.info("found quotes in vector index", {
166
168
  objects,
167
169
  quote
168
- }, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 26, S: void 0 });
170
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 25, S: void 0 });
169
171
  return objects.length > 0 ? [
170
172
  {
171
173
  id: objects[0].id.toString(),
@@ -179,11 +181,13 @@ var findQuotes = async (quotes, db) => {
179
181
  };
180
182
  var insertReferences = (text, quotes) => {
181
183
  for (const quote of quotes.references) {
182
- if (!ObjectId.isValid(quote.id)) {
184
+ if (!EntityId.isValid(quote.id)) {
183
185
  continue;
184
186
  }
185
187
  const regex = new RegExp(quote.quote.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "gi");
186
- text = text.replace(regex, `[${quote.quote}](${DXN.fromLocalObjectId(quote.id).toString()})`);
188
+ text = text.replace(regex, `[${quote.quote}](${EID.make({
189
+ entityId: quote.id
190
+ })})`);
187
191
  }
188
192
  return text;
189
193
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/extraction/extraction.ts", "../../../../src/extraction/extraction-ner-function/named-entity-recognition.ts", "../../../../src/extraction/quotes.ts"],
4
- "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Schema from 'effect/Schema';\n\nimport { Operation } from '@dxos/compute';\nimport { Obj } from '@dxos/echo';\nimport { log } from '@dxos/log';\nimport { Message } from '@dxos/types';\n\nexport const ExtractionInput = Schema.Struct({\n message: Message.Message,\n objects: Schema.optional(Schema.Array(Obj.Unknown)),\n options: Schema.optional(\n Schema.Struct({\n timeout: Schema.optional(Schema.Number),\n fallbackToRaw: Schema.optional(Schema.Boolean),\n }),\n ),\n});\nexport interface ExtractionInput extends Schema.Schema.Type<typeof ExtractionInput> {}\n\nexport const ExtractionOutput = Schema.Struct({\n message: Message.Message,\n timeElapsed: Schema.Number,\n});\nexport interface ExtractionOutput extends Schema.Schema.Type<typeof ExtractionOutput> {}\n\nexport type ProcessTranscriptMessageProps = {\n input: ExtractionInput;\n function: Operation.Definition<ExtractionInput, ExtractionOutput>;\n\n options?: {\n /**\n * Timeout for the entity extraction.\n */\n timeout?: number;\n\n /**\n * Fallback to raw text if the entity extraction fails.\n * Otherwise the function will throw an error.\n * @default false\n */\n fallbackToRaw?: boolean;\n };\n};\n\nexport type ExtractionFunction = Operation.Definition<ExtractionInput, ExtractionOutput>;\n\n/**\n * Placeholder for Anthropic-based entity extraction.\n * Implementation is currently disabled pending restoration of extraction logic.\n */\nexport const extractionAnthropicFunction = Operation.make({\n meta: {\n key: 'org.dxos.function.extraction.anthropic',\n name: 'Entity Extraction (Anthropic)',\n description: 'Extract entities from transcript using Anthropic LLM.',\n },\n input: ExtractionInput,\n output: ExtractionOutput,\n});\n\n/**\n * Placeholder for NER-based entity extraction.\n * Implementation is currently disabled pending restoration of extraction logic.\n */\nexport const extractionNerFunction = Operation.make({\n meta: {\n key: 'org.dxos.function.extraction.ner',\n name: 'Entity Extraction (NER)',\n description: 'Extract entities from transcript using Named Entity Recognition.',\n },\n input: ExtractionInput,\n output: ExtractionOutput,\n});\n\n/**\n * Extract entities from the transcript message and add them to the message.\n */\n// TODO(dmaretskyi): Move context to a vector search index.\nexport const processTranscriptMessage = async (params: ProcessTranscriptMessageProps): Promise<ExtractionOutput> => {\n try {\n if (params.options?.timeout && params.options.timeout > 0) {\n // return await asyncTimeout(params.executor.invoke(params.function, params.input), params.options.timeout);\n } else {\n // return await params.executor.invoke(params.function, params.input);\n }\n } catch (error) {\n if (params.options?.fallbackToRaw) {\n log.warn('failed to process message, falling back to raw text', { error });\n return {\n message: params.input.message,\n timeElapsed: 0,\n };\n } else {\n throw error;\n }\n }\n\n // TODO(dmaretskyi): Restore extraction logic.\n return { message: params.input.message, timeElapsed: 0 };\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", "//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Schema from 'effect/Schema';\n\nimport { type Database, Filter, Query } from '@dxos/echo';\nimport { ObjectId } from '@dxos/keys';\nimport { DXN } from '@dxos/keys';\nimport { log } from '@dxos/log';\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 const findQuotes = async (quotes: string[], db: Database.Database): Promise<ReferencedQuotes> => {\n const references = await Promise.all(\n quotes.map(async (quote) => {\n const objects = await db.query(Query.select(Filter.text(quote, { type: 'vector' }))).run();\n log.info('found quotes in vector index', { objects, quote });\n return objects.length > 0 ? [{ id: objects[0].id.toString(), quote }] : [];\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) => {\n for (const quote of quotes.references) {\n if (!ObjectId.isValid(quote.id)) {\n continue;\n }\n\n // Use a case-insensitive regular expression to replace the quote.\n const regex = new RegExp(quote.quote.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'), 'gi');\n text = text.replace(regex, `[${quote.quote}](${DXN.fromLocalObjectId(quote.id).toString()})`);\n }\n\n return text;\n};\n"],
5
- "mappings": "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",
6
- "names": ["Schema", "Operation", "Obj", "log", "Message", "ExtractionInput", "objects", "Array", "options", "optional", "Number", "fallbackToRaw", "timeElapsed", "key", "name", "description", "input", "output", "params", "timeout", "error", "message", "pipeline", "log", "_ner", "ner", "__dxlog_file", "entities", "text", "tokenGroups", "createTokenGroups", "combinedEntities", "canBeCombined", "prevToken", "currentToken", "currentState", "prevEntity", "entity", "currentEntity", "prevState", "token", "push", "lastTokenGroup", "score", "reduce", "index", "group", "at", "word", "start", "end", "combinedToken", "Schema", "Filter", "Query", "ObjectId", "DXN", "log", "__dxlog_file", "ReferencedQuotes", "String", "pipe", "description", "query", "select", "run", "info", "objects", "quote", "id", "toString", "text"]
4
+ "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Schema from 'effect/Schema';\n\nimport { Operation } from '@dxos/compute';\nimport { Obj, Type } from '@dxos/echo';\nimport { DXN } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { Message } from '@dxos/types';\n\nexport const ExtractionInput = Schema.Struct({\n message: Type.getSchema(Message.Message),\n objects: Schema.optional(Schema.Array(Obj.Unknown)),\n options: Schema.optional(\n Schema.Struct({\n timeout: Schema.optional(Schema.Number),\n fallbackToRaw: Schema.optional(Schema.Boolean),\n }),\n ),\n});\nexport type ExtractionInput = Schema.Schema.Type<typeof ExtractionInput>;\nexport const ExtractionOutput = Schema.Struct({\n message: Type.getSchema(Message.Message),\n timeElapsed: Schema.Number,\n});\nexport type ExtractionOutput = Schema.Schema.Type<typeof ExtractionOutput>;\nexport type ProcessTranscriptMessageProps = {\n input: ExtractionInput;\n function: Operation.Definition<ExtractionInput, ExtractionOutput>;\n\n options?: {\n /**\n * Timeout for the entity extraction.\n */\n timeout?: number;\n\n /**\n * Fallback to raw text if the entity extraction fails.\n * Otherwise the function will throw an error.\n * @default false\n */\n fallbackToRaw?: boolean;\n };\n};\n\nexport type ExtractionFunction = Operation.Definition<ExtractionInput, ExtractionOutput>;\n\n/**\n * Placeholder for Anthropic-based entity extraction.\n * Implementation is currently disabled pending restoration of extraction logic.\n */\nexport const extractionAnthropicFunction = Operation.make({\n meta: {\n key: DXN.make('org.dxos.function.extraction.anthropic'),\n name: 'Entity Extraction (Anthropic)',\n description: 'Extract entities from transcript using Anthropic LLM.',\n icon: 'ph--text-t--regular',\n },\n input: ExtractionInput,\n output: ExtractionOutput,\n});\n\n/**\n * Placeholder for NER-based entity extraction.\n * Implementation is currently disabled pending restoration of extraction logic.\n */\nexport const extractionNerFunction = Operation.make({\n meta: {\n key: DXN.make('org.dxos.function.extraction.ner'),\n name: 'Entity Extraction (NER)',\n description: 'Extract entities from transcript using Named Entity Recognition.',\n icon: 'ph--text-t--regular',\n },\n input: ExtractionInput,\n output: ExtractionOutput,\n});\n\n/**\n * Extract entities from the transcript message and add them to the message.\n */\n// TODO(dmaretskyi): Move context to a vector search index.\nexport const processTranscriptMessage = async (params: ProcessTranscriptMessageProps): Promise<ExtractionOutput> => {\n try {\n if (params.options?.timeout && params.options.timeout > 0) {\n // return await asyncTimeout(params.executor.invoke(params.function, params.input), params.options.timeout);\n } else {\n // return await params.executor.invoke(params.function, params.input);\n }\n } catch (error) {\n if (params.options?.fallbackToRaw) {\n log.warn('failed to process message, falling back to raw text', { error });\n return {\n message: params.input.message,\n timeElapsed: 0,\n };\n } else {\n throw error;\n }\n }\n\n // TODO(dmaretskyi): Restore extraction logic.\n return { message: params.input.message, timeElapsed: 0 };\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", "//\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';\nimport { log } from '@dxos/log';\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 const findQuotes = async (quotes: string[], db: Database.Database): Promise<ReferencedQuotes> => {\n const references = await Promise.all(\n quotes.map(async (quote) => {\n const objects = await db.query(Query.select(Filter.text(quote, { type: 'vector' }))).run();\n log.info('found quotes in vector index', { objects, quote });\n return objects.length > 0 ? [{ id: objects[0].id.toString(), quote }] : [];\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) => {\n for (const quote of quotes.references) {\n if (!EntityId.isValid(quote.id)) {\n continue;\n }\n\n // Use a case-insensitive regular expression to replace the quote.\n const regex = new RegExp(quote.quote.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'), 'gi');\n text = text.replace(regex, `[${quote.quote}](${EID.make({ entityId: quote.id })})`);\n }\n\n return text;\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["Schema", "Operation", "Obj", "Type", "DXN", "log", "Message", "ExtractionInput", "objects", "Array", "options", "Struct", "Number", "fallbackToRaw", "optional", "timeElapsed", "key", "make", "name", "description", "icon", "input", "output", "params", "timeout", "error", "message", "pipeline", "log", "_ner", "ner", "__dxlog_file", "entities", "text", "tokenGroups", "createTokenGroups", "combinedEntities", "canBeCombined", "prevToken", "currentToken", "currentState", "prevEntity", "entity", "currentEntity", "prevState", "token", "push", "lastTokenGroup", "score", "reduce", "index", "group", "at", "word", "start", "end", "combinedToken", "Schema", "Filter", "Query", "EID", "EntityId", "log", "__dxlog_file", "ReferencedQuotes", "String", "pipe", "description", "query", "select", "run", "info", "objects", "quote", "id", "toString", "entityId", "text"]
7
7
  }
@@ -22,37 +22,48 @@ import { invariant } from "@dxos/invariant";
22
22
  import * as Schema from "effect/Schema";
23
23
  import { Database, Obj, Ref } from "@dxos/echo";
24
24
  import { EncodedReference } from "@dxos/echo-protocol";
25
- import { DXN, LOCAL_SPACE_TAG } from "@dxos/keys";
25
+ import { EID, EntityId, SpaceId } from "@dxos/keys";
26
26
  import { trim } from "@dxos/util";
27
27
  var createArtifactElement = (id) => `<artifact id=${id} />`;
28
- var ArtifactId = class extends Schema.String.annotations({
28
+ var ArtifactURI = class extends Schema.String.annotations({
29
29
  // TODO(dmaretskyi): This section gets overriden.
30
30
  description: trim`
31
- The ID of the referenced object. Formats accepted:
32
- - DXN (dxn:echo:@:01KG7R1ZXWFMWQ4DA1Q6TN1DG4). DXNs can be prepended with an @ symbol for compatibility with in-text references.
31
+ The URI of the referenced object. Protocols accepted:
32
+ - echo://01KG7R1ZXWFMWQ4DA1Q6TN1DG4.
33
33
  - space ID, object ID tuple (spaceID:objectID)
34
34
  - Only object ID that is assumed to be in the current space (01KG7R1ZXWFMWQ4DA1Q6TN1DG4)
35
+ - dxn:org.dxos.type.calendar:0.1.0 -- named entity from the registry. Absoutely make sure it actually exists in the registry.
36
+
37
+ URIs can be prepended with an @ symbol for compatibility with in-text references.
35
38
  `,
36
39
  examples: [
37
- "dxn:echo:@:01KG7R1ZXWFMWQ4DA1Q6TN1DG4",
38
- "@dxn:echo:@:01KG7R1ZXWFMWQ4DA1Q6TN1DG4",
40
+ "echo://01KG7R1ZXWFMWQ4DA1Q6TN1DG4",
41
+ "@echo://01KG7R1ZXWFMWQ4DA1Q6TN1DG4",
39
42
  "BM3FSHFOMJCHCG5QW7JTVKGYABD2GAA7G:01KG7R1ZXWFMWQ4DA1Q6TN1DG4",
40
- "01KG7R1ZXWFMWQ4DA1Q6TN1DG4"
43
+ "01KG7R1ZXWFMWQ4DA1Q6TN1DG4",
44
+ "dxn:org.dxos.type.calendar:0.1.0",
45
+ "@dxn:org.dxos.type.calendar:0.1.0"
41
46
  ]
42
47
  }) {
43
- static toDXN(reference, owningSpaceId) {
44
- if (reference.startsWith("@dxn:")) {
45
- return DXN.parse(reference.slice(1));
46
- } else if (reference.startsWith("dxn:")) {
47
- return DXN.parse(reference);
48
- } else if (/^[A-Z0-9]+:[A-Z0-9]+$/.test(reference)) {
49
- const [spaceId, objectId] = reference.split(":");
50
- return new DXN(DXN.kind.ECHO, [
51
- spaceId === owningSpaceId ? LOCAL_SPACE_TAG : spaceId,
52
- objectId
53
- ]);
54
- } else if (/^[A-Z0-9]+$/.test(reference)) {
55
- return DXN.fromLocalObjectId(reference);
48
+ static toEchoURI(reference, owningSpaceId) {
49
+ const stripped = reference.startsWith("@") ? reference.slice(1) : reference;
50
+ if (stripped.startsWith("echo:") || stripped.startsWith("dxn:")) {
51
+ return EID.parse(stripped);
52
+ } else if (stripped.includes(":")) {
53
+ const [spaceId, objectId] = stripped.split(":");
54
+ if (!SpaceId.isValid(spaceId) || !EntityId.isValid(objectId)) {
55
+ throw new Error(`Unable to parse object reference: ${reference}`);
56
+ }
57
+ return spaceId === owningSpaceId ? EID.make({
58
+ entityId: objectId
59
+ }) : EID.make({
60
+ spaceId,
61
+ entityId: objectId
62
+ });
63
+ } else if (EntityId.isValid(stripped)) {
64
+ return EID.make({
65
+ entityId: stripped
66
+ });
56
67
  } else {
57
68
  throw new Error(`Unable to parse object reference: ${reference}`);
58
69
  }
@@ -61,16 +72,16 @@ var ArtifactId = class extends Schema.String.annotations({
61
72
  * Resolves an artifact ID to an object.
62
73
  */
63
74
  static resolve(schema, ref) {
64
- const dxn = ArtifactId.toDXN(ref);
65
- return Database.resolve(dxn, schema);
75
+ const uri = ArtifactURI.toEchoURI(ref);
76
+ return Database.resolve(Ref.fromURI(uri), schema);
66
77
  }
67
78
  };
68
- var RefFromLLM = Schema.transform(ArtifactId, Ref.Ref(Obj.Unknown), {
69
- decode: (fromA, fromI) => EncodedReference.fromDXN(ArtifactId.toDXN(fromA)),
70
- encode: (toI, toA) => EncodedReference.toDXN(toI).toString(),
79
+ var RefFromLLM = Schema.transform(ArtifactURI, Ref.Ref(Obj.Unknown), {
80
+ decode: (fromA, fromI) => EncodedReference.fromURI(ArtifactURI.toEchoURI(fromA)),
81
+ encode: (toI, toA) => EncodedReference.toURI(toI),
71
82
  strict: false
72
83
  }).annotations({
73
- description: ArtifactId.ast.annotations.description
84
+ description: ArtifactURI.ast.annotations.description
74
85
  });
75
86
 
76
87
  // src/util/diff.ts
@@ -191,6 +202,7 @@ var mapAiError = (err) => Effect.gen(function* () {
191
202
  import { AgentStatus } from "@dxos/ai";
192
203
  import { Obj as Obj2 } from "@dxos/echo";
193
204
  import { MESSAGE_PROPERTY_TOOL_CALL_ID } from "@dxos/functions";
205
+ import { EID as EID2 } from "@dxos/keys";
194
206
  import { LogLevel } from "@dxos/log";
195
207
  import { ContentBlock, Message } from "@dxos/types";
196
208
  import { isNonNullable as isNonNullable2 } from "@dxos/util";
@@ -561,7 +573,8 @@ var stringifyRef = (ref) => {
561
573
  if (ref.target) {
562
574
  return stringifyObject(ref.target);
563
575
  }
564
- return ref.dxn.asEchoDXN()?.echoId ?? ref.dxn.asQueueDXN()?.objectId ?? "";
576
+ const echoUri = EID2.tryParse(ref.uri);
577
+ return (echoUri ? EID2.getEntityId(echoUri) : void 0) ?? "";
565
578
  };
566
579
  var stringifyObject = (obj) => {
567
580
  return Obj2.getLabel(obj) ?? Obj2.getTypename(obj) ?? obj.id;
@@ -747,7 +760,7 @@ var formatSystemPrompt = ({ system, blueprints = [], objects = [] }) => Effect3.
747
760
  ].join("\n\n") : void 0));
748
761
  const objectDefs = yield* Function.pipe(objects, Effect3.forEach((object) => Effect3.succeed(trim2`
749
762
  <object>
750
- <dxn>${Obj4.getDXN(object)}</dxn>
763
+ <dxn>${Obj4.getURI(object)}</dxn>
751
764
  <typename>${Obj4.getTypename(object)}</typename>
752
765
  </object>
753
766
  `)), Effect3.map((objects2) => objects2.length > 0 ? [
@@ -1045,7 +1058,7 @@ var Request = class {
1045
1058
  concurrency: 1,
1046
1059
  unordered: false
1047
1060
  }), Stream.filterMap((_) => _), Stream.runCollect, Effect5.map(Chunk.toArray));
1048
- log3.info("messages", {
1061
+ log3("messages", {
1049
1062
  messages
1050
1063
  }, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 181, S: this });
1051
1064
  const toolCalls = this.getToolCalls();
@@ -1138,7 +1151,8 @@ var enrichToolCallBlock = (block, toolkit) => {
1138
1151
  return {
1139
1152
  ...block,
1140
1153
  operationKey: meta.key,
1141
- operationName: meta.name
1154
+ operationName: meta.name,
1155
+ operationIcon: meta.icon
1142
1156
  };
1143
1157
  };
1144
1158
  var createSnippet = (text, len = 32) => text.length <= len * 2 ? text : [
@@ -1175,7 +1189,7 @@ __export(AiContext_exports, {
1175
1189
  Bindings: () => Bindings,
1176
1190
  Service: () => Service
1177
1191
  });
1178
- import { Atom, Registry } from "@effect-atom/atom-react";
1192
+ import { Atom, Registry as AtomRegistry } from "@effect-atom/atom-react";
1179
1193
  import * as EArray from "effect/Array";
1180
1194
  import * as Context3 from "effect/Context";
1181
1195
  import * as Effect7 from "effect/Effect";
@@ -1184,8 +1198,9 @@ import * as Runtime from "effect/Runtime";
1184
1198
  import * as Schema5 from "effect/Schema";
1185
1199
  import { Blueprint } from "@dxos/compute";
1186
1200
  import { Resource } from "@dxos/context";
1187
- import { DXN as DXN2, Feed, Obj as Obj6, Query, Ref as Ref3, Type as Type2 } from "@dxos/echo";
1201
+ import { DXN, Feed, Obj as Obj6, Query, Ref as Ref3, Type as Type2 } from "@dxos/echo";
1188
1202
  import { assertArgument } from "@dxos/invariant";
1203
+ import { EID as EID3 } from "@dxos/keys";
1189
1204
  import { log as log4 } from "@dxos/log";
1190
1205
  import { ComplexSet, isNonNullable as isNonNullable3 } from "@dxos/util";
1191
1206
  var __dxlog_file5 = "/__w/dxos/dxos/packages/core/compute/assistant/src/session/AiContext.ts";
@@ -1198,18 +1213,18 @@ var Binding = Schema5.Struct({
1198
1213
  added: Schema5.Array(Ref3.Ref(Obj6.Unknown)),
1199
1214
  removed: Schema5.Array(Ref3.Ref(Obj6.Unknown))
1200
1215
  })
1201
- }).pipe(Type2.object({
1202
- typename: "org.dxos.type.contextBinding",
1203
- version: "0.1.0"
1204
- }));
1216
+ }).pipe(Type2.makeObject(DXN.make("org.dxos.type.contextBinding", "0.1.0")));
1205
1217
  var Bindings = class {
1206
- blueprints = new ComplexSet((ref) => ref.dxn.toString());
1218
+ blueprints = new ComplexSet((ref) => ref.uri);
1207
1219
  // TODO(burdon): Some DXNs have the Space prefix so only compare the object ID.
1208
- objects = new ComplexSet((ref) => ref.dxn.asEchoDXN()?.echoId);
1220
+ objects = new ComplexSet((ref) => {
1221
+ const echoUri = EID3.tryParse(ref.uri);
1222
+ return echoUri ? EID3.getEntityId(echoUri) : void 0;
1223
+ });
1209
1224
  toJSON() {
1210
1225
  return {
1211
- blueprints: EArray.fromIterable(this.blueprints).map((ref) => ref.dxn.toString()),
1212
- objects: EArray.fromIterable(this.objects).map((ref) => ref.dxn.toString())
1226
+ blueprints: EArray.fromIterable(this.blueprints).map((ref) => ref.uri),
1227
+ objects: EArray.fromIterable(this.objects).map((ref) => ref.uri)
1213
1228
  };
1214
1229
  }
1215
1230
  };
@@ -1226,7 +1241,7 @@ var Binder = class extends Resource {
1226
1241
  assertArgument(options.runtime, "options.runtime", "Feed runtime is required");
1227
1242
  this._feed = options.feed;
1228
1243
  this._runtime = options.runtime;
1229
- this._registry = options.registry ?? Registry.make();
1244
+ this._registry = options.registry ?? AtomRegistry.make();
1230
1245
  }
1231
1246
  /**
1232
1247
  * Returns the blueprints atom for subscription.
@@ -1280,12 +1295,12 @@ var Binder = class extends Resource {
1280
1295
  const results = await this.#bindingsQuery.run();
1281
1296
  log4("sync", {
1282
1297
  bindingItems: results.length
1283
- }, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 107, S: this });
1298
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 108, S: this });
1284
1299
  await this._updateBindings(results);
1285
1300
  log4("sync complete", {
1286
1301
  blueprints: this._registry.get(this._blueprints).length,
1287
1302
  blueprintKeys: this._registry.get(this._blueprints).map((bp) => Blueprint.getKey(bp))
1288
- }, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 111, S: this });
1303
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 112, S: this });
1289
1304
  }
1290
1305
  }
1291
1306
  async _updateBindings(items) {
@@ -1298,34 +1313,49 @@ var Binder = class extends Resource {
1298
1313
  blueprintRefs: [
1299
1314
  ...bindings.blueprints
1300
1315
  ].map((ref) => ({
1301
- dxn: ref.dxn.toString(),
1316
+ uri: ref.uri,
1302
1317
  available: ref.isAvailable
1303
1318
  }))
1304
- }, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 123, S: this });
1319
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 124, S: this });
1305
1320
  const currentBlueprints = this._registry.get(this._blueprints);
1306
1321
  const currentObjects = this._registry.get(this._objects);
1307
1322
  const resolvedBlueprints = await this._resolve(bindings.blueprints, currentBlueprints);
1308
1323
  const resolvedObjects = await this._resolve(bindings.objects, currentObjects);
1309
1324
  log4("_updateBindings resolved", {
1310
1325
  resolvedBlueprints: resolvedBlueprints.length,
1311
- resolvedBlueprintKeys: resolvedBlueprints.map((bp) => Blueprint.getKey(bp))
1312
- }, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 137, S: this });
1313
- const reducedBlueprintDxns = new ComplexSet(DXN2.hash, [
1326
+ resolvedBlueprintKeys: resolvedBlueprints.map((bp) => Obj6.getMeta(bp).key ?? "<missing>")
1327
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 138, S: this });
1328
+ const keyedBlueprints = resolvedBlueprints.filter((bp) => {
1329
+ if (Obj6.getMeta(bp).key === void 0) {
1330
+ log4.warn("dropping blueprint with no meta key", {
1331
+ uri: Obj6.getURI(bp)
1332
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 146, S: this });
1333
+ return false;
1334
+ }
1335
+ return true;
1336
+ });
1337
+ const reducedBlueprintDxns = new Set([
1314
1338
  ...bindings.blueprints
1315
- ].map((ref) => ref.dxn));
1316
- const reducedObjectDxns = new ComplexSet(DXN2.hash, [
1339
+ ].map((ref) => ref.uri));
1340
+ const reducedObjectDxns = new Set([
1317
1341
  ...bindings.objects
1318
- ].map((ref) => ref.dxn));
1319
- const filteredBlueprints = currentBlueprints.filter((obj) => reducedBlueprintDxns.has(Obj6.getDXN(obj)));
1320
- const filteredObjects = currentObjects.filter((obj) => reducedObjectDxns.has(Obj6.getDXN(obj)));
1321
- const mergedBlueprints = this._mergeInto(filteredBlueprints, resolvedBlueprints);
1342
+ ].map((ref) => ref.uri));
1343
+ const filteredBlueprints = currentBlueprints.filter((obj) => {
1344
+ const uri = Obj6.getURI(obj);
1345
+ return uri != null && reducedBlueprintDxns.has(uri) && Obj6.getMeta(obj).key !== void 0;
1346
+ });
1347
+ const filteredObjects = currentObjects.filter((obj) => {
1348
+ const uri = Obj6.getURI(obj);
1349
+ return uri != null && reducedObjectDxns.has(uri);
1350
+ });
1351
+ const mergedBlueprints = this._mergeInto(filteredBlueprints, keyedBlueprints);
1322
1352
  const mergedObjects = this._mergeInto(filteredObjects, resolvedObjects);
1323
1353
  this._registry.set(this._blueprints, mergedBlueprints);
1324
1354
  this._registry.set(this._objects, mergedObjects);
1325
1355
  log4("updated bindings", {
1326
1356
  blueprints: mergedBlueprints.length,
1327
1357
  objects: mergedObjects.length
1328
- }, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 155, S: this });
1358
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 173, S: this });
1329
1359
  }
1330
1360
  async _close() {
1331
1361
  this._registry.set(this._blueprints, []);
@@ -1344,7 +1374,7 @@ var Binder = class extends Resource {
1344
1374
  log4("bind", {
1345
1375
  blueprints: addedBlueprints.length,
1346
1376
  objects: addedObjects.length
1347
- }, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 176, S: this });
1377
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 194, S: this });
1348
1378
  await Runtime.runPromise(this._runtime)(Feed.append(this._feed, [
1349
1379
  Obj6.make(Binding, {
1350
1380
  blueprints: {
@@ -1362,20 +1392,20 @@ var Binder = class extends Resource {
1362
1392
  if (!blueprints?.length && !objects?.length) {
1363
1393
  return;
1364
1394
  }
1365
- const removedBlueprintDxns = (blueprints ?? []).map((ref) => ref.dxn);
1366
- const removedObjectDxns = (objects ?? []).map((ref) => ref.dxn);
1395
+ const removedBlueprintDxns = (blueprints ?? []).map((ref) => ref.uri);
1396
+ const removedObjectDxns = (objects ?? []).map((ref) => ref.uri);
1367
1397
  if (removedBlueprintDxns.length > 0) {
1368
1398
  const current = this._registry.get(this._blueprints);
1369
- this._registry.set(this._blueprints, current.filter((obj) => !removedBlueprintDxns.some((dxn) => DXN2.equalsEchoId(Obj6.getDXN(obj), dxn))));
1399
+ this._registry.set(this._blueprints, current.filter((obj) => !removedBlueprintDxns.some((uri) => Obj6.getURI(obj) === uri)));
1370
1400
  }
1371
1401
  if (removedObjectDxns.length > 0) {
1372
1402
  const current = this._registry.get(this._objects);
1373
- this._registry.set(this._objects, current.filter((obj) => !removedObjectDxns.some((dxn) => DXN2.equalsEchoId(Obj6.getDXN(obj), dxn))));
1403
+ this._registry.set(this._objects, current.filter((obj) => !removedObjectDxns.some((uri) => Obj6.getURI(obj) === uri)));
1374
1404
  }
1375
1405
  log4("unbind", {
1376
1406
  blueprints: blueprints?.length,
1377
1407
  objects: objects?.length
1378
- }, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 208, S: this });
1408
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 226, S: this });
1379
1409
  await Runtime.runPromise(this._runtime)(Feed.append(this._feed, [
1380
1410
  Obj6.make(Binding, {
1381
1411
  blueprints: {
@@ -1403,17 +1433,18 @@ var Binder = class extends Resource {
1403
1433
  next
1404
1434
  };
1405
1435
  }
1406
- const seen = new Set(current.map((obj) => Obj6.getDXN(obj).toString()));
1436
+ const seen = new Set(current.map((obj) => Obj6.getURI(obj)));
1407
1437
  for (const ref of refs) {
1408
- const dxn = ref.dxn.toString();
1409
- if (!seen.has(dxn)) {
1410
- seen.add(dxn);
1411
- added.push(ref);
1412
- if (ref.isAvailable) {
1413
- const target = ref.target;
1414
- if (target) {
1415
- next.push(target);
1416
- }
1438
+ const uri = ref.uri;
1439
+ if (seen.has(uri)) {
1440
+ continue;
1441
+ }
1442
+ seen.add(uri);
1443
+ added.push(ref);
1444
+ if (ref.isAvailable) {
1445
+ const target = ref.target;
1446
+ if (target) {
1447
+ next.push(target);
1417
1448
  }
1418
1449
  }
1419
1450
  }
@@ -1432,7 +1463,7 @@ var Binder = class extends Resource {
1432
1463
  objects.added.forEach((ref) => context.objects.add(ref));
1433
1464
  objects.removed.forEach((ref) => {
1434
1465
  for (const obj of context.objects) {
1435
- if (DXN2.equalsEchoId(obj.dxn, ref.dxn)) {
1466
+ if (obj.uri === ref.uri || EID3.tryParse(obj.uri) && EID3.tryParse(ref.uri) && EID3.getEntityId(EID3.tryParse(obj.uri)) === EID3.getEntityId(EID3.tryParse(ref.uri))) {
1436
1467
  context.objects.delete(obj);
1437
1468
  }
1438
1469
  }
@@ -1444,14 +1475,14 @@ var Binder = class extends Resource {
1444
1475
  * Merge resolved items into the current set, adding only items not already present (by DXN).
1445
1476
  */
1446
1477
  _mergeInto(current, resolved) {
1447
- const seen = new Set(current.map((obj) => Obj6.getDXN(obj).toString()));
1478
+ const seen = new Set(current.map((obj) => Obj6.getURI(obj)));
1448
1479
  const merged = [
1449
1480
  ...current
1450
1481
  ];
1451
1482
  for (const obj of resolved) {
1452
- const dxn = Obj6.getDXN(obj).toString();
1453
- if (!seen.has(dxn)) {
1454
- seen.add(dxn);
1483
+ const uri = Obj6.getURI(obj);
1484
+ if (!seen.has(uri)) {
1485
+ seen.add(uri);
1455
1486
  merged.push(obj);
1456
1487
  }
1457
1488
  }
@@ -1459,6 +1490,8 @@ var Binder = class extends Resource {
1459
1490
  }
1460
1491
  /**
1461
1492
  * Resolve references to objects, loading them first if needed and falling back to existing objects.
1493
+ * DXN refs (e.g. `dxn:org.dxos.blueprint.database`) resolve via the wired-up ECHO ref resolver
1494
+ * which already spans both the space DB and the hypergraph registry.
1462
1495
  */
1463
1496
  async _resolve(refs, current) {
1464
1497
  const refArray = [
@@ -1470,7 +1503,7 @@ var Binder = class extends Resource {
1470
1503
  if (ref.isAvailable) {
1471
1504
  target = ref.target;
1472
1505
  }
1473
- return target ?? current.find((obj) => Obj6.getDXN(obj).toString() === ref.dxn.toString());
1506
+ return target ?? current.find((obj) => Obj6.getURI(obj) === ref.uri);
1474
1507
  }).filter(isNonNullable3);
1475
1508
  }
1476
1509
  };
@@ -1560,7 +1593,7 @@ var Session = class extends Resource2 {
1560
1593
  */
1561
1594
  makeToolExecutionServices() {
1562
1595
  return ToolExecutionServices.pipe(Layer3.provide(Operation2.withInvocationOptions({
1563
- conversation: Obj7.getDXN(this._feed).toString()
1596
+ conversation: Obj7.getURI(this._feed)
1564
1597
  })));
1565
1598
  }
1566
1599
  /**
@@ -1629,7 +1662,7 @@ var Session = class extends Resource2 {
1629
1662
  }).pipe(Effect8.provide(Layer3.mergeAll(Layer3.succeed(Service, {
1630
1663
  binder: this.context
1631
1664
  }), Layer3.succeed(Service2, this), Operation2.withInvocationOptions({
1632
- conversation: Obj7.getDXN(this._feed).toString()
1665
+ conversation: Obj7.getURI(this._feed)
1633
1666
  }))), Effect8.withSpan("AiSession.createRequest"));
1634
1667
  }
1635
1668
  };
@@ -1753,7 +1786,6 @@ export {
1753
1786
  AiModelError,
1754
1787
  AiRequest_exports as AiRequest,
1755
1788
  AiSession_exports as AiSession,
1756
- ArtifactId,
1757
1789
  CompleteBlock,
1758
1790
  ExecutionGraph,
1759
1791
  GenerationObserver,