@dxos/assistant-toolkit 0.8.4-main.ae835ea

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 (200) hide show
  1. package/LICENSE +8 -0
  2. package/README.md +3 -0
  3. package/dist/lib/browser/index.mjs +2481 -0
  4. package/dist/lib/browser/index.mjs.map +7 -0
  5. package/dist/lib/browser/meta.json +1 -0
  6. package/dist/lib/node-esm/index.mjs +2483 -0
  7. package/dist/lib/node-esm/index.mjs.map +7 -0
  8. package/dist/lib/node-esm/meta.json +1 -0
  9. package/dist/types/src/blueprints/design/design-blueprint.d.ts +4 -0
  10. package/dist/types/src/blueprints/design/design-blueprint.d.ts.map +1 -0
  11. package/dist/types/src/blueprints/design/design-blueprint.test.d.ts +2 -0
  12. package/dist/types/src/blueprints/design/design-blueprint.test.d.ts.map +1 -0
  13. package/dist/types/src/blueprints/design/index.d.ts +3 -0
  14. package/dist/types/src/blueprints/design/index.d.ts.map +1 -0
  15. package/dist/types/src/blueprints/discord/discord-blueprint.d.ts +18 -0
  16. package/dist/types/src/blueprints/discord/discord-blueprint.d.ts.map +1 -0
  17. package/dist/types/src/blueprints/discord/index.d.ts +3 -0
  18. package/dist/types/src/blueprints/discord/index.d.ts.map +1 -0
  19. package/dist/types/src/blueprints/index.d.ts +7 -0
  20. package/dist/types/src/blueprints/index.d.ts.map +1 -0
  21. package/dist/types/src/blueprints/linear/index.d.ts +3 -0
  22. package/dist/types/src/blueprints/linear/index.d.ts.map +1 -0
  23. package/dist/types/src/blueprints/linear/linear-blueprint.d.ts +18 -0
  24. package/dist/types/src/blueprints/linear/linear-blueprint.d.ts.map +1 -0
  25. package/dist/types/src/blueprints/planning/index.d.ts +3 -0
  26. package/dist/types/src/blueprints/planning/index.d.ts.map +1 -0
  27. package/dist/types/src/blueprints/planning/planning-blueprint.d.ts +4 -0
  28. package/dist/types/src/blueprints/planning/planning-blueprint.d.ts.map +1 -0
  29. package/dist/types/src/blueprints/planning/planning-blueprint.test.d.ts +2 -0
  30. package/dist/types/src/blueprints/planning/planning-blueprint.test.d.ts.map +1 -0
  31. package/dist/types/src/blueprints/research/index.d.ts +3 -0
  32. package/dist/types/src/blueprints/research/index.d.ts.map +1 -0
  33. package/dist/types/src/blueprints/research/research-blueprint.d.ts +4 -0
  34. package/dist/types/src/blueprints/research/research-blueprint.d.ts.map +1 -0
  35. package/dist/types/src/blueprints/research/research-blueprint.test.d.ts +2 -0
  36. package/dist/types/src/blueprints/research/research-blueprint.test.d.ts.map +1 -0
  37. package/dist/types/src/blueprints/testing.d.ts +12 -0
  38. package/dist/types/src/blueprints/testing.d.ts.map +1 -0
  39. package/dist/types/src/blueprints/websearch/index.d.ts +4 -0
  40. package/dist/types/src/blueprints/websearch/index.d.ts.map +1 -0
  41. package/dist/types/src/blueprints/websearch/websearch-blueprint.d.ts +4 -0
  42. package/dist/types/src/blueprints/websearch/websearch-blueprint.d.ts.map +1 -0
  43. package/dist/types/src/blueprints/websearch/websearch-toolkit.d.ts +26 -0
  44. package/dist/types/src/blueprints/websearch/websearch-toolkit.d.ts.map +1 -0
  45. package/dist/types/src/experimental/feed.test.d.ts +2 -0
  46. package/dist/types/src/experimental/feed.test.d.ts.map +1 -0
  47. package/dist/types/src/functions/agent/index.d.ts +5 -0
  48. package/dist/types/src/functions/agent/index.d.ts.map +1 -0
  49. package/dist/types/src/functions/agent/prompt.d.ts +11 -0
  50. package/dist/types/src/functions/agent/prompt.d.ts.map +1 -0
  51. package/dist/types/src/functions/discord/fetch-messages.d.ts +11 -0
  52. package/dist/types/src/functions/discord/fetch-messages.d.ts.map +1 -0
  53. package/dist/types/src/functions/discord/fetch-messages.test.d.ts +2 -0
  54. package/dist/types/src/functions/discord/fetch-messages.test.d.ts.map +1 -0
  55. package/dist/types/src/functions/discord/index.d.ts +12 -0
  56. package/dist/types/src/functions/discord/index.d.ts.map +1 -0
  57. package/dist/types/src/functions/document/index.d.ts +12 -0
  58. package/dist/types/src/functions/document/index.d.ts.map +1 -0
  59. package/dist/types/src/functions/document/read.d.ts +7 -0
  60. package/dist/types/src/functions/document/read.d.ts.map +1 -0
  61. package/dist/types/src/functions/document/update.d.ts +6 -0
  62. package/dist/types/src/functions/document/update.d.ts.map +1 -0
  63. package/dist/types/src/functions/entity-extraction/entity-extraction.d.ts +173 -0
  64. package/dist/types/src/functions/entity-extraction/entity-extraction.d.ts.map +1 -0
  65. package/dist/types/src/functions/entity-extraction/entity-extraction.test.d.ts +2 -0
  66. package/dist/types/src/functions/entity-extraction/entity-extraction.test.d.ts.map +1 -0
  67. package/dist/types/src/functions/entity-extraction/index.d.ts +174 -0
  68. package/dist/types/src/functions/entity-extraction/index.d.ts.map +1 -0
  69. package/dist/types/src/functions/exa/exa.d.ts +5 -0
  70. package/dist/types/src/functions/exa/exa.d.ts.map +1 -0
  71. package/dist/types/src/functions/exa/index.d.ts +3 -0
  72. package/dist/types/src/functions/exa/index.d.ts.map +1 -0
  73. package/dist/types/src/functions/exa/mock.d.ts +5 -0
  74. package/dist/types/src/functions/exa/mock.d.ts.map +1 -0
  75. package/dist/types/src/functions/github/fetch-prs.d.ts +6 -0
  76. package/dist/types/src/functions/github/fetch-prs.d.ts.map +1 -0
  77. package/dist/types/src/functions/index.d.ts +8 -0
  78. package/dist/types/src/functions/index.d.ts.map +1 -0
  79. package/dist/types/src/functions/linear/index.d.ts +9 -0
  80. package/dist/types/src/functions/linear/index.d.ts.map +1 -0
  81. package/dist/types/src/functions/linear/linear.test.d.ts +2 -0
  82. package/dist/types/src/functions/linear/linear.test.d.ts.map +1 -0
  83. package/dist/types/src/functions/linear/sync-issues.d.ts +12 -0
  84. package/dist/types/src/functions/linear/sync-issues.d.ts.map +1 -0
  85. package/dist/types/src/functions/research/create-document.d.ts +7 -0
  86. package/dist/types/src/functions/research/create-document.d.ts.map +1 -0
  87. package/dist/types/src/functions/research/graph.d.ts +64 -0
  88. package/dist/types/src/functions/research/graph.d.ts.map +1 -0
  89. package/dist/types/src/functions/research/graph.test.d.ts +2 -0
  90. package/dist/types/src/functions/research/graph.test.d.ts.map +1 -0
  91. package/dist/types/src/functions/research/index.d.ts +19 -0
  92. package/dist/types/src/functions/research/index.d.ts.map +1 -0
  93. package/dist/types/src/functions/research/research-graph.d.ts +18 -0
  94. package/dist/types/src/functions/research/research-graph.d.ts.map +1 -0
  95. package/dist/types/src/functions/research/research.d.ts +13 -0
  96. package/dist/types/src/functions/research/research.d.ts.map +1 -0
  97. package/dist/types/src/functions/research/research.test.d.ts +2 -0
  98. package/dist/types/src/functions/research/research.test.d.ts.map +1 -0
  99. package/dist/types/src/functions/research/types.d.ts +384 -0
  100. package/dist/types/src/functions/research/types.d.ts.map +1 -0
  101. package/dist/types/src/functions/tasks/index.d.ts +15 -0
  102. package/dist/types/src/functions/tasks/index.d.ts.map +1 -0
  103. package/dist/types/src/functions/tasks/read.d.ts +7 -0
  104. package/dist/types/src/functions/tasks/read.d.ts.map +1 -0
  105. package/dist/types/src/functions/tasks/task-list.d.ts +74 -0
  106. package/dist/types/src/functions/tasks/task-list.d.ts.map +1 -0
  107. package/dist/types/src/functions/tasks/task-list.test.d.ts +2 -0
  108. package/dist/types/src/functions/tasks/task-list.test.d.ts.map +1 -0
  109. package/dist/types/src/functions/tasks/update.d.ts +9 -0
  110. package/dist/types/src/functions/tasks/update.d.ts.map +1 -0
  111. package/dist/types/src/index.d.ts +5 -0
  112. package/dist/types/src/index.d.ts.map +1 -0
  113. package/dist/types/src/plugins.d.ts +19 -0
  114. package/dist/types/src/plugins.d.ts.map +1 -0
  115. package/dist/types/src/sync/index.d.ts +2 -0
  116. package/dist/types/src/sync/index.d.ts.map +1 -0
  117. package/dist/types/src/sync/sync.d.ts +15 -0
  118. package/dist/types/src/sync/sync.d.ts.map +1 -0
  119. package/dist/types/src/testing/data/exa-search-1748337321991.d.ts +38 -0
  120. package/dist/types/src/testing/data/exa-search-1748337321991.d.ts.map +1 -0
  121. package/dist/types/src/testing/data/exa-search-1748337331526.d.ts +37 -0
  122. package/dist/types/src/testing/data/exa-search-1748337331526.d.ts.map +1 -0
  123. package/dist/types/src/testing/data/exa-search-1748337344119.d.ts +58 -0
  124. package/dist/types/src/testing/data/exa-search-1748337344119.d.ts.map +1 -0
  125. package/dist/types/src/testing/data/index.d.ts +3 -0
  126. package/dist/types/src/testing/data/index.d.ts.map +1 -0
  127. package/dist/types/src/testing/index.d.ts +2 -0
  128. package/dist/types/src/testing/index.d.ts.map +1 -0
  129. package/dist/types/src/util/graphql.d.ts +22 -0
  130. package/dist/types/src/util/graphql.d.ts.map +1 -0
  131. package/dist/types/src/util/index.d.ts +2 -0
  132. package/dist/types/src/util/index.d.ts.map +1 -0
  133. package/dist/types/tsconfig.tsbuildinfo +1 -0
  134. package/package.json +67 -0
  135. package/src/blueprints/design/design-blueprint.test.ts +108 -0
  136. package/src/blueprints/design/design-blueprint.ts +33 -0
  137. package/src/blueprints/design/index.ts +7 -0
  138. package/src/blueprints/discord/discord-blueprint.ts +34 -0
  139. package/src/blueprints/discord/index.ts +7 -0
  140. package/src/blueprints/index.ts +10 -0
  141. package/src/blueprints/linear/index.ts +7 -0
  142. package/src/blueprints/linear/linear-blueprint.ts +35 -0
  143. package/src/blueprints/planning/index.ts +7 -0
  144. package/src/blueprints/planning/planning-blueprint.test.ts +129 -0
  145. package/src/blueprints/planning/planning-blueprint.ts +98 -0
  146. package/src/blueprints/research/index.ts +7 -0
  147. package/src/blueprints/research/research-blueprint.test.ts +7 -0
  148. package/src/blueprints/research/research-blueprint.ts +45 -0
  149. package/src/blueprints/testing.ts +34 -0
  150. package/src/blueprints/websearch/index.ts +8 -0
  151. package/src/blueprints/websearch/websearch-blueprint.ts +20 -0
  152. package/src/blueprints/websearch/websearch-toolkit.ts +8 -0
  153. package/src/experimental/feed.test.ts +108 -0
  154. package/src/functions/agent/index.ts +11 -0
  155. package/src/functions/agent/prompt.ts +101 -0
  156. package/src/functions/discord/fetch-messages.test.ts +59 -0
  157. package/src/functions/discord/fetch-messages.ts +251 -0
  158. package/src/functions/discord/index.ts +9 -0
  159. package/src/functions/document/index.ts +11 -0
  160. package/src/functions/document/read.ts +29 -0
  161. package/src/functions/document/update.ts +30 -0
  162. package/src/functions/entity-extraction/entity-extraction.conversations.json +1 -0
  163. package/src/functions/entity-extraction/entity-extraction.test.ts +100 -0
  164. package/src/functions/entity-extraction/entity-extraction.ts +163 -0
  165. package/src/functions/entity-extraction/index.ts +9 -0
  166. package/src/functions/exa/exa.ts +37 -0
  167. package/src/functions/exa/index.ts +6 -0
  168. package/src/functions/exa/mock.ts +71 -0
  169. package/src/functions/github/fetch-prs.ts +30 -0
  170. package/src/functions/index.ts +11 -0
  171. package/src/functions/linear/index.ts +9 -0
  172. package/src/functions/linear/linear.test.ts +86 -0
  173. package/src/functions/linear/sync-issues.ts +189 -0
  174. package/src/functions/research/create-document.ts +69 -0
  175. package/src/functions/research/graph.test.ts +69 -0
  176. package/src/functions/research/graph.ts +388 -0
  177. package/src/functions/research/index.ts +15 -0
  178. package/src/functions/research/instructions-research.tpl +98 -0
  179. package/src/functions/research/research-graph.ts +47 -0
  180. package/src/functions/research/research.conversations.json +10714 -0
  181. package/src/functions/research/research.test.ts +240 -0
  182. package/src/functions/research/research.ts +155 -0
  183. package/src/functions/research/types.ts +24 -0
  184. package/src/functions/tasks/index.ts +11 -0
  185. package/src/functions/tasks/read.ts +34 -0
  186. package/src/functions/tasks/task-list.test.ts +99 -0
  187. package/src/functions/tasks/task-list.ts +165 -0
  188. package/src/functions/tasks/update.ts +52 -0
  189. package/src/index.ts +8 -0
  190. package/src/plugins.tsx +68 -0
  191. package/src/sync/index.ts +5 -0
  192. package/src/sync/sync.ts +87 -0
  193. package/src/testing/data/exa-search-1748337321991.ts +131 -0
  194. package/src/testing/data/exa-search-1748337331526.ts +144 -0
  195. package/src/testing/data/exa-search-1748337344119.ts +133 -0
  196. package/src/testing/data/index.ts +11 -0
  197. package/src/testing/index.ts +5 -0
  198. package/src/typedefs.d.ts +8 -0
  199. package/src/util/graphql.ts +31 -0
  200. package/src/util/index.ts +5 -0
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@dxos/assistant-toolkit",
3
+ "version": "0.8.4-main.ae835ea",
4
+ "description": "Assistant toolkit, definitions, and utilities.",
5
+ "homepage": "https://dxos.org",
6
+ "bugs": "https://github.com/dxos/dxos/issues",
7
+ "license": "MIT",
8
+ "author": "DXOS.org",
9
+ "type": "module",
10
+ "exports": {
11
+ ".": {
12
+ "source": "./src/index.ts",
13
+ "types": "./dist/types/src/index.d.ts",
14
+ "browser": "./dist/lib/browser/index.mjs",
15
+ "node": "./dist/lib/node-esm/index.mjs"
16
+ }
17
+ },
18
+ "types": "dist/types/src/index.d.ts",
19
+ "typesVersions": {
20
+ "*": {}
21
+ },
22
+ "files": [
23
+ "dist",
24
+ "src"
25
+ ],
26
+ "dependencies": {
27
+ "@effect/ai": "0.29.1",
28
+ "@effect/ai-anthropic": "0.19.2",
29
+ "@effect/experimental": "0.56.0",
30
+ "@effect/platform": "^0.92.1",
31
+ "dfx": "^0.126.0",
32
+ "exa-js": "^1.5.12",
33
+ "@dxos/ai": "0.8.4-main.ae835ea",
34
+ "@dxos/app-framework": "0.8.4-main.ae835ea",
35
+ "@dxos/assistant": "0.8.4-main.ae835ea",
36
+ "@dxos/blueprints": "0.8.4-main.ae835ea",
37
+ "@dxos/context": "0.8.4-main.ae835ea",
38
+ "@dxos/conductor": "0.8.4-main.ae835ea",
39
+ "@dxos/echo-db": "0.8.4-main.ae835ea",
40
+ "@dxos/echo": "0.8.4-main.ae835ea",
41
+ "@dxos/echo-protocol": "0.8.4-main.ae835ea",
42
+ "@dxos/edge-client": "0.8.4-main.ae835ea",
43
+ "@dxos/functions": "0.8.4-main.ae835ea",
44
+ "@dxos/errors": "0.8.4-main.ae835ea",
45
+ "@dxos/invariant": "0.8.4-main.ae835ea",
46
+ "@dxos/keys": "0.8.4-main.ae835ea",
47
+ "@dxos/log": "0.8.4-main.ae835ea",
48
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.ae835ea",
49
+ "@dxos/util": "0.8.4-main.ae835ea",
50
+ "@dxos/effect": "0.8.4-main.ae835ea",
51
+ "@dxos/plugin-markdown": "0.8.4-main.ae835ea",
52
+ "@dxos/schema": "0.8.4-main.ae835ea"
53
+ },
54
+ "devDependencies": {
55
+ "effect": "3.18.3",
56
+ "react": "~19.2.0",
57
+ "react-dom": "~19.2.0"
58
+ },
59
+ "peerDependencies": {
60
+ "effect": "^3.13.3",
61
+ "react": "^19.0.0",
62
+ "react-dom": "^19.0.0"
63
+ },
64
+ "publishConfig": {
65
+ "access": "public"
66
+ }
67
+ }
@@ -0,0 +1,108 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { describe, it } from '@effect/vitest';
6
+ import * as Effect from 'effect/Effect';
7
+ import * as Layer from 'effect/Layer';
8
+
9
+ import { AiService, ConsolePrinter } from '@dxos/ai';
10
+ import { AiServiceTestingPreset } from '@dxos/ai/testing';
11
+ import {
12
+ AiConversation,
13
+ type ContextBinding,
14
+ GenerationObserver,
15
+ makeToolExecutionServiceFromFunctions,
16
+ makeToolResolverFromFunctions,
17
+ } from '@dxos/assistant';
18
+ import { Blueprint } from '@dxos/blueprints';
19
+ import { Obj, Ref } from '@dxos/echo';
20
+ import { TestHelpers, acquireReleaseResource } from '@dxos/effect';
21
+ import {
22
+ ComputeEventLogger,
23
+ DatabaseService,
24
+ FunctionInvocationService,
25
+ QueueService,
26
+ TracingService,
27
+ } from '@dxos/functions';
28
+ import { TestDatabaseLayer } from '@dxos/functions/testing';
29
+ import { log } from '@dxos/log';
30
+ import { Markdown } from '@dxos/plugin-markdown/types';
31
+ import { DataType } from '@dxos/schema';
32
+ import { trim } from '@dxos/util';
33
+
34
+ import { Document } from '../../functions';
35
+ import { testToolkit } from '../testing';
36
+
37
+ import blueprint from './design-blueprint';
38
+
39
+ describe('Design Blueprint', { timeout: 120_000 }, () => {
40
+ it.scoped(
41
+ 'design blueprint',
42
+ Effect.fn(
43
+ function* ({ expect }) {
44
+ const observer = GenerationObserver.fromPrinter(new ConsolePrinter());
45
+ const queue = yield* QueueService.createQueue<DataType.Message | ContextBinding>();
46
+ const conversation = yield* acquireReleaseResource(() => new AiConversation(queue));
47
+
48
+ yield* DatabaseService.add(blueprint);
49
+ yield* Effect.promise(() =>
50
+ conversation.context.bind({
51
+ blueprints: [Ref.make(blueprint)],
52
+ }),
53
+ );
54
+
55
+ const artifact = yield* DatabaseService.add(Markdown.makeDocument({ content: 'Hello, world!' }));
56
+ let prevContent = artifact.content;
57
+
58
+ {
59
+ const prompt = trim`
60
+ I want to design a new feature for our product.
61
+
62
+ We need to add a user profile system with the following requirements:
63
+ 1. Users should be able to create and edit their profiles
64
+ 2. Profile should include basic info like name, bio, avatar
65
+ 3. Users can control privacy settings for their profile
66
+ 4. Profile should show user's activity history
67
+ 5. Need to consider data storage and security implications
68
+
69
+ Let's capture the key design decisions in our spec in ${Obj.getDXN(artifact)}
70
+ `;
71
+
72
+ yield* conversation.createRequest({ prompt, observer });
73
+ log.info('spec', { doc: artifact });
74
+ expect(artifact.content).not.toBe(prevContent);
75
+ prevContent = artifact.content;
76
+ }
77
+
78
+ {
79
+ const prompt = trim`
80
+ I want this to be built on top of Durable Objects and SQLite database.
81
+ Adjust the spec to reflect this.
82
+ `;
83
+
84
+ yield* conversation.createRequest({ observer, prompt });
85
+ expect(artifact.content).not.toBe(prevContent);
86
+ prevContent = artifact.content;
87
+ }
88
+ },
89
+ Effect.provide(
90
+ Layer.mergeAll(
91
+ makeToolResolverFromFunctions([Document.read, Document.update], testToolkit),
92
+ makeToolExecutionServiceFromFunctions(testToolkit, testToolkit.toLayer({}) as any),
93
+ AiService.model('@anthropic/claude-3-5-sonnet-20241022'),
94
+ ).pipe(
95
+ Layer.provideMerge(TestDatabaseLayer({ types: [DataType.Text, Markdown.Document, Blueprint.Blueprint] })),
96
+ Layer.provideMerge(AiServiceTestingPreset('direct')),
97
+ Layer.provideMerge(
98
+ FunctionInvocationService.layerTestMocked({ functions: [Document.read, Document.update] }).pipe(
99
+ Layer.provideMerge(ComputeEventLogger.layerFromTracing),
100
+ Layer.provideMerge(TracingService.layerNoop),
101
+ ),
102
+ ),
103
+ ),
104
+ ),
105
+ TestHelpers.taggedTest('llm'),
106
+ ),
107
+ );
108
+ });
@@ -0,0 +1,33 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { ToolId } from '@dxos/ai';
6
+ import { Blueprint } from '@dxos/blueprints';
7
+ import { Obj, Ref } from '@dxos/echo';
8
+ import { DataType } from '@dxos/schema';
9
+ import { trim } from '@dxos/util';
10
+
11
+ import { Document } from '../../functions';
12
+
13
+ const instructions = trim`
14
+ You manage a design spec based on the conversation.
15
+ The design spec is a markdown document that is used to record the tasks.
16
+ The design spec document follows a hierarchical structure, with nested markdown bulleted sections.
17
+ Use the appropriate tools to read and write the design spec document.
18
+ Maintain the document so that it can convey all relevant points from the conversation.
19
+ When replying to the user, be terse with your comments about design doc handling.
20
+ Do not announce when you read or write the design spec document.
21
+ `;
22
+
23
+ const blueprint: Blueprint.Blueprint = Obj.make(Blueprint.Blueprint, {
24
+ key: 'dxos.org/blueprint/design',
25
+ name: 'Design Spec',
26
+ description: 'Preserve the conversation in the design spec.',
27
+ instructions: {
28
+ source: Ref.make(DataType.makeText(instructions)),
29
+ },
30
+ tools: [Document.read, Document.update].map((fn) => ToolId.make(fn.key)),
31
+ });
32
+
33
+ export default blueprint;
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import blueprint from './design-blueprint';
6
+
7
+ export default blueprint;
@@ -0,0 +1,34 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { ToolId } from '@dxos/ai';
6
+ import { Blueprint } from '@dxos/blueprints';
7
+ import { Obj, Ref } from '@dxos/echo';
8
+ import { DataType } from '@dxos/schema';
9
+ import { trim } from '@dxos/util';
10
+
11
+ import { Discord } from '../../functions';
12
+
13
+ /**
14
+ * Agent prompt instructions for managing hierarchical task lists.
15
+ */
16
+ const instructions = trim`
17
+ You are able to fetch messages from Discord servers.
18
+
19
+ Known servers:
20
+
21
+ DXOS serverId: 837138313172353095
22
+ `;
23
+
24
+ export const blueprint = Obj.make(Blueprint.Blueprint, {
25
+ key: 'dxos.org/blueprint/discord',
26
+ name: 'Discord',
27
+ description: 'Discord integration.',
28
+ instructions: {
29
+ source: Ref.make(DataType.makeText(instructions)),
30
+ },
31
+ tools: [ToolId.make(Discord.fetch.key)],
32
+ });
33
+
34
+ export default blueprint;
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import blueprint from './discord-blueprint';
6
+
7
+ export default blueprint;
@@ -0,0 +1,10 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export { default as DesignBlueprint } from './design';
6
+ export { default as DiscordBlueprint } from './discord';
7
+ export { default as LinearBlueprint } from './linear';
8
+ export { default as PlanningBlueprint } from './planning';
9
+ export { default as ResearchBlueprint } from './research';
10
+ export { default as WebSearchBlueprint, WebSearchToolkit } from './websearch';
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import blueprint from './linear-blueprint';
6
+
7
+ export default blueprint;
@@ -0,0 +1,35 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { ToolId } from '@dxos/ai';
6
+ import { Blueprint } from '@dxos/blueprints';
7
+ import { Obj, Ref } from '@dxos/echo';
8
+ import { DataType } from '@dxos/schema';
9
+ import { trim } from '@dxos/util';
10
+
11
+ import { Linear } from '../../functions';
12
+
13
+ /**
14
+ * Agent prompt instructions for managing hierarchical task lists.
15
+ */
16
+ const instructions = trim`
17
+ You are able to sync Linear workspaces.
18
+ Sometimes sync does not complete in one go and you need to call the function again.
19
+
20
+ Known workspaces:
21
+
22
+ DXOS teamId: 1127c63a-6f77-4725-9229-50f6cd47321c
23
+ `;
24
+
25
+ export const blueprint = Obj.make(Blueprint.Blueprint, {
26
+ key: 'dxos.org/blueprint/linear',
27
+ name: 'Linear',
28
+ description: 'Syncs Linear workspaces.',
29
+ instructions: {
30
+ source: Ref.make(DataType.makeText(instructions)),
31
+ },
32
+ tools: [Linear.sync].map((tool) => ToolId.make(tool.key)),
33
+ });
34
+
35
+ export default blueprint;
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import blueprint from './planning-blueprint';
6
+
7
+ export default blueprint;
@@ -0,0 +1,129 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { describe, it } from '@effect/vitest';
6
+ import * as Effect from 'effect/Effect';
7
+ import * as Layer from 'effect/Layer';
8
+
9
+ import { AiService } from '@dxos/ai';
10
+ import { AiServiceTestingPreset } from '@dxos/ai/testing';
11
+ import {
12
+ AiConversation,
13
+ type ContextBinding,
14
+ makeToolExecutionServiceFromFunctions,
15
+ makeToolResolverFromFunctions,
16
+ } from '@dxos/assistant';
17
+ import { Blueprint } from '@dxos/blueprints';
18
+ import { Obj, Ref } from '@dxos/echo';
19
+ import { TestHelpers, acquireReleaseResource } from '@dxos/effect';
20
+ import {
21
+ ComputeEventLogger,
22
+ DatabaseService,
23
+ FunctionImplementationResolver,
24
+ FunctionInvocationService,
25
+ QueueService,
26
+ TracingService,
27
+ } from '@dxos/functions';
28
+ import { TestDatabaseLayer } from '@dxos/functions/testing';
29
+ import { log } from '@dxos/log';
30
+ import { Markdown } from '@dxos/plugin-markdown/types';
31
+ import { DataType } from '@dxos/schema';
32
+ import { trim } from '@dxos/util';
33
+
34
+ import { Tasks } from '../../functions';
35
+ import { type TestStep, runSteps, testToolkit } from '../testing';
36
+
37
+ import blueprint from './planning-blueprint';
38
+
39
+ describe('Planning Blueprint', { timeout: 120_000 }, () => {
40
+ it.scoped(
41
+ 'planning blueprint',
42
+ Effect.fn(
43
+ function* ({ expect }) {
44
+ const queue = yield* QueueService.createQueue<DataType.Message | ContextBinding>();
45
+ const conversation = yield* acquireReleaseResource(() => new AiConversation(queue));
46
+
47
+ yield* DatabaseService.add(blueprint);
48
+ yield* Effect.promise(() =>
49
+ conversation.context.bind({
50
+ blueprints: [Ref.make(blueprint)],
51
+ }),
52
+ );
53
+
54
+ const artifact = yield* DatabaseService.add(Markdown.makeDocument());
55
+ let prevContent = artifact.content;
56
+ const matchList =
57
+ ({ includes = [], excludes = [] }: { includes: RegExp[]; excludes?: RegExp[] }) =>
58
+ async () => {
59
+ const { content } = await artifact.content.load();
60
+ log.info('spec', { doc: artifact.content.target?.content });
61
+ expect(content).not.toBe(prevContent);
62
+ const text = content.toLowerCase();
63
+ for (const include of includes) {
64
+ expect(text.match(include), `does not include: ${include}`).toBeTruthy();
65
+ }
66
+ for (const exclude of excludes) {
67
+ expect(text.match(exclude), `includes: ${exclude}`).toBeFalsy();
68
+ }
69
+ prevContent = artifact.content;
70
+ };
71
+
72
+ const system = 'You are a helpful assistant.';
73
+ const steps: TestStep[] = [
74
+ {
75
+ system,
76
+ prompt: trim`
77
+ I'm building a shelf.
78
+ Maintain a shopping list here: ${Obj.getDXN(artifact)}
79
+ I need a hammer, nails, and a saw.
80
+ `,
81
+ test: matchList({
82
+ includes: [/- \[.+hammer/, /- \[.+nails/, /- \[.+saw/],
83
+ }),
84
+ },
85
+ {
86
+ system,
87
+ prompt: trim`
88
+ I will need a board too.
89
+ `,
90
+ test: matchList({
91
+ includes: [/- \[.+board/],
92
+ }),
93
+ },
94
+ {
95
+ system,
96
+ prompt: trim`
97
+ Actually I'm going to use screws and a screwdriver.
98
+ `,
99
+ test: matchList({
100
+ includes: [/- \[.+screwdriver/, /- \[.+screws/],
101
+ excludes: [/- \[.+hammer/, /- \[.+nails/],
102
+ }),
103
+ },
104
+ ];
105
+
106
+ yield* runSteps(conversation, steps);
107
+ },
108
+ Effect.provide(
109
+ Layer.mergeAll(
110
+ TestDatabaseLayer({ types: [DataType.Text, Markdown.Document, Blueprint.Blueprint] }),
111
+ makeToolResolverFromFunctions([Tasks.read, Tasks.update], testToolkit),
112
+ makeToolExecutionServiceFromFunctions(testToolkit, testToolkit.toLayer({}) as any),
113
+ AiService.model('@anthropic/claude-3-5-sonnet-20241022'),
114
+ ).pipe(
115
+ Layer.provideMerge(
116
+ FunctionInvocationService.layerTestMocked({ functions: [Tasks.read, Tasks.update] }).pipe(
117
+ Layer.provideMerge(ComputeEventLogger.layerFromTracing),
118
+ Layer.provideMerge(TracingService.layerNoop),
119
+ ),
120
+ ),
121
+ Layer.provideMerge(FunctionImplementationResolver.layerTest({ functions: [Tasks.read, Tasks.update] })),
122
+ Layer.provideMerge(TestDatabaseLayer({ types: [DataType.Text, Markdown.Document, Blueprint.Blueprint] })),
123
+ Layer.provideMerge(AiServiceTestingPreset('direct')),
124
+ ),
125
+ ),
126
+ TestHelpers.taggedTest('llm'),
127
+ ),
128
+ );
129
+ });
@@ -0,0 +1,98 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { ToolId } from '@dxos/ai';
6
+ import { Blueprint } from '@dxos/blueprints';
7
+ import { Obj, Ref } from '@dxos/echo';
8
+ import { DataType } from '@dxos/schema';
9
+ import { trim } from '@dxos/util';
10
+
11
+ import { Tasks } from '../../functions';
12
+
13
+ /**
14
+ * Agent prompt instructions for managing hierarchical task lists.
15
+ */
16
+ const instructions = trim`
17
+ You are a task management agent that maintains hierarchical task lists where each line is a task.
18
+
19
+ ## Document Format
20
+ You will receive task lists with line numbers prefixed like:
21
+
22
+ ${'```'}
23
+ 1. - [ ] First main task
24
+ 2. - [ ] Subtask 1: Research phase
25
+ 3. - [x] Literature review
26
+ 4. - [ ] Stakeholder interviews
27
+ 5. - [ ] Subtask 2: Implementation
28
+ 6. - [ ] Setup infrastructure
29
+ 7. - [ ] Write core functionality
30
+ 8. - [ ] Another main task
31
+ ${'```'}
32
+
33
+ ## Task Hierarchy
34
+ - 0 spaces: Top-level tasks
35
+ - 2 spaces: First-level subtasks
36
+ - 4 spaces: Second-level subtasks
37
+ - 6 spaces: Third-level subtasks (and so on)
38
+
39
+ ## Available Operations
40
+ You can modify the task list using these operations:
41
+
42
+ 1. **insertTask(lineNumber, text, completed?, indent?)** - Insert a new task
43
+ 2. **deleteTask(lineNumber)** - Delete a task
44
+ 3. **updateTaskText(lineNumber, text)** - Change task description
45
+ 4. **toggleTaskCompletion(lineNumber, completed?)** - Mark task complete/incomplete
46
+ 5. **setTaskIndent(lineNumber, indent)** - Change task hierarchy level
47
+
48
+ ## Examples
49
+
50
+ ### Example 1: Adding a subtask
51
+ **User:** "Add a subtask 'Code review' under the task on line 1"
52
+ **Response:** \`insertTask(2, "Code review", false, 2)\`
53
+
54
+ ### Example 2: Marking a task complete
55
+ **User:** "Mark the task on line 3 as complete"
56
+ **Response:** \`toggleTaskCompletion(3, true)\`
57
+
58
+ ### Example 3: Updating task text
59
+ **User:** "Change the task on line 5 to 'Backend implementation'"
60
+ **Response:** \`updateTaskText(5, "Backend implementation")\`
61
+
62
+ ### Example 4: Creating a task hierarchy
63
+ **User:** "Add a main task 'Testing phase' with two subtasks"
64
+ **Response:**
65
+ \`\`\`
66
+ insertTask(999, "Testing phase", false, 0)
67
+ insertTask(999, "Unit tests", false, 2)
68
+ insertTask(999, "Integration tests", false, 2)
69
+ \`\`\`
70
+
71
+ ### Example 5: Reorganizing hierarchy
72
+ **User:** "Move the task on line 4 to be a main task (top level)"
73
+ **Response:** \`setTaskIndent(4, 0)\`
74
+
75
+ ### Example 6: Adding nested subtasks
76
+ **User:** "Add a sub-subtask 'Write test cases' under line 6"
77
+ **Response:** \`insertTask(7, "Write test cases", false, 4)\`
78
+
79
+ ## Guidelines
80
+ - Always reference line numbers from the numbered document you receive
81
+ - Use line number 999 to append to the end of the document
82
+ - Maintain logical hierarchy (subtasks should be indented under their parent)
83
+ - Use appropriate indentation levels (0, 2, 4, 6, etc. spaces)
84
+ - When creating subtasks, consider the parent task's completion status
85
+ - Be precise with task descriptions and hierarchy levels
86
+ `;
87
+
88
+ export const blueprint: Blueprint.Blueprint = Obj.make(Blueprint.Blueprint, {
89
+ key: 'dxos.org/blueprint/planning',
90
+ name: 'Planning',
91
+ description: 'Plans and tracks complex tasks with artifact management.',
92
+ instructions: {
93
+ source: Ref.make(DataType.makeText(instructions)),
94
+ },
95
+ tools: [Tasks.read, Tasks.update].map((fn) => ToolId.make(fn.key)),
96
+ });
97
+
98
+ export default blueprint;
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import blueprint from './research-blueprint';
6
+
7
+ export default blueprint;
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { describe } from '@effect/vitest';
6
+
7
+ describe.runIf(process.env.DX_RUN_SLOW_TESTS === '1')('Research Blueprint', { timeout: 120_000 }, () => {});
@@ -0,0 +1,45 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { ToolId } from '@dxos/ai';
6
+ import { Blueprint } from '@dxos/blueprints';
7
+ import { Obj, Ref } from '@dxos/echo';
8
+ import { DataType } from '@dxos/schema';
9
+ import { trim } from '@dxos/util';
10
+
11
+ import { Research } from '../../functions';
12
+
13
+ /**
14
+ * Agent prompt instructions for managing hierarchical task lists.
15
+ */
16
+ const instructions = trim`
17
+ {{! Research }}
18
+
19
+ You are an analyst that does research tasks using tools that scrape the web and create structured data.
20
+ The result of the research is a set of structured entities forming an interconnected graph.
21
+ When you are done, reply with the created objects.
22
+ Do not print the data, instead reply with inline references to the created objects.
23
+ Those will be later substituted with the pills representing the created objects.
24
+ Print the rest of the created objects as block references after the main note.
25
+
26
+ <example>
27
+ Based on my research, Google was founded by @dxn:queue:data:B6INSIBY3CBEF4M5VZRYBCMAHQMPYK5AJ:01K24XMVHSZHS97SG1VTVQDM5Z:01K24XPK464FSCKVQJAB2H662M and @dxn:queue:data:B6INSIBY3CBEF4M5VZRYBCMAHQMPYK5AJ:01K24XMVHSZHS97SG1VTVQDM5Z:01K24XPK46K31DDW62PBW9H2ZQ
28
+
29
+ <object><dxn>dxn:queue:data:B6INSIBY3CBEF4M5VZRYBCMAHQMPYK5AJ:01K24XMVHSZHS97SG1VTVQDM5Z:01K24XPK464FSCKVQJAB2H662M</dxn></object>
30
+ <object><dxn>dxn:queue:data:B6INSIBY3CBEF4M5VZRYBCMAHQMPYK5AJ:01K24XMVHSZHS97SG1VTVQDM5Z:01K24XPK46K31DDW62PBW9H2ZQ</dxn></object>
31
+ <object><dxn>dxn:queue:data:B6INSIBY3CBEF4M5VZRYBCMAHQMPYK5AJ:01K24XMVHSZHS97SG1VTVQDM5Z:01K24XPK46K31DDW62PBW92333</dxn></object>
32
+ </example>
33
+ `;
34
+
35
+ export const blueprint: Blueprint.Blueprint = Obj.make(Blueprint.Blueprint, {
36
+ key: 'dxos.org/blueprint/research',
37
+ name: 'Research',
38
+ description: 'Researches the web and creates structured data.',
39
+ instructions: {
40
+ source: Ref.make(DataType.makeText(instructions)),
41
+ },
42
+ tools: [Research.create, Research.research].map((fn) => ToolId.make(fn.key)),
43
+ });
44
+
45
+ export default blueprint;
@@ -0,0 +1,34 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Toolkit from '@effect/ai/Toolkit';
6
+ import * as Effect from 'effect/Effect';
7
+
8
+ import { ConsolePrinter } from '@dxos/ai';
9
+ import { type AiConversation, type AiConversationRunParams, GenerationObserver } from '@dxos/assistant';
10
+ import { log } from '@dxos/log';
11
+
12
+ export type TestStep = Pick<AiConversationRunParams, 'prompt' | 'system'> & {
13
+ test?: () => Promise<void>;
14
+ };
15
+
16
+ /**
17
+ * Runs the prompt steps, calling the test function after each step.
18
+ */
19
+ export const runSteps = Effect.fn(function* (conversation: AiConversation, steps: TestStep[]) {
20
+ for (const { test, ...props } of steps) {
21
+ yield* conversation.createRequest({
22
+ ...props,
23
+ observer: GenerationObserver.fromPrinter(new ConsolePrinter({ mode: 'json' })),
24
+ });
25
+ const messages = yield* Effect.promise(() => conversation.getHistory());
26
+ log.info('conversation', { messages });
27
+ if (test) {
28
+ yield* Effect.promise(() => test());
29
+ }
30
+ }
31
+ });
32
+
33
+ // TODO(wittjosiah): Don't cast.
34
+ export const testToolkit = Toolkit.empty as Toolkit.Toolkit<any>;
@@ -0,0 +1,8 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import blueprint from './websearch-blueprint';
6
+
7
+ export { WebSearchToolkit } from './websearch-toolkit';
8
+ export default blueprint;