@dxos/assistant 0.8.4-main.ae835ea → 0.8.4-main.bc674ce

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 (116) hide show
  1. package/dist/lib/browser/{chunk-4VIJTKPM.mjs → chunk-7CDDG6LL.mjs} +252 -28
  2. package/dist/lib/browser/chunk-7CDDG6LL.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
  4. package/dist/lib/browser/extraction/index.mjs +119 -166
  5. package/dist/lib/browser/extraction/index.mjs.map +4 -4
  6. package/dist/lib/browser/index.mjs +239 -289
  7. package/dist/lib/browser/index.mjs.map +4 -4
  8. package/dist/lib/browser/meta.json +1 -1
  9. package/dist/lib/browser/testing/index.mjs +32 -0
  10. package/dist/lib/browser/testing/index.mjs.map +7 -0
  11. package/dist/lib/node-esm/{chunk-AUUC7II4.mjs → chunk-CC7ER6Q3.mjs} +251 -28
  12. package/dist/lib/node-esm/chunk-CC7ER6Q3.mjs.map +7 -0
  13. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  14. package/dist/lib/node-esm/extraction/index.mjs +119 -166
  15. package/dist/lib/node-esm/extraction/index.mjs.map +4 -4
  16. package/dist/lib/node-esm/index.mjs +239 -289
  17. package/dist/lib/node-esm/index.mjs.map +4 -4
  18. package/dist/lib/node-esm/meta.json +1 -1
  19. package/dist/lib/node-esm/testing/index.mjs +33 -0
  20. package/dist/lib/node-esm/testing/index.mjs.map +7 -0
  21. package/dist/types/src/conversation/context.d.ts +88 -62
  22. package/dist/types/src/conversation/context.d.ts.map +1 -1
  23. package/dist/types/src/conversation/context.test.d.ts +2 -0
  24. package/dist/types/src/conversation/context.test.d.ts.map +1 -0
  25. package/dist/types/src/conversation/conversation.d.ts +16 -16
  26. package/dist/types/src/conversation/conversation.d.ts.map +1 -1
  27. package/dist/types/src/conversation/conversation.test.d.ts +2 -0
  28. package/dist/types/src/conversation/conversation.test.d.ts.map +1 -0
  29. package/dist/types/src/errors.d.ts +22 -30
  30. package/dist/types/src/errors.d.ts.map +1 -1
  31. package/dist/types/src/execution-graph.d.ts +5 -2
  32. package/dist/types/src/execution-graph.d.ts.map +1 -1
  33. package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.d.ts.map +1 -1
  34. package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts +254 -252
  35. package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts.map +1 -1
  36. package/dist/types/src/extraction/extraction.d.ts +344 -309
  37. package/dist/types/src/extraction/extraction.d.ts.map +1 -1
  38. package/dist/types/src/extraction/quotes.d.ts +2 -2
  39. package/dist/types/src/extraction/quotes.d.ts.map +1 -1
  40. package/dist/types/src/functions/services.d.ts +4 -3
  41. package/dist/types/src/functions/services.d.ts.map +1 -1
  42. package/dist/types/src/functions.test.d.ts +2 -0
  43. package/dist/types/src/functions.test.d.ts.map +1 -0
  44. package/dist/types/src/session/GenericToolkit.d.ts +85 -0
  45. package/dist/types/src/session/GenericToolkit.d.ts.map +1 -0
  46. package/dist/types/src/session/artifact-diff.d.ts +1 -1
  47. package/dist/types/src/session/artifact-diff.d.ts.map +1 -1
  48. package/dist/types/src/session/format.d.ts +4 -178
  49. package/dist/types/src/session/format.d.ts.map +1 -1
  50. package/dist/types/src/session/index.d.ts +1 -0
  51. package/dist/types/src/session/index.d.ts.map +1 -1
  52. package/dist/types/src/session/observer.d.ts +6 -5
  53. package/dist/types/src/session/observer.d.ts.map +1 -1
  54. package/dist/types/src/session/session.d.ts +16 -11
  55. package/dist/types/src/session/session.d.ts.map +1 -1
  56. package/dist/types/src/session/toolkit.d.ts +5 -6
  57. package/dist/types/src/session/toolkit.d.ts.map +1 -1
  58. package/dist/types/src/session/version-pin.d.ts +3 -3
  59. package/dist/types/src/session/version-pin.d.ts.map +1 -1
  60. package/dist/types/src/testing/index.d.ts +2 -0
  61. package/dist/types/src/testing/index.d.ts.map +1 -0
  62. package/dist/types/src/testing/layer.d.ts +21 -0
  63. package/dist/types/src/testing/layer.d.ts.map +1 -0
  64. package/dist/types/src/types/artifact.d.ts +14 -2
  65. package/dist/types/src/types/artifact.d.ts.map +1 -1
  66. package/dist/types/tsconfig.tsbuildinfo +1 -1
  67. package/package.json +38 -27
  68. package/src/conversation/context.test.ts +46 -0
  69. package/src/conversation/context.ts +183 -66
  70. package/src/conversation/conversation.test.ts +65 -0
  71. package/src/conversation/conversation.ts +51 -54
  72. package/src/diff.test.ts +3 -3
  73. package/src/errors.ts +2 -2
  74. package/src/execution-graph.test.ts +45 -43
  75. package/src/execution-graph.ts +23 -14
  76. package/src/extraction/extraction-llm-function/extraction-llm-function.test.ts +2 -2
  77. package/src/extraction/extraction-llm-function/extraction-llm-function.ts +44 -54
  78. package/src/extraction/extraction-ner-function/extraction-ner-function.test.ts +14 -13
  79. package/src/extraction/extraction-ner-function/extraction-ner-function.ts +36 -44
  80. package/src/extraction/extraction-ner-function/named-entity-recognition.test.ts +10 -5
  81. package/src/extraction/extraction.ts +9 -8
  82. package/src/extraction/quotes.ts +4 -5
  83. package/src/functions/services.ts +41 -19
  84. package/src/functions.conversations.json +1 -0
  85. package/src/functions.test.ts +74 -0
  86. package/src/session/GenericToolkit.ts +131 -0
  87. package/src/session/artifact-diff.ts +1 -1
  88. package/src/session/format.test.ts +103 -39
  89. package/src/session/format.ts +17 -16
  90. package/src/session/index.ts +2 -0
  91. package/src/session/observer.ts +5 -3
  92. package/src/session/session.conversations.json +1 -1
  93. package/src/session/session.test.ts +7 -13
  94. package/src/session/session.ts +40 -19
  95. package/src/session/toolkit.ts +13 -22
  96. package/src/session/version-pin.ts +6 -6
  97. package/src/templates/{format.tpl → instructions/format.tpl} +1 -0
  98. package/src/templates/system.ts +2 -2
  99. package/src/testing/index.ts +5 -0
  100. package/src/testing/layer.ts +78 -0
  101. package/src/types/artifact.ts +33 -3
  102. package/dist/lib/browser/chunk-4VIJTKPM.mjs.map +0 -7
  103. package/dist/lib/browser/chunk-UB26N5UF.mjs +0 -89
  104. package/dist/lib/browser/chunk-UB26N5UF.mjs.map +0 -7
  105. package/dist/lib/browser/named-entity-recognition-QPYHML66.mjs +0 -13
  106. package/dist/lib/node-esm/chunk-AUUC7II4.mjs.map +0 -7
  107. package/dist/lib/node-esm/chunk-BCFXTNSK.mjs +0 -91
  108. package/dist/lib/node-esm/chunk-BCFXTNSK.mjs.map +0 -7
  109. package/dist/lib/node-esm/named-entity-recognition-2HDF46YX.mjs +0 -14
  110. package/dist/types/src/summarization/summarization.test.d.ts +0 -2
  111. package/dist/types/src/summarization/summarization.test.d.ts.map +0 -1
  112. package/src/summarization/summarization.test.ts +0 -202
  113. /package/dist/lib/browser/{named-entity-recognition-QPYHML66.mjs.map → chunk-J5LGTIGS.mjs.map} +0 -0
  114. /package/dist/lib/node-esm/{named-entity-recognition-2HDF46YX.mjs.map → chunk-HSLMI22Q.mjs.map} +0 -0
  115. /package/src/extraction/extraction-llm-function/{instructions.tpl → transcription-instructions.tpl} +0 -0
  116. /package/src/templates/{system.tpl → instructions/system.tpl} +0 -0
