@dxos/assistant 0.8.1 → 0.8.2-main.10c050d
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.
- package/dist/lib/browser/index.mjs +1830 -228
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +1825 -229
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +1831 -228
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/{src/bin → bin}/chat.d.ts.map +1 -1
- package/dist/types/src/blueprint/blueprint.d.ts +79 -0
- package/dist/types/src/blueprint/blueprint.d.ts.map +1 -0
- package/dist/types/src/blueprint/blueprint.test.d.ts +2 -0
- package/dist/types/src/blueprint/blueprint.test.d.ts.map +1 -0
- package/dist/types/src/blueprint/index.d.ts +4 -0
- package/dist/types/src/blueprint/index.d.ts.map +1 -0
- package/dist/types/src/blueprint/logger.d.ts +3 -0
- package/dist/types/src/blueprint/logger.d.ts.map +1 -0
- package/dist/types/src/blueprint/machine.d.ts +113 -0
- package/dist/types/src/blueprint/machine.d.ts.map +1 -0
- package/dist/types/src/blueprint/test-data.d.ts +3 -0
- package/dist/types/src/blueprint/test-data.d.ts.map +1 -0
- package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.d.ts +4 -0
- package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.d.ts.map +1 -0
- package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.test.d.ts +2 -0
- package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.test.d.ts.map +1 -0
- package/dist/types/src/extraction/extraction-llm-function/index.d.ts +2 -0
- package/dist/types/src/extraction/extraction-llm-function/index.d.ts.map +1 -0
- package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts +210 -0
- package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts.map +1 -0
- package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.test.d.ts +2 -0
- package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.test.d.ts.map +1 -0
- package/dist/types/src/extraction/extraction-ner-function/index.d.ts +3 -0
- package/dist/types/src/extraction/extraction-ner-function/index.d.ts.map +1 -0
- package/dist/types/src/extraction/extraction-ner-function/named-entity-recognition.d.ts +14 -0
- package/dist/types/src/extraction/extraction-ner-function/named-entity-recognition.d.ts.map +1 -0
- package/dist/types/src/extraction/extraction-ner-function/named-entity-recognition.test.d.ts +2 -0
- package/dist/types/src/extraction/extraction-ner-function/named-entity-recognition.test.d.ts.map +1 -0
- package/dist/types/src/extraction/extraction.d.ts +242 -0
- package/dist/types/src/extraction/extraction.d.ts.map +1 -0
- package/dist/types/src/extraction/index.d.ts +5 -0
- package/dist/types/src/extraction/index.d.ts.map +1 -0
- package/dist/types/src/extraction/quotes.d.ts +15 -0
- package/dist/types/src/extraction/quotes.d.ts.map +1 -0
- package/dist/types/src/extraction/quotes.test.d.ts +2 -0
- package/dist/types/src/extraction/quotes.test.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +4 -3
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/research/exa.d.ts +7 -0
- package/dist/types/src/research/exa.d.ts.map +1 -0
- package/dist/types/src/research/graph.d.ts +39 -0
- package/dist/types/src/research/graph.d.ts.map +1 -0
- package/dist/types/src/research/graph.test.d.ts +2 -0
- package/dist/types/src/research/graph.test.d.ts.map +1 -0
- package/dist/types/src/research/index.d.ts +4 -0
- package/dist/types/src/research/index.d.ts.map +1 -0
- package/dist/types/src/research/research.d.ts +10 -0
- package/dist/types/src/research/research.d.ts.map +1 -0
- package/dist/types/src/research/research.test.d.ts +2 -0
- package/dist/types/src/research/research.test.d.ts.map +1 -0
- package/dist/types/src/session/index.d.ts +1 -0
- package/dist/types/src/session/index.d.ts.map +1 -1
- package/dist/types/src/session/session.d.ts +80 -35
- package/dist/types/src/session/session.d.ts.map +1 -1
- package/dist/types/src/session/version-pin.d.ts +21 -0
- package/dist/types/src/session/version-pin.d.ts.map +1 -0
- package/dist/types/src/session/version-pin.test.d.ts +2 -0
- package/dist/types/src/session/version-pin.test.d.ts.map +1 -0
- package/dist/types/src/summarization/summarization.test.d.ts +2 -0
- package/dist/types/src/summarization/summarization.test.d.ts.map +1 -0
- package/dist/types/src/testing/exa-search-1748337321991.d.ts +38 -0
- package/dist/types/src/testing/exa-search-1748337321991.d.ts.map +1 -0
- package/dist/types/src/testing/exa-search-1748337331526.d.ts +37 -0
- package/dist/types/src/testing/exa-search-1748337331526.d.ts.map +1 -0
- package/dist/types/src/testing/exa-search-1748337344119.d.ts +58 -0
- package/dist/types/src/testing/exa-search-1748337344119.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +2 -6
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +3 -0
- package/dist/types/src/types.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +25 -35
- package/src/blueprint/blueprint.test.ts +142 -0
- package/src/blueprint/blueprint.ts +95 -0
- package/src/blueprint/index.ts +7 -0
- package/src/blueprint/logger.ts +66 -0
- package/src/blueprint/machine.ts +208 -0
- package/src/blueprint/test-data.ts +55 -0
- package/src/extraction/extraction-llm-function/extraction-llm-function.test.ts +95 -0
- package/src/extraction/extraction-llm-function/extraction-llm-function.ts +64 -0
- package/src/extraction/extraction-llm-function/index.ts +5 -0
- package/src/extraction/extraction-llm-function/instructions.tpl +28 -0
- package/src/extraction/extraction-ner-function/extraction-ner-function.test.ts +115 -0
- package/src/extraction/extraction-ner-function/extraction-ner-function.ts +54 -0
- package/src/extraction/extraction-ner-function/index.ts +6 -0
- package/src/extraction/extraction-ner-function/named-entity-recognition.test.ts +94 -0
- package/src/extraction/extraction-ner-function/named-entity-recognition.ts +97 -0
- package/src/extraction/extraction.ts +75 -0
- package/src/extraction/index.ts +8 -0
- package/src/extraction/quotes.test.ts +27 -0
- package/src/extraction/quotes.ts +57 -0
- package/src/index.ts +4 -3
- package/src/research/exa.ts +100 -0
- package/src/research/graph.test.ts +15 -0
- package/src/research/graph.ts +291 -0
- package/src/research/index.ts +7 -0
- package/src/research/instructions-research.tpl +97 -0
- package/src/research/research.test.ts +189 -0
- package/src/research/research.ts +89 -0
- package/src/session/index.ts +1 -0
- package/src/session/session.test.ts +39 -67
- package/src/session/session.ts +328 -155
- package/src/session/version-pin.test.ts +26 -0
- package/src/session/version-pin.ts +48 -0
- package/src/summarization/summarization.test.ts +216 -0
- package/src/testing/exa-search-1748337321991.ts +131 -0
- package/src/testing/exa-search-1748337331526.ts +144 -0
- package/src/testing/exa-search-1748337344119.ts +133 -0
- package/src/testing/index.ts +8 -7
- package/src/typedefs.d.ts +8 -0
- package/src/types.ts +8 -0
- package/src/typings.d.ts +8 -0
- package/dist/lib/browser/chunk-PND5VR6D.mjs +0 -2315
- package/dist/lib/browser/chunk-PND5VR6D.mjs.map +0 -7
- package/dist/lib/browser/testing/index.mjs +0 -621
- package/dist/lib/browser/testing/index.mjs.map +0 -7
- package/dist/lib/node/chunk-IBOBRBDF.cjs +0 -2326
- package/dist/lib/node/chunk-IBOBRBDF.cjs.map +0 -7
- package/dist/lib/node/testing/index.cjs +0 -637
- package/dist/lib/node/testing/index.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-DCQJOLSR.mjs +0 -2317
- package/dist/lib/node-esm/chunk-DCQJOLSR.mjs.map +0 -7
- package/dist/lib/node-esm/testing/index.mjs +0 -622
- package/dist/lib/node-esm/testing/index.mjs.map +0 -7
- package/dist/types/src/ai-service/client.test.d.ts +0 -2
- package/dist/types/src/ai-service/client.test.d.ts.map +0 -1
- package/dist/types/src/ai-service/defs.d.ts +0 -9
- package/dist/types/src/ai-service/defs.d.ts.map +0 -1
- package/dist/types/src/ai-service/edge-client.d.ts +0 -19
- package/dist/types/src/ai-service/edge-client.d.ts.map +0 -1
- package/dist/types/src/ai-service/index.d.ts +0 -10
- package/dist/types/src/ai-service/index.d.ts.map +0 -1
- package/dist/types/src/ai-service/message-collector.d.ts +0 -88
- package/dist/types/src/ai-service/message-collector.d.ts.map +0 -1
- package/dist/types/src/ai-service/ollama-client.d.ts +0 -39
- package/dist/types/src/ai-service/ollama-client.d.ts.map +0 -1
- package/dist/types/src/ai-service/parser.d.ts +0 -138
- package/dist/types/src/ai-service/parser.d.ts.map +0 -1
- package/dist/types/src/ai-service/service.d.ts +0 -9
- package/dist/types/src/ai-service/service.d.ts.map +0 -1
- package/dist/types/src/ai-service/stream.d.ts +0 -40
- package/dist/types/src/ai-service/stream.d.ts.map +0 -1
- package/dist/types/src/ai-service/stream.test.d.ts +0 -2
- package/dist/types/src/ai-service/stream.test.d.ts.map +0 -1
- package/dist/types/src/ai-service/testing/index.d.ts +0 -3
- package/dist/types/src/ai-service/testing/index.d.ts.map +0 -1
- package/dist/types/src/ai-service/testing/mock.d.ts +0 -7
- package/dist/types/src/ai-service/testing/mock.d.ts.map +0 -1
- package/dist/types/src/ai-service/testing/test-stream.d.ts +0 -7
- package/dist/types/src/ai-service/testing/test-stream.d.ts.map +0 -1
- package/dist/types/src/ai-service/transform.d.ts +0 -27
- package/dist/types/src/ai-service/transform.d.ts.map +0 -1
- package/dist/types/src/ai-service/types.d.ts +0 -167
- package/dist/types/src/ai-service/types.d.ts.map +0 -1
- package/dist/types/src/ai-service/util/index.d.ts +0 -2
- package/dist/types/src/ai-service/util/index.d.ts.map +0 -1
- package/dist/types/src/ai-service/util/sse.d.ts +0 -39
- package/dist/types/src/ai-service/util/sse.d.ts.map +0 -1
- package/dist/types/src/conversation/conversation.d.ts +0 -80
- package/dist/types/src/conversation/conversation.d.ts.map +0 -1
- package/dist/types/src/conversation/conversation.test.d.ts +0 -2
- package/dist/types/src/conversation/conversation.test.d.ts.map +0 -1
- package/dist/types/src/conversation/index.d.ts +0 -2
- package/dist/types/src/conversation/index.d.ts.map +0 -1
- package/dist/types/src/conversation/types.d.ts +0 -79
- package/dist/types/src/conversation/types.d.ts.map +0 -1
- package/dist/types/src/cypher/ast.d.ts +0 -56
- package/dist/types/src/cypher/ast.d.ts.map +0 -1
- package/dist/types/src/cypher/combinators.d.ts +0 -14
- package/dist/types/src/cypher/combinators.d.ts.map +0 -1
- package/dist/types/src/cypher/combinators.test.d.ts +0 -2
- package/dist/types/src/cypher/combinators.test.d.ts.map +0 -1
- package/dist/types/src/cypher/echo-data-source.d.ts +0 -16
- package/dist/types/src/cypher/echo-data-source.d.ts.map +0 -1
- package/dist/types/src/cypher/execution-plan.d.ts +0 -49
- package/dist/types/src/cypher/execution-plan.d.ts.map +0 -1
- package/dist/types/src/cypher/execution-plan.test.d.ts +0 -2
- package/dist/types/src/cypher/execution-plan.test.d.ts.map +0 -1
- package/dist/types/src/cypher/index.d.ts +0 -5
- package/dist/types/src/cypher/index.d.ts.map +0 -1
- package/dist/types/src/cypher/parjs.d.ts +0 -4
- package/dist/types/src/cypher/parjs.d.ts.map +0 -1
- package/dist/types/src/cypher/parser.d.ts +0 -6
- package/dist/types/src/cypher/parser.d.ts.map +0 -1
- package/dist/types/src/cypher/query-executor.d.ts +0 -26
- package/dist/types/src/cypher/query-executor.d.ts.map +0 -1
- package/dist/types/src/cypher/query-executor.test.d.ts +0 -2
- package/dist/types/src/cypher/query-executor.test.d.ts.map +0 -1
- package/dist/types/src/cypher/schema.d.ts +0 -12
- package/dist/types/src/cypher/schema.d.ts.map +0 -1
- package/dist/types/src/cypher/schema.test.d.ts +0 -2
- package/dist/types/src/cypher/schema.test.d.ts.map +0 -1
- package/dist/types/src/testing/artifacts.test.d.ts +0 -1
- package/dist/types/src/testing/artifacts.test.d.ts.map +0 -1
- package/dist/types/src/testing/data.d.ts +0 -2
- package/dist/types/src/testing/data.d.ts.map +0 -1
- package/dist/types/src/testing/defs.d.ts +0 -5
- package/dist/types/src/testing/defs.d.ts.map +0 -1
- package/dist/types/src/testing/logger.d.ts +0 -12
- package/dist/types/src/testing/logger.d.ts.map +0 -1
- package/dist/types/src/testing/object-extraction.test.d.ts +0 -1
- package/dist/types/src/testing/object-extraction.test.d.ts.map +0 -1
- package/dist/types/src/testing/ollama.d.ts +0 -6
- package/dist/types/src/testing/ollama.d.ts.map +0 -1
- package/dist/types/src/testing/query-promts.d.ts +0 -5
- package/dist/types/src/testing/query-promts.d.ts.map +0 -1
- package/dist/types/src/testing/query.test.d.ts +0 -2
- package/dist/types/src/testing/query.test.d.ts.map +0 -1
- package/dist/types/src/testing/test-data.d.ts +0 -29
- package/dist/types/src/testing/test-data.d.ts.map +0 -1
- package/dist/types/src/testing/test-schema.d.ts +0 -50
- package/dist/types/src/testing/test-schema.d.ts.map +0 -1
- package/dist/types/src/util/index.d.ts +0 -2
- package/dist/types/src/util/index.d.ts.map +0 -1
- package/dist/types/src/util/trim.d.ts +0 -5
- package/dist/types/src/util/trim.d.ts.map +0 -1
- package/src/ai-service/client.test.ts +0 -265
- package/src/ai-service/defs.ts +0 -39
- package/src/ai-service/edge-client.ts +0 -67
- package/src/ai-service/index.ts +0 -13
- package/src/ai-service/message-collector.ts +0 -84
- package/src/ai-service/ollama-client.ts +0 -499
- package/src/ai-service/parser.ts +0 -358
- package/src/ai-service/service.ts +0 -15
- package/src/ai-service/stream.test.ts +0 -125
- package/src/ai-service/stream.ts +0 -118
- package/src/ai-service/testing/index.ts +0 -6
- package/src/ai-service/testing/mock.ts +0 -22
- package/src/ai-service/testing/test-stream.ts +0 -93
- package/src/ai-service/transform.ts +0 -121
- package/src/ai-service/types.ts +0 -103
- package/src/ai-service/util/index.ts +0 -5
- package/src/ai-service/util/sse.ts +0 -341
- package/src/bin/chat.ts +0 -79
- package/src/conversation/conversation.test.ts +0 -73
- package/src/conversation/conversation.ts +0 -257
- package/src/conversation/index.ts +0 -5
- package/src/conversation/types.ts +0 -129
- package/src/cypher/ast.ts +0 -75
- package/src/cypher/combinators.test.ts +0 -137
- package/src/cypher/combinators.ts +0 -148
- package/src/cypher/echo-data-source.ts +0 -105
- package/src/cypher/execution-plan.test.ts +0 -44
- package/src/cypher/execution-plan.ts +0 -208
- package/src/cypher/index.ts +0 -8
- package/src/cypher/parjs-shims.d.ts +0 -10
- package/src/cypher/parjs.ts +0 -10
- package/src/cypher/parser.ts +0 -19
- package/src/cypher/query-executor.test.ts +0 -47
- package/src/cypher/query-executor.ts +0 -145
- package/src/cypher/schema.test.ts +0 -17
- package/src/cypher/schema.ts +0 -86
- package/src/testing/artifacts.test.ts +0 -182
- package/src/testing/data.ts +0 -13
- package/src/testing/defs.ts +0 -9
- package/src/testing/logger.ts +0 -129
- package/src/testing/object-extraction.test.ts +0 -71
- package/src/testing/ollama.ts +0 -15
- package/src/testing/query-promts.ts +0 -75
- package/src/testing/query.test.ts +0 -91
- package/src/testing/test-data.ts +0 -372
- package/src/testing/test-schema.ts +0 -80
- package/src/util/index.ts +0 -5
- package/src/util/trim.ts +0 -15
- package/vendor/parjs-browser.mjs +0 -4
- package/vendor/parjs-default.mjs +0 -8
- /package/dist/types/{src/bin → bin}/chat.d.ts +0 -0
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2024 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { test } from 'vitest';
|
|
6
|
-
|
|
7
|
-
import { log } from '@dxos/log';
|
|
8
|
-
|
|
9
|
-
import { executeQuery } from './query-executor';
|
|
10
|
-
import { createTestData } from '../testing';
|
|
11
|
-
|
|
12
|
-
test.skip('run', async ({ expect }) => {
|
|
13
|
-
const dataSource = createTestData();
|
|
14
|
-
// for (const node of dataSource.nodes) {
|
|
15
|
-
// log('node', { id: node.id, label: node.label, name: node.properties.name });
|
|
16
|
-
// }
|
|
17
|
-
// for (const relationship of dataSource.relationships) {
|
|
18
|
-
// log('relationship', {
|
|
19
|
-
// source: relationship.source.id,
|
|
20
|
-
// target: relationship.target.id,
|
|
21
|
-
// label: relationship.label,
|
|
22
|
-
// });
|
|
23
|
-
// }
|
|
24
|
-
|
|
25
|
-
const result = await executeQuery(
|
|
26
|
-
dataSource,
|
|
27
|
-
`
|
|
28
|
-
MATCH (org:Org {name: 'DXOS'})-[:ORG_EMPLOYEES]->(c:Contact)<-[:TASK_ASSIGNEE]-(t:Task)-[:TASK_PROJECT]->(p:Project {name: 'Composer'})
|
|
29
|
-
RETURN c.name, t.name
|
|
30
|
-
`,
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
expect(result).toEqual([
|
|
34
|
-
{ c_name: 'Rich', t_name: 'Create form builder' },
|
|
35
|
-
{
|
|
36
|
-
c_name: 'Josiah',
|
|
37
|
-
t_name: 'Optimize startup performance',
|
|
38
|
-
},
|
|
39
|
-
{ c_name: 'Rich', t_name: 'Implement dark mode' },
|
|
40
|
-
{
|
|
41
|
-
c_name: 'Josiah',
|
|
42
|
-
t_name: 'Add support for custom themes',
|
|
43
|
-
},
|
|
44
|
-
]);
|
|
45
|
-
|
|
46
|
-
log('result', { result });
|
|
47
|
-
});
|
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2024 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import type { JsonPath } from '@dxos/echo-schema';
|
|
6
|
-
import { log } from '@dxos/log';
|
|
7
|
-
import { mapValues } from '@dxos/util';
|
|
8
|
-
|
|
9
|
-
import { createExecutionPlan, type ExecutionPlan, type VariableName } from './execution-plan';
|
|
10
|
-
import { parseCypherQuery } from './parser';
|
|
11
|
-
|
|
12
|
-
export interface DataSource {
|
|
13
|
-
getNodes: (params: { label?: string }) => Promise<Node[]>;
|
|
14
|
-
getRelationships: (params: { label?: string }) => Promise<Relationship[]>;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export type Node = {
|
|
18
|
-
id: string;
|
|
19
|
-
kind: 'node';
|
|
20
|
-
label: string;
|
|
21
|
-
properties: Record<string, unknown>;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export type Relationship = {
|
|
25
|
-
id: string;
|
|
26
|
-
kind: 'relationship';
|
|
27
|
-
label: string;
|
|
28
|
-
properties: Record<string, unknown>;
|
|
29
|
-
source: Node;
|
|
30
|
-
target: Node;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
export const executeQueryPlan = async (
|
|
34
|
-
dataSource: DataSource,
|
|
35
|
-
plan: ExecutionPlan,
|
|
36
|
-
): Promise<Record<string, unknown>[]> => {
|
|
37
|
-
let buffer: Record<VariableName, Node | Relationship>[] = [];
|
|
38
|
-
const results: Record<string, unknown>[] = [];
|
|
39
|
-
|
|
40
|
-
for (const step of plan.steps) {
|
|
41
|
-
log('begin step', { step });
|
|
42
|
-
|
|
43
|
-
switch (step.type) {
|
|
44
|
-
case 'NodeScan': {
|
|
45
|
-
const nodes = await dataSource.getNodes({ label: step.label });
|
|
46
|
-
buffer.push(...nodes.map((node) => ({ [step.into]: node })));
|
|
47
|
-
break;
|
|
48
|
-
}
|
|
49
|
-
case 'FilterByLabel': {
|
|
50
|
-
buffer = buffer.filter((item) => {
|
|
51
|
-
const node = item[step.variable];
|
|
52
|
-
return node && node.kind === 'node' && node.label === step.label;
|
|
53
|
-
});
|
|
54
|
-
break;
|
|
55
|
-
}
|
|
56
|
-
case 'FilterByProperty': {
|
|
57
|
-
buffer = buffer.filter((item) => {
|
|
58
|
-
const node = item[step.variable];
|
|
59
|
-
return node && node.kind === 'node' && node.properties[step.property] === step.value;
|
|
60
|
-
});
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
case 'RelationshipScan': {
|
|
64
|
-
const relationships = await dataSource.getRelationships({ label: step.label });
|
|
65
|
-
for (const tuple of [...buffer]) {
|
|
66
|
-
if (tuple[step.anchor].kind !== 'node') {
|
|
67
|
-
continue;
|
|
68
|
-
}
|
|
69
|
-
const filteredRelationships = relationships.filter((relationship) => {
|
|
70
|
-
switch (step.direction) {
|
|
71
|
-
case 'in':
|
|
72
|
-
return relationship.target.id === tuple[step.anchor].id;
|
|
73
|
-
case 'out':
|
|
74
|
-
return relationship.source.id === tuple[step.anchor].id;
|
|
75
|
-
case 'both':
|
|
76
|
-
return (
|
|
77
|
-
relationship.source.id === tuple[step.anchor].id || relationship.target.id === tuple[step.anchor].id
|
|
78
|
-
);
|
|
79
|
-
default:
|
|
80
|
-
throw new Error(`Unknown direction: ${step.direction}`);
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
for (let i = 0; i < filteredRelationships.length; i++) {
|
|
84
|
-
const relationship = filteredRelationships[i];
|
|
85
|
-
const newTuple = i === 0 ? tuple : { ...tuple };
|
|
86
|
-
if (newTuple !== tuple) {
|
|
87
|
-
buffer.push(newTuple);
|
|
88
|
-
}
|
|
89
|
-
newTuple[step.relationshipInto] = relationship;
|
|
90
|
-
switch (step.direction) {
|
|
91
|
-
case 'in':
|
|
92
|
-
newTuple[step.nodeInto] = relationship.source;
|
|
93
|
-
break;
|
|
94
|
-
case 'out':
|
|
95
|
-
newTuple[step.nodeInto] = relationship.target;
|
|
96
|
-
break;
|
|
97
|
-
case 'both':
|
|
98
|
-
newTuple[step.nodeInto] =
|
|
99
|
-
relationship.source.id === newTuple[step.anchor].id ? relationship.target : relationship.source;
|
|
100
|
-
break;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
break;
|
|
105
|
-
}
|
|
106
|
-
case 'ProduceResults': {
|
|
107
|
-
for (const tuple of buffer) {
|
|
108
|
-
const result: Record<string, unknown> = {};
|
|
109
|
-
for (const field of step.fields) {
|
|
110
|
-
result[field.name] = jsonPathGet(tuple[field.variable].properties, field.path);
|
|
111
|
-
}
|
|
112
|
-
results.push(result);
|
|
113
|
-
}
|
|
114
|
-
break;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
log('finish step', { buffer: buffer.map((tuple) => mapValues(tuple, (x) => x.id)), results });
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return results;
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
export const executeQuery = (dataSource: DataSource, query: string): Promise<Record<string, unknown>[]> => {
|
|
125
|
-
const plan = createExecutionPlan(parseCypherQuery(query));
|
|
126
|
-
return executeQueryPlan(dataSource, plan);
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
// TODO(dmaretskyi): Extract.
|
|
130
|
-
const jsonPathGet = (obj: Record<string, unknown>, path: JsonPath): unknown => {
|
|
131
|
-
if (path === '' || path === '$') {
|
|
132
|
-
return obj;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const parts = path.split('.');
|
|
136
|
-
if (parts[0] === '$') {
|
|
137
|
-
parts.shift();
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
let result: any = obj;
|
|
141
|
-
for (const part of parts) {
|
|
142
|
-
result = result?.[part];
|
|
143
|
-
}
|
|
144
|
-
return result;
|
|
145
|
-
};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2024 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { test } from 'vitest';
|
|
6
|
-
|
|
7
|
-
import { toJsonSchema } from '@dxos/echo-schema';
|
|
8
|
-
|
|
9
|
-
import { formatJsonSchemaForLLM } from './schema';
|
|
10
|
-
import { Contact, Org, Project, Task } from '../testing';
|
|
11
|
-
|
|
12
|
-
test('Org-Project-Task-Contact schema', async ({ expect }) => {
|
|
13
|
-
const jsonSchema = [Org, Project, Task, Contact].map((schema) => toJsonSchema(schema));
|
|
14
|
-
const result = formatJsonSchemaForLLM(jsonSchema);
|
|
15
|
-
// log('result', { result });
|
|
16
|
-
expect(result).toHaveLength(8);
|
|
17
|
-
});
|
package/src/cypher/schema.ts
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2024 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { raise } from '@dxos/debug';
|
|
6
|
-
import { JSON_SCHEMA_ECHO_REF_ID, type JsonSchemaType } from '@dxos/echo-schema';
|
|
7
|
-
|
|
8
|
-
import { trim } from '../util';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Formats ECHO schema to be consumed by LLM.
|
|
12
|
-
* Schema is formatted in cypher format.
|
|
13
|
-
* Objects are represented as nodes.
|
|
14
|
-
* References are represented as relationships.
|
|
15
|
-
*/
|
|
16
|
-
export const formatJsonSchemaForLLM = (schemaTypes: JsonSchemaType[]): string[] => {
|
|
17
|
-
return schemaTypes.flatMap((schema) => [
|
|
18
|
-
formatNodeSchema(schema),
|
|
19
|
-
...formatInferredRelationships(schema, schemaTypes),
|
|
20
|
-
]);
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const formatNodeSchema = (schema: JsonSchemaType) => {
|
|
24
|
-
const label = formatNodeLabel(schema.typename ?? raise(new Error('Schema must have $id')));
|
|
25
|
-
const properties = Object.entries(schema.properties!).filter(([key, prop]) => key !== 'id' && !isReference(prop));
|
|
26
|
-
|
|
27
|
-
return trim`
|
|
28
|
-
<node>
|
|
29
|
-
(:${label})
|
|
30
|
-
|
|
31
|
-
<description>${schema.description}</description>
|
|
32
|
-
|
|
33
|
-
<properties>
|
|
34
|
-
${properties.map(([key, value]) => {
|
|
35
|
-
return trim`
|
|
36
|
-
<${key}>
|
|
37
|
-
<type>${value.type}</type>
|
|
38
|
-
<description>${value.description}</description>
|
|
39
|
-
</${key}>
|
|
40
|
-
`;
|
|
41
|
-
})}
|
|
42
|
-
</properties>
|
|
43
|
-
</node>
|
|
44
|
-
`;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
const formatInferredRelationships = (schema: JsonSchemaType, allSchema: JsonSchemaType[]): string[] => {
|
|
48
|
-
const nodeLabel = formatNodeLabel(schema.typename ?? raise(new Error('Schema must have $id')));
|
|
49
|
-
const relationships = Object.entries(schema.properties!).filter(([key, prop]) => isReference(prop));
|
|
50
|
-
|
|
51
|
-
return relationships.map(([key, value]) => {
|
|
52
|
-
const relationshipLabel = formatInferredRelationshipLabel(
|
|
53
|
-
schema.typename ?? raise(new Error('Schema must have $id')),
|
|
54
|
-
key,
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
// TODO(dmaretskyi): Registered schema don't get reference types updated.
|
|
58
|
-
const targetSchema = allSchema.find((schema) => `dxn:type/${schema.typename}` === value.reference?.schema.$ref);
|
|
59
|
-
const targetLabel = targetSchema ? formatNodeLabel(targetSchema?.typename ?? '') : '';
|
|
60
|
-
|
|
61
|
-
return trim`
|
|
62
|
-
<relationship>
|
|
63
|
-
(:${nodeLabel})-[:${relationshipLabel}]->(:${targetLabel})
|
|
64
|
-
|
|
65
|
-
<description>${value.description}</description>
|
|
66
|
-
</relationship>
|
|
67
|
-
`;
|
|
68
|
-
});
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
export const formatNodeLabel = (typename: string) => {
|
|
72
|
-
return typename.replace(/^example\.com\/type\//g, '');
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
export const formatInferredRelationshipLabel = (typename: string, property: string) => {
|
|
76
|
-
const nodeLabel = formatNodeLabel(typename);
|
|
77
|
-
return `${nodeLabel}_${property}`.toUpperCase();
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
export const isReference = (schema: JsonSchemaType) =>
|
|
81
|
-
schema.$id === JSON_SCHEMA_ECHO_REF_ID ||
|
|
82
|
-
(schema.type === 'array' &&
|
|
83
|
-
!Array.isArray(schema.items) &&
|
|
84
|
-
typeof schema.items === 'object' &&
|
|
85
|
-
'$id' in schema.items &&
|
|
86
|
-
schema.items.$id === JSON_SCHEMA_ECHO_REF_ID);
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
/*
|
|
6
|
-
import { Schema as S } from '@effect/schema';
|
|
7
|
-
import { describe, test } from 'vitest';
|
|
8
|
-
|
|
9
|
-
import { ObjectId, toJsonSchema } from '@dxos/echo-schema';
|
|
10
|
-
import { invariant } from '@dxos/invariant';
|
|
11
|
-
import { SpaceId } from '@dxos/keys';
|
|
12
|
-
import { log } from '@dxos/log';
|
|
13
|
-
|
|
14
|
-
import { AIServiceEdgeClient, Tool } from '../ai-service';
|
|
15
|
-
import { defineTool, ToolResult } from '../conversation';
|
|
16
|
-
|
|
17
|
-
// TODO(dmaretskyi): Effect schema.
|
|
18
|
-
const ArtifactDef = S.Struct({
|
|
19
|
-
typename: S.String,
|
|
20
|
-
description: S.String,
|
|
21
|
-
schema: S.Any,
|
|
22
|
-
actions: S.Array(Tool),
|
|
23
|
-
}).pipe(S.mutable);
|
|
24
|
-
|
|
25
|
-
type ArtifactDef = S.Schema.Type<typeof ArtifactDef>;
|
|
26
|
-
|
|
27
|
-
const ListItem = S.Struct({
|
|
28
|
-
name: S.String,
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
const ListSchema = S.Struct({
|
|
32
|
-
id: ObjectId,
|
|
33
|
-
title: S.String,
|
|
34
|
-
items: S.Array(ListItem).pipe(S.mutable),
|
|
35
|
-
}).pipe(S.mutable);
|
|
36
|
-
|
|
37
|
-
type ListSchema = S.Schema.Type<typeof ListSchema>;
|
|
38
|
-
|
|
39
|
-
const list: ArtifactDef = {
|
|
40
|
-
typename: 'example.com/type/List',
|
|
41
|
-
description: 'Ordered set of text items.',
|
|
42
|
-
schema: ListSchema,
|
|
43
|
-
actions: [
|
|
44
|
-
defineTool('list', {
|
|
45
|
-
name: 'query',
|
|
46
|
-
description: 'Query all lists',
|
|
47
|
-
schema: S.Struct({}),
|
|
48
|
-
execute: async ({}, context) => {
|
|
49
|
-
return ToolResult.Success(LISTS[id]);
|
|
50
|
-
},
|
|
51
|
-
}),
|
|
52
|
-
defineTool('list', {
|
|
53
|
-
name: 'inspect',
|
|
54
|
-
description: 'Get contents of the list',
|
|
55
|
-
schema: S.Struct({
|
|
56
|
-
id: ObjectId.annotations({ description: 'The list to inspect' }),
|
|
57
|
-
}),
|
|
58
|
-
execute: async ({ id }, context) => {
|
|
59
|
-
return ToolResult.Success(LISTS[id]);
|
|
60
|
-
},
|
|
61
|
-
}),
|
|
62
|
-
defineTool('list', {
|
|
63
|
-
name: 'create',
|
|
64
|
-
description: 'Add one or more items to an existing list',
|
|
65
|
-
schema: S.Struct({
|
|
66
|
-
id: ObjectId.annotations({ description: 'The list to add items to' }),
|
|
67
|
-
items: S.Array(ListItem).annotations({ description: 'The items to add to the list' }),
|
|
68
|
-
}),
|
|
69
|
-
execute: async ({ id, items }, context) => {
|
|
70
|
-
LISTS[id].items.push(...items);
|
|
71
|
-
return ToolResult.Success(LISTS[id]);
|
|
72
|
-
},
|
|
73
|
-
}),
|
|
74
|
-
],
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
const LISTS: Record<ObjectId, ListSchema> = {};
|
|
78
|
-
|
|
79
|
-
const artifacts = [list];
|
|
80
|
-
|
|
81
|
-
const getArtifactDefinitions = defineTool('system', {
|
|
82
|
-
name: 'getArtifactDefinitions',
|
|
83
|
-
description: 'Queries the definitions and metadata of artifacts defined in the system',
|
|
84
|
-
schema: S.Any,
|
|
85
|
-
execute: async (_, context) => {
|
|
86
|
-
return ToolResult.Success(
|
|
87
|
-
artifacts.map((artifact) => ({
|
|
88
|
-
typename: artifact.typename,
|
|
89
|
-
description: artifact.description,
|
|
90
|
-
schema: toJsonSchema(artifact.schema),
|
|
91
|
-
actions: artifact.actions.map((action) => ({
|
|
92
|
-
name: action.name,
|
|
93
|
-
description: action.description,
|
|
94
|
-
})),
|
|
95
|
-
})),
|
|
96
|
-
);
|
|
97
|
-
},
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
const ARTIFACT_INSTRUCTIONS = `
|
|
101
|
-
You have ability to interact with artifacts.
|
|
102
|
-
Artifacts are persistent structured objects that have actions associated with them.
|
|
103
|
-
|
|
104
|
-
Before replying to the user you should first query the artifact definitions and metadata.
|
|
105
|
-
If there's
|
|
106
|
-
|
|
107
|
-
`;
|
|
108
|
-
|
|
109
|
-
describe('Artifacts', () => {
|
|
110
|
-
test('shopping list', async () => {
|
|
111
|
-
const client = new AIServiceEdgeClient({
|
|
112
|
-
endpoint: ENDPOINT,
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
const custodian: Tool = {
|
|
116
|
-
name: 'custodian',
|
|
117
|
-
description: 'Custodian can tell you the password if you say the magic word',
|
|
118
|
-
parameters: toJsonSchema(
|
|
119
|
-
S.Struct({
|
|
120
|
-
magicWord: S.String.annotations({ description: 'The magic word. Should be exactly "pretty please"' }),
|
|
121
|
-
}),
|
|
122
|
-
),
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
const spaceId = SpaceId.random();
|
|
126
|
-
const threadId = ObjectId.random();
|
|
127
|
-
|
|
128
|
-
await client.appendMessages([
|
|
129
|
-
{
|
|
130
|
-
id: ObjectId.random(),
|
|
131
|
-
spaceId,
|
|
132
|
-
threadId,
|
|
133
|
-
role: 'user',
|
|
134
|
-
content: [{ type: 'text', text: 'What is the password? Ask the custodian' }],
|
|
135
|
-
},
|
|
136
|
-
]);
|
|
137
|
-
|
|
138
|
-
const stream = await client.generate({
|
|
139
|
-
model: DEFAULT_EDGE_MODEL,
|
|
140
|
-
spaceId,
|
|
141
|
-
threadId,
|
|
142
|
-
systemPrompt: 'You are a helpful assistant.',
|
|
143
|
-
tools: [custodian],
|
|
144
|
-
});
|
|
145
|
-
for await (const event of stream) {
|
|
146
|
-
log('event', event);
|
|
147
|
-
}
|
|
148
|
-
const [message] = await stream.complete();
|
|
149
|
-
log('full message', {
|
|
150
|
-
message,
|
|
151
|
-
});
|
|
152
|
-
await client.appendMessages([message]);
|
|
153
|
-
|
|
154
|
-
const toolUse = message.content.find(({ type }) => type === 'tool_use')!;
|
|
155
|
-
invariant(toolUse.type === 'tool_use');
|
|
156
|
-
await client.appendMessages([
|
|
157
|
-
{
|
|
158
|
-
id: ObjectId.random(),
|
|
159
|
-
spaceId,
|
|
160
|
-
threadId,
|
|
161
|
-
role: 'user',
|
|
162
|
-
content: [{ type: 'tool_result', toolUseId: toolUse.id, content: 'password="The sky is gray"' }],
|
|
163
|
-
},
|
|
164
|
-
]);
|
|
165
|
-
|
|
166
|
-
const stream2 = await client.generate({
|
|
167
|
-
model: DEFAULT_EDGE_MODEL,
|
|
168
|
-
spaceId,
|
|
169
|
-
threadId,
|
|
170
|
-
systemPrompt: 'You are a helpful assistant.',
|
|
171
|
-
tools: [custodian],
|
|
172
|
-
});
|
|
173
|
-
for await (const event of stream2) {
|
|
174
|
-
log('event', event);
|
|
175
|
-
}
|
|
176
|
-
const [message2] = await stream2.complete();
|
|
177
|
-
log('full message', {
|
|
178
|
-
message: message2,
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
});
|
|
182
|
-
*/
|
package/src/testing/data.ts
DELETED
package/src/testing/defs.ts
DELETED
package/src/testing/logger.ts
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2024 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import type { ImageSource, MessageContentBlock } from '@dxos/artifact';
|
|
6
|
-
|
|
7
|
-
import type { ConversationEvent } from '../conversation';
|
|
8
|
-
|
|
9
|
-
export const createLogger = ({
|
|
10
|
-
stream,
|
|
11
|
-
filter,
|
|
12
|
-
onImage,
|
|
13
|
-
}: {
|
|
14
|
-
stream?: boolean;
|
|
15
|
-
filter?: (event: ConversationEvent) => boolean;
|
|
16
|
-
onImage?: (img: { id: string; description?: string; source: ImageSource }) => void;
|
|
17
|
-
} = {}) => {
|
|
18
|
-
const images: Record<string, any> = {};
|
|
19
|
-
let currentText = '';
|
|
20
|
-
|
|
21
|
-
return (event: ConversationEvent) => {
|
|
22
|
-
if (typeof filter === 'function' && !filter(event)) {
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const printContentBlock = (content: MessageContentBlock) => {
|
|
27
|
-
switch (content.type) {
|
|
28
|
-
case 'text':
|
|
29
|
-
process.stdout.write(content.text);
|
|
30
|
-
break;
|
|
31
|
-
case 'tool_use':
|
|
32
|
-
process.stdout.write(`⚙️ [Tool Use] ${content.name}\n`);
|
|
33
|
-
break;
|
|
34
|
-
case 'image': {
|
|
35
|
-
if (content.id && content.source) {
|
|
36
|
-
images[content.id] = content.source;
|
|
37
|
-
}
|
|
38
|
-
process.stdout.write(`[Image id=${content.id} mediaType=${content.source?.mediaType}]`);
|
|
39
|
-
break;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
const onTextBlockPrinted = (text: string) => {
|
|
45
|
-
const imageMatch = text.match(/<image id="([^"]+)"(?:\s+prompt="([^"]+)")?\s*\/>/);
|
|
46
|
-
if (imageMatch && onImage && images[imageMatch[1]]) {
|
|
47
|
-
onImage({
|
|
48
|
-
id: imageMatch[1],
|
|
49
|
-
description: imageMatch[2], // Extract prompt as description if present
|
|
50
|
-
source: images[imageMatch[1]],
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
if (stream) {
|
|
56
|
-
switch (event.type) {
|
|
57
|
-
case 'message_start': {
|
|
58
|
-
process.stdout.write(`${event.message.role.toUpperCase()}\n\n`);
|
|
59
|
-
for (const content of event.message.content) {
|
|
60
|
-
printContentBlock(content);
|
|
61
|
-
}
|
|
62
|
-
break;
|
|
63
|
-
}
|
|
64
|
-
case 'content_block_start': {
|
|
65
|
-
currentText = '';
|
|
66
|
-
printContentBlock(event.content);
|
|
67
|
-
break;
|
|
68
|
-
}
|
|
69
|
-
case 'content_block_delta': {
|
|
70
|
-
switch (event.delta.type) {
|
|
71
|
-
case 'text_delta': {
|
|
72
|
-
currentText += event.delta.text;
|
|
73
|
-
process.stdout.write(event.delta.text);
|
|
74
|
-
break;
|
|
75
|
-
}
|
|
76
|
-
case 'input_json_delta': {
|
|
77
|
-
process.stdout.write(event.delta.partial_json);
|
|
78
|
-
break;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
break;
|
|
82
|
-
}
|
|
83
|
-
case 'content_block_stop': {
|
|
84
|
-
process.stdout.write('\n');
|
|
85
|
-
onTextBlockPrinted(currentText);
|
|
86
|
-
currentText = '';
|
|
87
|
-
break;
|
|
88
|
-
}
|
|
89
|
-
case 'message_delta': {
|
|
90
|
-
break;
|
|
91
|
-
}
|
|
92
|
-
case 'message_stop': {
|
|
93
|
-
process.stdout.write('\n\n');
|
|
94
|
-
break;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
switch (event.type) {
|
|
100
|
-
case 'message': {
|
|
101
|
-
if (!stream || event.message.role !== 'assistant') {
|
|
102
|
-
process.stdout.write(`${event.message.role.toUpperCase()}\n\n`);
|
|
103
|
-
for (const block of event.message.content) {
|
|
104
|
-
switch (block.type) {
|
|
105
|
-
case 'text':
|
|
106
|
-
process.stdout.write(block.text + '\n');
|
|
107
|
-
onTextBlockPrinted(block.text);
|
|
108
|
-
break;
|
|
109
|
-
case 'tool_use':
|
|
110
|
-
process.stdout.write(`⚙️ [Tool Use] ${block.name}\n`);
|
|
111
|
-
process.stdout.write(` ${JSON.stringify(block.input)}\n`);
|
|
112
|
-
break;
|
|
113
|
-
case 'tool_result':
|
|
114
|
-
if (block.isError) {
|
|
115
|
-
process.stdout.write('❌ [Tool Error]\n');
|
|
116
|
-
process.stdout.write(block.content + '\n');
|
|
117
|
-
} else {
|
|
118
|
-
process.stdout.write('✅ [Tool Success]\n');
|
|
119
|
-
process.stdout.write(block.content + '\n');
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
process.stdout.write('\n\n');
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
break;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
};
|
|
129
|
-
};
|