@@ -2,59 +2,123 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { beforeAll, describe, it } from '@effect/vitest';
5
+ import { describe, expect, it } from '@effect/vitest';
6
6
  import * as Effect from 'effect/Effect';
7
+ import * as Schema from 'effect/Schema';
7
8
 
8
9
  import { Blueprint, Template } from '@dxos/blueprints';
9
- import { Obj } from '@dxos/echo';
10
- import { type EchoDatabase } from '@dxos/echo-db';
11
- import { EchoTestBuilder } from '@dxos/echo-db/testing';
12
- import { DataType } from '@dxos/schema';
10
+ import { Database, Obj, Query } from '@dxos/echo';
11
+ import { TestHelpers } from '@dxos/effect/testing';
12
+ import { defineFunction } from '@dxos/functions';
13
+ import { Text } from '@dxos/schema';
14
+ import { Organization } from '@dxos/types';
13
15
  import { trim } from '@dxos/util';
14
16
 
15
17
  import { createSystemPrompt } from '../templates/system';
18
+ import { AssistantTestLayer } from '../testing';
16
19
 
17
20
  import { formatSystemPrompt } from './format';
18
21
 
19
- describe('format', () => {
20
- let db: EchoDatabase;
21
- beforeAll(async () => {
22
- const builder = await new EchoTestBuilder().open();
23
- ({ db } = await builder.createDatabase({
24
- types: [DataType.Text, DataType.Organization, Blueprint.Blueprint],
25
- }));
26
- });
22
+ const organizationListFunction = defineFunction({
23
+ key: 'dxos.org/function/organization-list',
24
+ name: 'Organization List',
25
+ description: 'List organizations',
26
+ inputSchema: Schema.Struct({}),
27
+ outputSchema: Schema.Array(Schema.String),
28
+ handler: Effect.fnUntraced(function* () {
29
+ const organizations = yield* Database.Service.runQuery(Query.type(Organization.Organization));
30
+ return organizations.map((organization) => organization.name);
31
+ }),
32
+ });
33
+
34
+ const TestLayer = AssistantTestLayer({
35
+ types: [Text.Text, Organization.Organization, Blueprint.Blueprint],
36
+ functions: [organizationListFunction],
37
+ });
27
38
 
39
+ describe('format', () => {
28
40
  it.effect(
29
41
  'should format',
30
- Effect.fn(function* () {
31
- const object = db.add(
32
- Obj.make(DataType.Organization, {
33
- name: 'Test',
34
- website: 'https://www.test.com',
35
- }),
36
- );
37
-
38
- const blueprint = db.add(
39
- Blueprint.make({
40
- key: 'example.com/blueprint/test',
41
- name: 'Test',
42
- instructions: Template.make({
43
- source: trim`
44
- Test
45
- This is the test blueprint.
46
- `,
42
+ Effect.fnUntraced(
43
+ function* (_) {
44
+ const { db } = yield* Database.Service;
45
+ const object = db.add(
46
+ Obj.make(Organization.Organization, {
47
+ name: 'Test',
48
+ website: 'https://www.test.com',
49
+ }),
50
+ );
51
+
52
+ const blueprint = db.add(
53
+ Blueprint.make({
54
+ key: 'example.com/blueprint/test',
55
+ name: 'Test',
56
+ instructions: Template.make({
57
+ source: trim`
58
+ Test
59
+ This is the test blueprint.
60
+ `,
61
+ }),
62
+ }),
63
+ );
64
+
65
+ const output = yield* formatSystemPrompt({
66
+ system: createSystemPrompt({}),
67
+ blueprints: [blueprint],
68
+ objects: [object],
69
+ });
70
+
71
+ console.log(output);
72
+ },
73
+ Effect.provide(TestLayer),
74
+ TestHelpers.provideTestContext,
75
+ ),
76
+ );
77
+
78
+ it.effect(
79
+ 'should format with function input',
80
+ Effect.fnUntraced(
81
+ function* (_) {
82
+ const { db } = yield* Database.Service;
83
+ const object = db.add(
84
+ Obj.make(Organization.Organization, {
85
+ name: 'Test Org',
86
+ website: 'https://www.test.com',
87
+ }),
88
+ );
89
+
90
+ const blueprint = db.add(
91
+ Blueprint.make({
92
+ key: 'example.com/blueprint/test',
93
+ name: 'Test',
94
+ instructions: Template.make({
95
+ source: trim`
96
+ Organization List:
97
+ {{#each organizations}}
98
+ - {{this}}
99
+ {{/each}}
100
+ `,
101
+ inputs: [
102
+ {
103
+ name: 'organizations',
104
+ kind: 'function',
105
+ function: organizationListFunction.key,
106
+ },
107
+ ],
108
+ }),
47
109
  }),
48
- }),
49
- );
110
+ );
50
111
 
51
- const output = yield* formatSystemPrompt({
52
- system: createSystemPrompt({}),
53
- blueprints: [blueprint, blueprint],
54
- objects: [object, object],
55
- });
112
+ const output = yield* formatSystemPrompt({
113
+ system: createSystemPrompt({}),
114
+ blueprints: [blueprint],
115
+ objects: [object],
116
+ });
56
117
 
57
- console.log(output);
58
- }),
118
+ expect(output).to.include('Test Org');
119
+ },
120
+ Effect.provide(TestLayer),
121
+ TestHelpers.provideTestContext,
122
+ ),
59
123
  );
60
124
  });
@@ -2,24 +2,22 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import * as Array from 'effect/Array';
6
5
  import * as Effect from 'effect/Effect';
7
6
  import * as Function from 'effect/Function';
8
7
  import * as Option from 'effect/Option';
9
8
 
10
9
  import { Template } from '@dxos/blueprints';
11
10
  import { Obj } from '@dxos/echo';
12
- import { type ObjectId } from '@dxos/echo/internal';
13
11
  import { ObjectVersion } from '@dxos/echo-db';
14
- import { DatabaseService } from '@dxos/functions';
12
+ import { type ObjectId } from '@dxos/keys';
15
13
  import { log } from '@dxos/log';
16
- import { type ContentBlock, DataType } from '@dxos/schema';
14
+ import { type ContentBlock, Message } from '@dxos/types';
17
15
  import { trim } from '@dxos/util';
18
16
 
19
17
  import { AiAssistantError } from '../errors';
20
18
 
21
19
  import { ArtifactDiffResolver } from './artifact-diff';
22
- import { type AiSessionRunParams } from './session';
20
+ import { type AiSessionRunError, type AiSessionRunProps } from './session';
23
21
 
24
22
  /**
25
23
  * Formats the system prompt.
@@ -29,20 +27,20 @@ export const formatSystemPrompt = ({
29
27
  system,
30
28
  blueprints = [],
31
29
  objects = [],
32
- }: Pick<AiSessionRunParams<any>, 'system' | 'blueprints' | 'objects'>) =>
30
+ }: Pick<AiSessionRunProps<any>, 'system' | 'blueprints' | 'objects'>) =>
33
31
  Effect.gen(function* () {
34
32
  const blueprintDefs = yield* Function.pipe(
35
33
  blueprints,
36
34
  Effect.forEach((blueprint) => Effect.succeed(blueprint.instructions)),
37
- Effect.flatMap(Effect.forEach((template) => DatabaseService.loadOption(template.source))),
38
- Effect.map(Array.filter(Option.isSome)),
39
- Effect.map(
40
- Array.map(
41
- (template) => trim`
35
+ Effect.flatMap(
36
+ Effect.forEach((template) =>
37
+ Effect.gen(function* () {
38
+ return trim`
42
39
  <blueprint>
43
- ${Template.process(template.value.content)}
40
+ ${yield* Template.processTemplate(template)}
44
41
  </blueprint>
45
- `,
42
+ `;
43
+ }),
46
44
  ),
47
45
  ),
48
46
  Effect.map((blueprints) =>
@@ -74,7 +72,10 @@ export const formatSystemPrompt = ({
74
72
  */
75
73
  // TODO(burdon): Move to AiPreprocessor.
76
74
  // TODO(burdon): Convert util below to `Effect.fn` (to preserve stack info)
77
- export const formatUserPrompt = ({ prompt, history = [] }: Pick<AiSessionRunParams<any>, 'prompt' | 'history'>) =>
75
+ export const formatUserPrompt = ({
76
+ prompt,
77
+ history = [],
78
+ }: Pick<AiSessionRunProps<any>, 'prompt' | 'history'>): Effect.Effect<Message.Message, AiSessionRunError> =>
78
79
  Effect.gen(function* () {
79
80
  const blocks: ContentBlock.Any[] = [];
80
81
 
@@ -105,14 +106,14 @@ export const formatUserPrompt = ({ prompt, history = [] }: Pick<AiSessionRunPara
105
106
  }
106
107
  }
107
108
 
108
- return Obj.make(DataType.Message, {
109
+ return Obj.make(Message.Message, {
109
110
  created: new Date().toISOString(),
110
111
  sender: { role: 'user' },
111
112
  blocks: [...blocks, { _tag: 'text', text: prompt }],
112
113
  });
113
114
  });
114
115
 
115
- const gatherObjectVersions = (messages: DataType.Message[]): Map<ObjectId, ObjectVersion> => {
116
+ const gatherObjectVersions = (messages: Message.Message[]): Map<ObjectId, ObjectVersion> => {
116
117
  const artifactIds = new Map<ObjectId, ObjectVersion>();
117
118
  for (const message of messages) {
118
119
  for (const block of message.blocks) {
@@ -7,3 +7,5 @@ export * from './observer';
7
7
  export * from './session';
8
8
  export * from './toolkit';
9
9
  export * from './version-pin';
10
+
11
+ export * as GenericToolkit from './GenericToolkit';
@@ -2,21 +2,23 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ import type * as Tool from '@effect/ai/Tool';
5
6
  import * as Effect from 'effect/Effect';
6
7
  import * as Function from 'effect/Function';
7
8
 
8
9
  import { type AiParser, type ConsolePrinter } from '@dxos/ai';
9
- import { type DataType } from '@dxos/schema';
10
+ import { type Message } from '@dxos/types';
10
11
 
11
12
  /**
12
13
  * Live observer of the generation process.
13
14
  */
14
- export interface GenerationObserver extends AiParser.ParseResponseCallbacks {
15
+ export interface GenerationObserver<Tools extends Record<string, Tool.Any> = any>
16
+ extends AiParser.ParseResponseCallbacks<Tools> {
15
17
  /**
16
18
  * Complete messages fired during the session, both from the model and from the user.
17
19
  * This message will contain all message blocks emitted through the `onBlock` callback.
18
20
  */
19
- onMessage: (message: DataType.Message) => Effect.Effect<void>;
21
+ onMessage: (message: Message.Message) => Effect.Effect<void>;
20
22
  }
21
23
 
22
24
  export const GenerationObserver = Object.freeze({
@@ -1 +1 @@
1
- {"conversations":[{"parameters":{"model":"@anthropic/claude-3-5-sonnet-20241022","stream":true,"tools":[]},"prompt":{"content":[{"role":"user","content":"Hello world!","options":{}}]},"response":[{"type":"response-metadata","id":"msg_01Bm496JGgDMgC9YwdYTFFHo","modelId":"claude-3-5-sonnet-20241022","timestamp":"1970-01-01T00:00:00.000Z","metadata":{}},{"type":"text-start","id":"0","metadata":{}},{"type":"text-delta","id":"0","delta":"Hi","metadata":{}},{"type":"text-delta","id":"0","delta":"!","metadata":{}},{"type":"text-delta","id":"0","delta":" How can","metadata":{}},{"type":"text-delta","id":"0","delta":" I help you today?","metadata":{}},{"type":"text-end","id":"0","metadata":{}},{"type":"finish","reason":"stop","usage":{"inputTokens":10,"outputTokens":12,"totalTokens":22},"metadata":{"anthropic":{"usage":{"cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":0},"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"input_tokens":10,"output_tokens":1,"server_tool_use":null,"service_tier":"standard"}}}}]},{"parameters":{"model":"@anthropic/claude-3-5-sonnet-20241022","stream":true,"tools":[{"name":"Calculator","description":"Basic calculator tool","inputSchema":{"type":"object","required":["input"],"properties":{"input":{"type":"string","description":"The calculation to perform."}},"additionalProperties":false}}]},"prompt":{"content":[{"role":"user","content":"What is 10 + 30?","options":{}}]},"response":[{"type":"response-metadata","id":"msg_01UNTbjtTHEpdFgGunu2k8Br","modelId":"claude-3-5-sonnet-20241022","timestamp":"1970-01-01T00:00:00.000Z","metadata":{}},{"type":"text-start","id":"0","metadata":{}},{"type":"text-delta","id":"0","delta":"I","metadata":{}},{"type":"text-delta","id":"0","delta":"'ll help","metadata":{}},{"type":"text-delta","id":"0","delta":" you calculate","metadata":{}},{"type":"text-delta","id":"0","delta":" ","metadata":{}},{"type":"text-delta","id":"0","delta":"10 + 30","metadata":{}},{"type":"text-delta","id":"0","delta":" using the","metadata":{}},{"type":"text-delta","id":"0","delta":" Calculator tool.","metadata":{}},{"type":"text-end","id":"0","metadata":{}},{"type":"tool-params-start","id":"toolu_01LTGUgfihCQtVchm1b37xHQ","name":"Calculator","providerExecuted":false,"metadata":{}},{"type":"tool-params-delta","id":"toolu_01LTGUgfihCQtVchm1b37xHQ","delta":"","metadata":{}},{"type":"tool-params-delta","id":"toolu_01LTGUgfihCQtVchm1b37xHQ","delta":"{\"input\": \"","metadata":{}},{"type":"tool-params-delta","id":"toolu_01LTGUgfihCQtVchm1b37xHQ","delta":"10 + 30","metadata":{}},{"type":"tool-params-delta","id":"toolu_01LTGUgfihCQtVchm1b37xHQ","delta":"\"}","metadata":{}},{"type":"tool-params-end","id":"toolu_01LTGUgfihCQtVchm1b37xHQ","metadata":{}},{"type":"tool-call","id":"toolu_01LTGUgfihCQtVchm1b37xHQ","name":"Calculator","params":{"input":"10 + 30"},"providerExecuted":false,"metadata":{}},{"type":"finish","reason":"tool-calls","usage":{"inputTokens":394,"outputTokens":73,"totalTokens":467},"metadata":{"anthropic":{"usage":{"cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":0},"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"input_tokens":394,"output_tokens":1,"server_tool_use":null,"service_tier":"standard"}}}}]},{"parameters":{"model":"@anthropic/claude-3-5-sonnet-20241022","stream":true,"tools":[{"name":"Calculator","description":"Basic calculator tool","inputSchema":{"type":"object","required":["input"],"properties":{"input":{"type":"string","description":"The calculation to perform."}},"additionalProperties":false}}]},"prompt":{"content":[{"role":"user","content":"What is 10 + 30?","options":{}},{"role":"assistant","content":[{"type":"text","text":"I'll help you calculate 10 + 30 using the Calculator tool.","options":{}},{"type":"tool-call","id":"toolu_01LTGUgfihCQtVchm1b37xHQ","name":"Calculator","params":{"input":"10 + 30"},"providerExecuted":false,"options":{}}],"options":{}},{"role":"tool","content":[{"type":"tool-result","id":"toolu_01LTGUgfihCQtVchm1b37xHQ","name":"Calculator","result":{"result":40},"options":{}}],"options":{}}]},"response":[{"type":"response-metadata","id":"msg_01AKio3GheJGn38BhvAp33rs","modelId":"claude-3-5-sonnet-20241022","timestamp":"1970-01-01T00:00:00.000Z","metadata":{}},{"type":"text-start","id":"0","metadata":{}},{"type":"text-delta","id":"0","delta":"The result","metadata":{}},{"type":"text-delta","id":"0","delta":" of 10 +","metadata":{}},{"type":"text-delta","id":"0","delta":" 30 is ","metadata":{}},{"type":"text-delta","id":"0","delta":"40.","metadata":{}},{"type":"text-end","id":"0","metadata":{}},{"type":"finish","reason":"stop","usage":{"inputTokens":482,"outputTokens":18,"totalTokens":500},"metadata":{"anthropic":{"usage":{"cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":0},"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"input_tokens":482,"output_tokens":3,"server_tool_use":null,"service_tier":"standard"}}}}]}]}
1
+ {"conversations":[{"parameters":{"model":"@anthropic/claude-3-5-sonnet-20241022","stream":true,"tools":[]},"prompt":{"content":[{"role":"user","content":"Hello world!","options":{}}]},"response":[{"type":"response-metadata","id":"msg_01Bm496JGgDMgC9YwdYTFFHo","modelId":"claude-3-5-sonnet-20241022","timestamp":"1970-01-01T00:00:00.000Z","metadata":{}},{"type":"text-start","id":"0","metadata":{}},{"type":"text-delta","id":"0","delta":"Hi","metadata":{}},{"type":"text-delta","id":"0","delta":"!","metadata":{}},{"type":"text-delta","id":"0","delta":" How can","metadata":{}},{"type":"text-delta","id":"0","delta":" I help you today?","metadata":{}},{"type":"text-end","id":"0","metadata":{}},{"type":"finish","reason":"stop","usage":{"inputTokens":10,"outputTokens":12,"totalTokens":22},"metadata":{"anthropic":{"usage":{"cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":0},"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"input_tokens":10,"output_tokens":1,"server_tool_use":null,"service_tier":"standard"}}}}]},{"parameters":{"model":"@anthropic/claude-3-5-sonnet-20241022","stream":true,"tools":[{"name":"Calculator","description":"Basic calculator tool","inputSchema":{"type":"object","required":["input"],"properties":{"input":{"type":"string","description":"The calculation to perform."}},"additionalProperties":false}}]},"prompt":{"content":[{"role":"user","content":"What is 10 + 30?","options":{}}]},"response":[{"type":"response-metadata","id":"msg_01UNTbjtTHEpdFgGunu2k8Br","modelId":"claude-3-5-sonnet-20241022","timestamp":"1970-01-01T00:00:00.000Z","metadata":{}},{"type":"text-start","id":"0","metadata":{}},{"type":"text-delta","id":"0","delta":"I","metadata":{}},{"type":"text-delta","id":"0","delta":"'ll help","metadata":{}},{"type":"text-delta","id":"0","delta":" you calculate","metadata":{}},{"type":"text-delta","id":"0","delta":" ","metadata":{}},{"type":"text-delta","id":"0","delta":"10 + 30","metadata":{}},{"type":"text-delta","id":"0","delta":" using the","metadata":{}},{"type":"text-delta","id":"0","delta":" Calculator tool.","metadata":{}},{"type":"text-end","id":"0","metadata":{}},{"type":"tool-params-start","id":"toolu_01LTGUgfihCQtVchm1b37xHQ","name":"Calculator","providerExecuted":false,"metadata":{}},{"type":"tool-params-delta","id":"toolu_01LTGUgfihCQtVchm1b37xHQ","delta":"","metadata":{}},{"type":"tool-params-delta","id":"toolu_01LTGUgfihCQtVchm1b37xHQ","delta":"{\"input\": \"","metadata":{}},{"type":"tool-params-delta","id":"toolu_01LTGUgfihCQtVchm1b37xHQ","delta":"10 + 30","metadata":{}},{"type":"tool-params-delta","id":"toolu_01LTGUgfihCQtVchm1b37xHQ","delta":"\"}","metadata":{}},{"type":"tool-params-end","id":"toolu_01LTGUgfihCQtVchm1b37xHQ","metadata":{}},{"type":"tool-call","id":"toolu_01LTGUgfihCQtVchm1b37xHQ","name":"Calculator","params":{"input":"10 + 30"},"providerExecuted":false,"metadata":{}},{"type":"finish","reason":"tool-calls","usage":{"inputTokens":394,"outputTokens":73,"totalTokens":467},"metadata":{"anthropic":{"usage":{"cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":0},"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"input_tokens":394,"output_tokens":1,"server_tool_use":null,"service_tier":"standard"}}}}]},{"parameters":{"model":"@anthropic/claude-3-5-sonnet-20241022","stream":true,"tools":[{"name":"Calculator","description":"Basic calculator tool","inputSchema":{"type":"object","required":["input"],"properties":{"input":{"type":"string","description":"The calculation to perform."}},"additionalProperties":false}}]},"prompt":{"content":[{"role":"user","content":"What is 10 + 30?","options":{}},{"role":"assistant","content":[{"type":"text","text":"I'll help you calculate 10 + 30 using the Calculator tool.","options":{}},{"type":"tool-call","id":"toolu_01LTGUgfihCQtVchm1b37xHQ","name":"Calculator","params":{"input":"10 + 30"},"providerExecuted":false,"options":{}}],"options":{}},{"role":"tool","content":[{"type":"tool-result","id":"toolu_01LTGUgfihCQtVchm1b37xHQ","name":"Calculator","isFailure":false,"result":{"result":40},"options":{}}],"options":{}}]},"response":[{"type":"response-metadata","id":"msg_01AKio3GheJGn38BhvAp33rs","modelId":"claude-3-5-sonnet-20241022","timestamp":"1970-01-01T00:00:00.000Z","metadata":{}},{"type":"text-start","id":"0","metadata":{}},{"type":"text-delta","id":"0","delta":"The result","metadata":{}},{"type":"text-delta","id":"0","delta":" of 10 +","metadata":{}},{"type":"text-delta","id":"0","delta":" 30 is ","metadata":{}},{"type":"text-delta","id":"0","delta":"40.","metadata":{}},{"type":"text-end","id":"0","metadata":{}},{"type":"finish","reason":"stop","usage":{"inputTokens":482,"outputTokens":18,"totalTokens":500},"metadata":{"anthropic":{"usage":{"cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":0},"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"input_tokens":482,"output_tokens":3,"server_tool_use":null,"service_tier":"standard"}}}}]},{"parameters":{"model":"@anthropic/claude-opus-4-0","stream":true,"tools":[]},"prompt":{"content":[{"role":"user","content":"Hello world!","options":{}}]},"response":[{"type":"response-metadata","id":"msg_01QPPeofAkjiYa83LPCeSYfS","modelId":"claude-opus-4-20250514","timestamp":"1970-01-01T00:00:00.000Z","metadata":{}},{"type":"text-start","id":"0","metadata":{}},{"type":"text-delta","id":"0","delta":"Hello!","metadata":{}},{"type":"text-delta","id":"0","delta":" Welcome","metadata":{}},{"type":"text-delta","id":"0","delta":" to the worl","metadata":{}},{"type":"text-delta","id":"0","delta":"d!","metadata":{}},{"type":"text-delta","id":"0","delta":" 🌍 ","metadata":{}},{"type":"text-delta","id":"0","delta":"How","metadata":{}},{"type":"text-delta","id":"0","delta":" are you doing today? Is there anything","metadata":{}},{"type":"text-delta","id":"0","delta":" specific you'd like to chat about or","metadata":{}},{"type":"text-delta","id":"0","delta":" any questions","metadata":{}},{"type":"text-delta","id":"0","delta":" I can help you with?","metadata":{}},{"type":"text-end","id":"0","metadata":{}},{"type":"finish","reason":"stop","usage":{"inputTokens":10,"outputTokens":40,"totalTokens":50},"metadata":{"anthropic":{"usage":{"cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":0},"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"input_tokens":10,"output_tokens":2,"server_tool_use":null,"service_tier":"standard"}}}}]},{"parameters":{"model":"@anthropic/claude-opus-4-0","stream":true,"tools":[{"name":"Calculator","description":"Basic calculator tool","inputSchema":{"type":"object","required":["input"],"properties":{"input":{"type":"string","description":"The calculation to perform."}},"additionalProperties":false}}]},"prompt":{"content":[{"role":"user","content":"What is 10 + 30?","options":{}}]},"response":[{"type":"response-metadata","id":"msg_01EaHNEDYN3Hvp5toY8hQGe6","modelId":"claude-opus-4-20250514","timestamp":"1970-01-01T00:00:00.000Z","metadata":{}},{"type":"text-start","id":"0","metadata":{}},{"type":"text-delta","id":"0","delta":"I'll help","metadata":{}},{"type":"text-delta","id":"0","delta":" you calculate ","metadata":{}},{"type":"text-delta","id":"0","delta":"10 + 30.","metadata":{}},{"type":"text-end","id":"0","metadata":{}},{"type":"tool-params-start","id":"toolu_01X4qkrMwCisiUN8Cm4E4Voe","name":"Calculator","providerExecuted":false,"metadata":{}},{"type":"tool-params-delta","id":"toolu_01X4qkrMwCisiUN8Cm4E4Voe","delta":"","metadata":{}},{"type":"tool-params-delta","id":"toolu_01X4qkrMwCisiUN8Cm4E4Voe","delta":"{\"input\": ","metadata":{}},{"type":"tool-params-delta","id":"toolu_01X4qkrMwCisiUN8Cm4E4Voe","delta":"\"10 + 3","metadata":{}},{"type":"tool-params-delta","id":"toolu_01X4qkrMwCisiUN8Cm4E4Voe","delta":"0\"}","metadata":{}},{"type":"tool-params-end","id":"toolu_01X4qkrMwCisiUN8Cm4E4Voe","metadata":{}},{"type":"tool-call","id":"toolu_01X4qkrMwCisiUN8Cm4E4Voe","name":"Calculator","params":{"input":"10 + 30"},"providerExecuted":false,"metadata":{}},{"type":"finish","reason":"tool-calls","usage":{"inputTokens":394,"outputTokens":68,"totalTokens":462},"metadata":{"anthropic":{"usage":{"cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":0},"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"input_tokens":394,"output_tokens":3,"server_tool_use":null,"service_tier":"standard"}}}}]},{"parameters":{"model":"@anthropic/claude-opus-4-0","stream":true,"tools":[{"name":"Calculator","description":"Basic calculator tool","inputSchema":{"type":"object","required":["input"],"properties":{"input":{"type":"string","description":"The calculation to perform."}},"additionalProperties":false}}]},"prompt":{"content":[{"role":"user","content":"What is 10 + 30?","options":{}},{"role":"assistant","content":[{"type":"text","text":"I'll help you calculate 10 + 30.","options":{}},{"type":"tool-call","id":"toolu_01X4qkrMwCisiUN8Cm4E4Voe","name":"Calculator","params":{"input":"10 + 30"},"providerExecuted":false,"options":{}}],"options":{}},{"role":"tool","content":[{"type":"tool-result","id":"toolu_01X4qkrMwCisiUN8Cm4E4Voe","name":"Calculator","isFailure":false,"result":{"result":40},"options":{}}],"options":{}}]},"response":[{"type":"response-metadata","id":"msg_01RjnEkFT3iEUFCpfC4B28aS","modelId":"claude-opus-4-20250514","timestamp":"1970-01-01T00:00:00.000Z","metadata":{}},{"type":"text-start","id":"0","metadata":{}},{"type":"text-delta","id":"0","delta":"10 + 30 = ","metadata":{}},{"type":"text-delta","id":"0","delta":"40","metadata":{}},{"type":"text-end","id":"0","metadata":{}},{"type":"finish","reason":"stop","usage":{"inputTokens":478,"outputTokens":12,"totalTokens":490},"metadata":{"anthropic":{"usage":{"cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":0},"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"input_tokens":478,"output_tokens":8,"server_tool_use":null,"service_tier":"standard"}}}}]}]}
@@ -9,13 +9,12 @@ import * as Effect from 'effect/Effect';
9
9
  import * as Layer from 'effect/Layer';
10
10
  import * as Schema from 'effect/Schema';
11
11
 
12
- import { AiService, MemoizedAiService, ToolExecutionService, ToolResolverService } from '@dxos/ai';
13
- import { AiServiceTestingPreset } from '@dxos/ai/testing';
14
12
  import { Obj, Type } from '@dxos/echo';
15
- import { TestHelpers } from '@dxos/effect';
16
- import { TracingService } from '@dxos/functions';
13
+ import { TestHelpers } from '@dxos/effect/testing';
17
14
  import { log } from '@dxos/log';
18
15
 
16
+ import { AssistantTestLayer } from '../testing';
17
+
19
18
  import { AiSession } from './session';
20
19
 
21
20
  // Define a calendar event artifact schema.
@@ -25,7 +24,7 @@ const CalendarEventSchema = Schema.Struct({
25
24
  endTime: Schema.String,
26
25
  description: Schema.String,
27
26
  }).pipe(
28
- Type.Obj({
27
+ Type.object({
29
28
  typename: 'example.com/type/CalendarEvent',
30
29
  version: '0.1.0',
31
30
  }),
@@ -66,15 +65,10 @@ const toolkitLayer = TestToolkit.toLayer({
66
65
  });
67
66
 
68
67
  const TestLayer = Layer.mergeAll(
68
+ AssistantTestLayer({
69
+ types: [CalendarEventSchema],
70
+ }),
69
71
  toolkitLayer,
70
- AiService.model('@anthropic/claude-3-5-sonnet-20241022'),
71
- TracingService.layerNoop,
72
- ToolResolverService.layerEmpty,
73
- ToolExecutionService.layerEmpty,
74
- ).pipe(
75
- //
76
- Layer.provideMerge(MemoizedAiService.layerTest()),
77
- Layer.provide(AiServiceTestingPreset('direct')),
78
72
  );
79
73
 
80
74
  describe('AiSession', () => {
@@ -24,9 +24,9 @@ import {
24
24
  import { type Blueprint } from '@dxos/blueprints';
25
25
  import { todo } from '@dxos/debug';
26
26
  import { Obj } from '@dxos/echo';
27
- import { TracingService } from '@dxos/functions';
27
+ import { type FunctionInvocationService, TracingService } from '@dxos/functions';
28
28
  import { log } from '@dxos/log';
29
- import { DataType } from '@dxos/schema';
29
+ import { Message } from '@dxos/types';
30
30
 
31
31
  import { type AiAssistantError } from '../errors';
32
32
 
@@ -39,21 +39,22 @@ export type AiSessionRunRequirements =
39
39
  | LanguageModel.LanguageModel
40
40
  | ToolExecutionService
41
41
  | ToolResolverService
42
- | TracingService;
42
+ | TracingService
43
+ | FunctionInvocationService;
43
44
 
44
- export type AiSessionRunParams<Tools extends Record<string, Tool.Any>> = {
45
+ export type AiSessionOptions = {};
46
+
47
+ export type AiSessionRunProps<Tools extends Record<string, Tool.Any>> = {
45
48
  prompt: string;
46
49
  // TODO(wittjosiah): Rename to systemPrompt.
47
50
  system?: string;
48
- history?: DataType.Message[];
49
- objects?: Obj.Any[];
50
- blueprints?: Blueprint.Blueprint[];
51
+ history?: Message.Message[];
52
+ objects?: Obj.Unknown[];
53
+ blueprints?: readonly Blueprint.Blueprint[];
51
54
  toolkit?: Toolkit.WithHandler<Tools>;
52
- observer?: GenerationObserver;
55
+ observer?: GenerationObserver<Tools>;
53
56
  };
54
57
 
55
- export type AiSessionOptions = {};
56
-
57
58
  /**
58
59
  * Contains message history, tools, current context.
59
60
  * Current context means the state of the app, time of day, and other contextual information.
@@ -70,13 +71,25 @@ export class AiSession {
70
71
 
71
72
  /** Message history from queue. */
72
73
  // TODO(burdon): Evolve into supporting a git-like graph of messages.
73
- private _history: DataType.Message[] = [];
74
+ private _history: Message.Message[] = [];
74
75
 
75
76
  /** Pending messages for this session (incl. the current prompt). */
76
- private _pending: DataType.Message[] = [];
77
+ private _pending: Message.Message[] = [];
78
+
79
+ private _started = 0;
80
+ private _ended = 0;
81
+ private _toolCalls = 0;
77
82
 
78
83
  constructor(private readonly _options: AiSessionOptions = {}) {}
79
84
 
85
+ get duration(): number {
86
+ return this._ended - this._started;
87
+ }
88
+
89
+ get toolCalls(): number {
90
+ return this._toolCalls;
91
+ }
92
+
80
93
  run = <Tools extends Record<string, Tool.Any>>({
81
94
  prompt,
82
95
  system: systemTemplate,
@@ -85,13 +98,14 @@ export class AiSession {
85
98
  blueprints = [],
86
99
  toolkit,
87
100
  observer = GenerationObserver.noop(),
88
- }: AiSessionRunParams<Tools>): Effect.Effect<DataType.Message[], AiSessionRunError, AiSessionRunRequirements> =>
101
+ }: AiSessionRunProps<Tools>): Effect.Effect<Message.Message[], AiSessionRunError, AiSessionRunRequirements> =>
89
102
  Effect.gen(this, function* () {
103
+ this._started = Date.now();
90
104
  this._history = [...history];
91
105
  this._pending = [];
92
106
  const pending = this._pending;
93
107
 
94
- const submitMessage = Effect.fnUntraced(function* (message: DataType.Message) {
108
+ const submitMessage = Effect.fnUntraced(function* (message: Message.Message) {
95
109
  pending.push(message);
96
110
  yield* observer.onMessage(message);
97
111
  yield* TracingService.emitConverationMessage(message);
@@ -103,7 +117,9 @@ export class AiSession {
103
117
  const promptMessage = yield* submitMessage(yield* formatUserPrompt({ prompt, history }));
104
118
 
105
119
  // Generate system and prompt messages.
106
- const system = yield* formatSystemPrompt({ system: systemTemplate, blueprints, objects });
120
+ const system = yield* formatSystemPrompt({ system: systemTemplate, blueprints, objects }).pipe(Effect.orDie);
121
+
122
+ // log('system', { prompt: system });
107
123
 
108
124
  // Tool call loop.
109
125
  do {
@@ -135,9 +151,11 @@ export class AiSession {
135
151
  Effect.map(Chunk.toArray),
136
152
  );
137
153
 
154
+ // log('blocks', { blocks });
155
+
138
156
  // Create the response message.
139
157
  const response = yield* submitMessage(
140
- Obj.make(DataType.Message, {
158
+ Obj.make(Message.Message, {
141
159
  created: new Date().toISOString(),
142
160
  sender: { role: 'assistant' },
143
161
  blocks,
@@ -170,15 +188,18 @@ export class AiSession {
170
188
  // TODO(wittjosiah): Sometimes tool error results are added to the queue before the tool agent statuses.
171
189
  // This results in a broken execution graph.
172
190
  yield* submitMessage(
173
- Obj.make(DataType.Message, {
191
+ Obj.make(Message.Message, {
174
192
  created: new Date().toISOString(),
175
193
  sender: { role: 'tool' },
176
194
  blocks: toolResults,
177
195
  }),
178
196
  );
197
+
198
+ this._toolCalls++;
179
199
  } while (true);
180
200
 
181
- log('done', { pending: this._pending.length });
201
+ this._ended = Date.now();
202
+ log('done', { pending: this._pending.length, duration: this.duration, tools: this._toolCalls });
182
203
  return this._pending;
183
204
  }).pipe(this._semaphore.withPermits(1), Effect.withSpan('AiSession.run'));
184
205
 
@@ -188,7 +209,7 @@ export class AiSession {
188
209
  // TODO(burdon): Implement or remove.
189
210
  async runStructured<S extends Schema.Schema.AnyNoContext>(
190
211
  _schema: S,
191
- _options: AiSessionRunParams<any>,
212
+ _options: AiSessionRunProps<any>,
192
213
  ): Promise<Schema.Schema.Type<S>> {
193
214
  return todo();
194
215
  // const parser = structuredOutputParser(schema);
@@ -4,45 +4,36 @@
4
4
 
5
5
  import type * as Tool from '@effect/ai/Tool';
6
6
  import * as Toolkit from '@effect/ai/Toolkit';
7
- import type * as Context from 'effect/Context';
8
7
  import * as Effect from 'effect/Effect';
9
8
 
10
- import { type AiToolNotFoundError, ToolExecutionService, type ToolId, ToolResolverService } from '@dxos/ai';
9
+ import { type AiToolNotFoundError, ToolExecutionService, ToolResolverService } from '@dxos/ai';
11
10
  import { type Blueprint } from '@dxos/blueprints';
12
11
  import { isTruthy } from '@dxos/util';
13
12
 
14
- export type ToolkitParams<Tools extends Record<string, Tool.Any>> = {
15
- toolkit?: Toolkit.Toolkit<Tools>;
16
- toolIds?: ToolId[];
17
- blueprints?: Blueprint.Blueprint[];
13
+ export type CreateToolkitProps = {
14
+ toolkit?: Toolkit.Any;
15
+ blueprints?: readonly Blueprint.Blueprint[];
18
16
  };
19
17
 
20
18
  /**
21
19
  * Build a combined toolkit from the blueprint tools and the provided toolkit.
22
20
  */
23
- export const createToolkit = <Tools extends Record<string, Tool.Any> = {}>({
24
- toolkit: toolkitParam,
25
- toolIds = [],
21
+ export const createToolkit = ({
22
+ toolkit: toolkitProp,
26
23
  blueprints = [],
27
- }: ToolkitParams<Tools>): Effect.Effect<
24
+ }: CreateToolkitProps): Effect.Effect<
28
25
  Toolkit.WithHandler<any>,
29
26
  AiToolNotFoundError,
30
- ToolResolverService | ToolExecutionService | Tool.HandlersFor<Tools>
27
+ ToolResolverService | ToolExecutionService | Tool.HandlersFor<any>
31
28
  > =>
32
29
  Effect.gen(function* () {
33
- const blueprintToolkit = yield* ToolResolverService.resolveToolkit([
34
- ...blueprints.flatMap(({ tools }) => tools),
35
- ...toolIds,
36
- ]);
30
+ const blueprintToolkit = yield* ToolResolverService.resolveToolkit(blueprints.flatMap(({ tools }) => tools));
31
+ const blueprintToolHandler = yield* blueprintToolkit.toContext(ToolExecutionService.handlersFor(blueprintToolkit));
37
32
 
38
- const blueprintToolkitHandler: Context.Context<Tool.HandlersFor<any>> = yield* blueprintToolkit.toContext(
39
- ToolExecutionService.handlersFor(blueprintToolkit),
40
- );
41
-
42
- const toolkit = Toolkit.merge(...[toolkitParam, blueprintToolkit].filter(isTruthy));
43
- return yield* toolkit.pipe(Effect.provide(blueprintToolkitHandler)) as any as Effect.Effect<
33
+ const toolkit = Toolkit.merge(...[toolkitProp, blueprintToolkit].filter(isTruthy));
34
+ return yield* toolkit.pipe(Effect.provide(blueprintToolHandler)) as any as Effect.Effect<
44
35
  Toolkit.WithHandler<any>,
45
36
  never,
46
- Tool.HandlersFor<Tools>
37
+ Tool.HandlersFor<any>
47
38
  >;
48
39
  });
@@ -4,10 +4,10 @@
4
4
 
5
5
  import * as Schema from 'effect/Schema';
6
6
 
7
- import { type AnyEchoObject, ObjectId } from '@dxos/echo/internal';
8
- import { type ObjectVersion } from '@dxos/echo-db';
9
- import { getVersion } from '@dxos/echo-db';
10
- import { type ContentBlock } from '@dxos/schema';
7
+ import { type Obj } from '@dxos/echo';
8
+ import { type ObjectVersion, getVersion } from '@dxos/echo-db';
9
+ import { ObjectId } from '@dxos/keys';
10
+ import { type ContentBlock } from '@dxos/types';
11
11
 
12
12
  // TODO(dmaretskyi): Extract.
13
13
  const ObjectVersionSchema = Schema.Unknown as Schema.Schema<ObjectVersion>;
@@ -27,11 +27,11 @@ export interface VersionPin extends Schema.Schema.Type<typeof VersionPinSchema>
27
27
 
28
28
  export const VersionPin: typeof VersionPinSchema & {
29
29
  DISPOSITION: 'version-pin';
30
- fromObject: (object: AnyEchoObject) => VersionPin;
30
+ fromObject: (object: Obj.Unknown) => VersionPin;
31
31
  createBlock: (pin: VersionPin) => ContentBlock.Any;
32
32
  } = class extends VersionPinSchema {
33
33
  static readonly DISPOSITION = 'version-pin';
34
- static fromObject(object: AnyEchoObject): VersionPin {
34
+ static fromObject(object: Obj.Unknown): VersionPin {
35
35
  return VersionPin.make({
36
36
  objectId: object.id,
37
37
  version: getVersion(object),
@@ -45,6 +45,7 @@ You can reply with a block reference for objects if you have the DXN. For exampl
45
45
 
46
46
  Each suggestion must in the form of a proposed action enclosed in a <suggestion> tag.
47
47
  Example: <suggestion>Show on a map</suggestion>
48
+ Do not use bullets when listing suggestions.
48
49
 
49
50
  ### Multiple choice questions
50
51
 
@@ -7,8 +7,8 @@ import defaultsDeep from 'lodash.defaultsdeep';
7
7
  import { type ModelCapabilities } from '@dxos/ai';
8
8
  import { Template } from '@dxos/blueprints';
9
9
 
10
- import FORMAT from './format.tpl?raw';
11
- import SYSTEM from './system.tpl?raw';
10
+ import FORMAT from './instructions/format.tpl?raw';
11
+ import SYSTEM from './instructions/system.tpl?raw';
12
12
 
13
13
  /**
14
14
  * System template variables.
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ export * from './layer';