@dxos/assistant-toolkit 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.
- package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
- package/dist/lib/browser/chunk-J5LGTIGS.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +1091 -692
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +43 -0
- package/dist/lib/browser/testing/index.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +1090 -692
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +44 -0
- package/dist/lib/node-esm/testing/index.mjs.map +7 -0
- package/dist/types/src/blueprints/design/design-blueprint.d.ts +17 -3
- package/dist/types/src/blueprints/design/design-blueprint.d.ts.map +1 -1
- package/dist/types/src/blueprints/design/index.d.ts +1 -1
- package/dist/types/src/blueprints/design/index.d.ts.map +1 -1
- package/dist/types/src/blueprints/discord/discord-blueprint.d.ts +13 -13
- package/dist/types/src/blueprints/discord/discord-blueprint.d.ts.map +1 -1
- package/dist/types/src/blueprints/discord/index.d.ts +1 -1
- package/dist/types/src/blueprints/discord/index.d.ts.map +1 -1
- package/dist/types/src/blueprints/linear/index.d.ts +1 -1
- package/dist/types/src/blueprints/linear/index.d.ts.map +1 -1
- package/dist/types/src/blueprints/linear/linear-blueprint.d.ts +13 -13
- package/dist/types/src/blueprints/linear/linear-blueprint.d.ts.map +1 -1
- package/dist/types/src/blueprints/planning/index.d.ts +1 -1
- package/dist/types/src/blueprints/planning/index.d.ts.map +1 -1
- package/dist/types/src/blueprints/planning/planning-blueprint.d.ts +17 -3
- package/dist/types/src/blueprints/planning/planning-blueprint.d.ts.map +1 -1
- package/dist/types/src/blueprints/research/index.d.ts +1 -1
- package/dist/types/src/blueprints/research/index.d.ts.map +1 -1
- package/dist/types/src/blueprints/research/research-blueprint.d.ts +17 -3
- package/dist/types/src/blueprints/research/research-blueprint.d.ts.map +1 -1
- package/dist/types/src/blueprints/testing.d.ts +2 -2
- package/dist/types/src/blueprints/testing.d.ts.map +1 -1
- package/dist/types/src/blueprints/websearch/index.d.ts +1 -1
- package/dist/types/src/blueprints/websearch/index.d.ts.map +1 -1
- package/dist/types/src/blueprints/websearch/websearch-blueprint.d.ts +17 -3
- package/dist/types/src/blueprints/websearch/websearch-blueprint.d.ts.map +1 -1
- package/dist/types/src/blueprints/websearch/websearch-toolkit.d.ts +1 -0
- package/dist/types/src/blueprints/websearch/websearch-toolkit.d.ts.map +1 -1
- package/dist/types/src/{functions/research → crud}/graph.d.ts +14 -11
- package/dist/types/src/crud/graph.d.ts.map +1 -0
- package/dist/types/src/crud/graph.test.d.ts.map +1 -0
- package/dist/types/src/crud/index.d.ts +2 -0
- package/dist/types/src/crud/index.d.ts.map +1 -0
- package/dist/types/src/functions/agent/prompt.d.ts +73 -8
- package/dist/types/src/functions/agent/prompt.d.ts.map +1 -1
- package/dist/types/src/functions/discord/fetch-messages.d.ts +1 -1
- package/dist/types/src/functions/discord/index.d.ts +1 -1
- package/dist/types/src/functions/discord/index.d.ts.map +1 -1
- package/dist/types/src/functions/document/index.d.ts +3 -2
- package/dist/types/src/functions/document/index.d.ts.map +1 -1
- package/dist/types/src/functions/document/read.d.ts +1 -1
- package/dist/types/src/functions/document/read.d.ts.map +1 -1
- package/dist/types/src/functions/document/update.d.ts +1 -1
- package/dist/types/src/functions/document/update.d.ts.map +1 -1
- package/dist/types/src/functions/entity-extraction/entity-extraction.d.ts +126 -125
- package/dist/types/src/functions/entity-extraction/entity-extraction.d.ts.map +1 -1
- package/dist/types/src/functions/entity-extraction/index.d.ts +126 -125
- package/dist/types/src/functions/entity-extraction/index.d.ts.map +1 -1
- package/dist/types/src/functions/exa/data/exa-search-1748337321991.d.ts.map +1 -0
- package/dist/types/src/functions/exa/data/exa-search-1748337331526.d.ts.map +1 -0
- package/dist/types/src/functions/exa/data/exa-search-1748337344119.d.ts.map +1 -0
- package/dist/types/src/functions/exa/data/index.d.ts.map +1 -0
- package/dist/types/src/functions/exa/exa.d.ts +1 -1
- package/dist/types/src/functions/exa/mock.d.ts +1 -1
- package/dist/types/src/functions/github/fetch-prs.d.ts +1 -1
- package/dist/types/src/functions/github/fetch-prs.d.ts.map +1 -1
- package/dist/types/src/functions/linear/index.d.ts +2 -2
- package/dist/types/src/functions/linear/index.d.ts.map +1 -1
- package/dist/types/src/functions/linear/sync-issues.d.ts +2 -2
- package/dist/types/src/functions/linear/sync-issues.d.ts.map +1 -1
- package/dist/types/src/functions/research/document-create.d.ts +9 -0
- package/dist/types/src/functions/research/document-create.d.ts.map +1 -0
- package/dist/types/src/functions/research/index.d.ts +8 -6
- package/dist/types/src/functions/research/index.d.ts.map +1 -1
- package/dist/types/src/functions/research/research-graph.d.ts +9 -8
- package/dist/types/src/functions/research/research-graph.d.ts.map +1 -1
- package/dist/types/src/functions/research/research.d.ts +4 -3
- package/dist/types/src/functions/research/research.d.ts.map +1 -1
- package/dist/types/src/functions/research/types.d.ts +2 -380
- package/dist/types/src/functions/research/types.d.ts.map +1 -1
- package/dist/types/src/functions/tasks/index.d.ts +2 -2
- package/dist/types/src/functions/tasks/index.d.ts.map +1 -1
- package/dist/types/src/functions/tasks/read.d.ts +1 -1
- package/dist/types/src/functions/tasks/read.d.ts.map +1 -1
- package/dist/types/src/functions/tasks/update.d.ts +1 -1
- package/dist/types/src/functions/tasks/update.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +2 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/initiative/Initiative.d.ts +84 -0
- package/dist/types/src/initiative/Initiative.d.ts.map +1 -0
- package/dist/types/src/initiative/InitiativeSchema.d.ts +19 -0
- package/dist/types/src/initiative/InitiativeSchema.d.ts.map +1 -0
- package/dist/types/src/initiative/functions/agent.d.ts +37 -0
- package/dist/types/src/initiative/functions/agent.d.ts.map +1 -0
- package/dist/types/src/initiative/functions/getContext.d.ts +17 -0
- package/dist/types/src/initiative/functions/getContext.d.ts.map +1 -0
- package/dist/types/src/initiative/functions/index.d.ts +4 -0
- package/dist/types/src/initiative/functions/index.d.ts.map +1 -0
- package/dist/types/src/{functions/research/create-document.d.ts → initiative/functions/update.d.ts} +3 -3
- package/dist/types/src/initiative/functions/update.d.ts.map +1 -0
- package/dist/types/src/initiative/index.d.ts +1 -0
- package/dist/types/src/initiative/index.d.ts.map +1 -0
- package/dist/types/src/initiative/initiative.test.d.ts +2 -0
- package/dist/types/src/initiative/initiative.test.d.ts.map +1 -0
- package/dist/types/src/sync/sync.d.ts +3 -3
- package/dist/types/src/sync/sync.d.ts.map +1 -1
- package/dist/types/src/testing/index.d.ts +1 -1
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/testing/plugins.d.ts +19 -0
- package/dist/types/src/testing/plugins.d.ts.map +1 -0
- package/dist/types/src/toolkits/AssistantToolkit.d.ts +43 -0
- package/dist/types/src/toolkits/AssistantToolkit.d.ts.map +1 -0
- package/dist/types/src/toolkits/AssistantToolkit.test.d.ts +2 -0
- package/dist/types/src/toolkits/AssistantToolkit.test.d.ts.map +1 -0
- package/dist/types/src/toolkits/SystemToolkit.d.ts +99 -0
- package/dist/types/src/toolkits/SystemToolkit.d.ts.map +1 -0
- package/dist/types/src/toolkits/index.d.ts +3 -0
- package/dist/types/src/toolkits/index.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +49 -33
- package/src/blueprints/design/design-blueprint.test.ts +17 -20
- package/src/blueprints/design/design-blueprint.ts +4 -6
- package/src/blueprints/design/index.ts +1 -1
- package/src/blueprints/discord/discord-blueprint.ts +4 -6
- package/src/blueprints/discord/index.ts +1 -1
- package/src/blueprints/linear/index.ts +1 -1
- package/src/blueprints/linear/linear-blueprint.ts +4 -6
- package/src/blueprints/planning/index.ts +1 -1
- package/src/blueprints/planning/planning-blueprint.test.ts +17 -20
- package/src/blueprints/planning/planning-blueprint.ts +4 -6
- package/src/blueprints/research/index.ts +1 -1
- package/src/blueprints/research/research-blueprint.ts +25 -19
- package/src/blueprints/testing.ts +2 -2
- package/src/blueprints/websearch/index.ts +2 -1
- package/src/blueprints/websearch/websearch-blueprint.ts +4 -6
- package/src/crud/graph.test.ts +46 -0
- package/src/{functions/research → crud}/graph.ts +32 -40
- package/src/crud/index.ts +5 -0
- package/src/experimental/feed.test.ts +12 -9
- package/src/functions/agent/prompt.ts +39 -22
- package/src/functions/discord/fetch-messages.test.ts +6 -7
- package/src/functions/discord/fetch-messages.ts +11 -10
- package/src/functions/document/index.ts +1 -0
- package/src/functions/document/read.ts +4 -3
- package/src/functions/document/update.ts +7 -4
- package/src/functions/entity-extraction/entity-extraction.conversations.json +6597 -1
- package/src/functions/entity-extraction/entity-extraction.test.ts +16 -23
- package/src/functions/entity-extraction/entity-extraction.ts +51 -31
- package/src/functions/exa/mock.ts +1 -1
- package/src/functions/github/fetch-prs.ts +3 -2
- package/src/functions/linear/linear.test.ts +18 -20
- package/src/functions/linear/sync-issues.ts +14 -12
- package/src/functions/research/document-create.ts +76 -0
- package/src/functions/research/index.ts +1 -2
- package/src/functions/research/research-graph.ts +13 -11
- package/src/functions/research/{instructions-research.tpl → research-instructions.tpl} +14 -6
- package/src/functions/research/research.conversations.json +1 -10714
- package/src/functions/research/research.test.ts +92 -161
- package/src/functions/research/research.ts +88 -54
- package/src/functions/research/types.ts +14 -12
- package/src/functions/tasks/read.ts +4 -3
- package/src/functions/tasks/update.ts +4 -3
- package/src/index.ts +2 -1
- package/src/initiative/Initiative.ts +99 -0
- package/src/initiative/InitiativeSchema.ts +37 -0
- package/src/initiative/functions/agent.ts +57 -0
- package/src/initiative/functions/getContext.ts +74 -0
- package/src/initiative/functions/index.ts +7 -0
- package/src/initiative/functions/update.ts +63 -0
- package/src/initiative/index.ts +3 -0
- package/src/initiative/initiative.conversations.json +1 -0
- package/src/initiative/initiative.test.ts +485 -0
- package/src/sync/sync.ts +38 -30
- package/src/testing/index.ts +1 -1
- package/src/{plugins.tsx → testing/plugins.tsx} +15 -15
- package/src/toolkits/AssistantToolkit.conversations.json +1 -0
- package/src/toolkits/AssistantToolkit.test.ts +94 -0
- package/src/toolkits/AssistantToolkit.ts +70 -0
- package/src/toolkits/SystemToolkit.ts +299 -0
- package/src/toolkits/index.ts +6 -0
- package/dist/types/src/functions/research/create-document.d.ts.map +0 -1
- package/dist/types/src/functions/research/graph.d.ts.map +0 -1
- package/dist/types/src/functions/research/graph.test.d.ts.map +0 -1
- package/dist/types/src/plugins.d.ts +0 -19
- package/dist/types/src/plugins.d.ts.map +0 -1
- package/dist/types/src/testing/data/exa-search-1748337321991.d.ts.map +0 -1
- package/dist/types/src/testing/data/exa-search-1748337331526.d.ts.map +0 -1
- package/dist/types/src/testing/data/exa-search-1748337344119.d.ts.map +0 -1
- package/dist/types/src/testing/data/index.d.ts.map +0 -1
- package/src/functions/research/create-document.ts +0 -69
- package/src/functions/research/graph.test.ts +0 -69
- /package/dist/types/src/{functions/research → crud}/graph.test.d.ts +0 -0
- /package/dist/types/src/{testing → functions/exa}/data/exa-search-1748337321991.d.ts +0 -0
- /package/dist/types/src/{testing → functions/exa}/data/exa-search-1748337331526.d.ts +0 -0
- /package/dist/types/src/{testing → functions/exa}/data/exa-search-1748337344119.d.ts +0 -0
- /package/dist/types/src/{testing → functions/exa}/data/index.d.ts +0 -0
- /package/src/{testing → functions/exa}/data/exa-search-1748337321991.ts +0 -0
- /package/src/{testing → functions/exa}/data/exa-search-1748337331526.ts +0 -0
- /package/src/{testing → functions/exa}/data/exa-search-1748337344119.ts +0 -0
- /package/src/{testing → functions/exa}/data/index.ts +0 -0
|
@@ -1,23 +1,28 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
__export
|
|
4
|
+
} from "./chunk-HSLMI22Q.mjs";
|
|
2
5
|
|
|
3
6
|
// src/blueprints/design/design-blueprint.ts
|
|
4
7
|
import { ToolId } from "@dxos/ai";
|
|
5
8
|
import { Blueprint } from "@dxos/blueprints";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
9
|
+
import { Ref as Ref6 } from "@dxos/echo";
|
|
10
|
+
import { Text as Text2 } from "@dxos/schema";
|
|
8
11
|
import { trim as trim5 } from "@dxos/util";
|
|
9
12
|
|
|
10
13
|
// src/functions/agent/prompt.ts
|
|
11
14
|
import * as Array2 from "effect/Array";
|
|
12
15
|
import * as Effect from "effect/Effect";
|
|
13
16
|
import * as Function from "effect/Function";
|
|
17
|
+
import * as Match from "effect/Match";
|
|
14
18
|
import * as Option from "effect/Option";
|
|
15
19
|
import * as Schema from "effect/Schema";
|
|
16
20
|
import { AiService, ConsolePrinter, ModelName } from "@dxos/ai";
|
|
17
21
|
import { AiSession, GenerationObserver, createToolkit } from "@dxos/assistant";
|
|
18
22
|
import { Prompt, Template } from "@dxos/blueprints";
|
|
19
23
|
import { Obj, Ref, Type } from "@dxos/echo";
|
|
20
|
-
import {
|
|
24
|
+
import { Database } from "@dxos/echo";
|
|
25
|
+
import { TracingService, defineFunction } from "@dxos/functions";
|
|
21
26
|
import { log } from "@dxos/log";
|
|
22
27
|
var __dxlog_file = "/__w/dxos/dxos/packages/core/assistant-toolkit/src/functions/agent/prompt.ts";
|
|
23
28
|
var DEFAULT_MODEL = "@anthropic/claude-opus-4-0";
|
|
@@ -36,10 +41,9 @@ var prompt_default = defineFunction({
|
|
|
36
41
|
* Input object or data.
|
|
37
42
|
* References get auto-resolved.
|
|
38
43
|
*/
|
|
39
|
-
input: Schema.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
})
|
|
44
|
+
input: Schema.Any.pipe(Schema.annotations({
|
|
45
|
+
title: "Input"
|
|
46
|
+
}))
|
|
43
47
|
}),
|
|
44
48
|
outputSchema: Schema.Any,
|
|
45
49
|
handler: Effect.fnUntraced(function* ({ data }) {
|
|
@@ -47,47 +51,39 @@ var prompt_default = defineFunction({
|
|
|
47
51
|
input: data.input
|
|
48
52
|
}, {
|
|
49
53
|
F: __dxlog_file,
|
|
50
|
-
L:
|
|
54
|
+
L: 41,
|
|
51
55
|
S: this,
|
|
52
56
|
C: (f, a) => f(...a)
|
|
53
57
|
});
|
|
54
|
-
const input = {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (Ref.isRef(value)) {
|
|
60
|
-
const object = yield* DatabaseService.load(value);
|
|
61
|
-
input[key] = Obj.toJSON(object);
|
|
62
|
-
} else {
|
|
63
|
-
input[key] = JSON.stringify(value);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
yield* DatabaseService.flush({
|
|
58
|
+
const input = yield* Match.value(data.input).pipe(Match.when((value2) => Ref.isRef(value2), Effect.fnUntraced(function* (ref) {
|
|
59
|
+
const object = yield* Database.Service.load(ref);
|
|
60
|
+
return Obj.toJSON(object);
|
|
61
|
+
})), Match.orElse(() => Effect.succeed(data.input)));
|
|
62
|
+
yield* Database.Service.flush({
|
|
67
63
|
indexes: true
|
|
68
64
|
});
|
|
69
|
-
const prompt = yield*
|
|
70
|
-
const systemPrompt = data.systemPrompt ? yield*
|
|
65
|
+
const prompt = yield* Database.Service.load(data.prompt);
|
|
66
|
+
const systemPrompt = data.systemPrompt ? yield* Database.Service.load(data.systemPrompt) : void 0;
|
|
71
67
|
yield* TracingService.emitStatus({
|
|
72
68
|
message: `Running ${prompt.id}`
|
|
73
69
|
});
|
|
74
70
|
log.info("starting agent", {
|
|
75
71
|
prompt: prompt.id,
|
|
76
|
-
input
|
|
72
|
+
input
|
|
77
73
|
}, {
|
|
78
74
|
F: __dxlog_file,
|
|
79
|
-
L:
|
|
75
|
+
L: 71,
|
|
80
76
|
S: this,
|
|
81
77
|
C: (f, a) => f(...a)
|
|
82
78
|
});
|
|
83
|
-
const blueprints = yield* Function.pipe(prompt.blueprints, Array2.appendAll(systemPrompt?.blueprints ?? []), Effect.forEach(
|
|
84
|
-
const objects = yield* Function.pipe(prompt.context, Array2.appendAll(systemPrompt?.context ?? []), Effect.forEach(DatabaseService.loadOption), Effect.map(Array2.filter(Option.isSome)), Effect.map(Array2.map((option) => option.value)));
|
|
79
|
+
const blueprints = yield* Function.pipe(prompt.blueprints, Array2.appendAll(systemPrompt?.blueprints ?? []), Effect.forEach(Database.Service.loadOption), Effect.map(Array2.filter(Option.isSome)), Effect.map(Array2.map((option) => option.value)));
|
|
85
80
|
const toolkit = yield* createToolkit({
|
|
86
81
|
blueprints
|
|
87
82
|
});
|
|
88
|
-
const
|
|
83
|
+
const objects = yield* Function.pipe(prompt.context, Array2.appendAll(systemPrompt?.context ?? []), Effect.forEach(Database.Service.loadOption), Effect.map(Array2.filter(Option.isSome)), Effect.map(Array2.map((option) => option.value)));
|
|
84
|
+
const promptInstructions = yield* Database.Service.load(prompt.instructions.source);
|
|
89
85
|
const promptText = Template.process(promptInstructions.content, input);
|
|
90
|
-
const systemInstructions = systemPrompt ? yield*
|
|
86
|
+
const systemInstructions = systemPrompt ? yield* Database.Service.load(systemPrompt.instructions.source) : void 0;
|
|
91
87
|
const systemText = systemInstructions ? Template.process(systemInstructions.content, {}) : void 0;
|
|
92
88
|
const session = new AiSession();
|
|
93
89
|
const result = yield* session.run({
|
|
@@ -125,7 +121,7 @@ import * as Schema2 from "effect/Schema";
|
|
|
125
121
|
import { Obj as Obj2 } from "@dxos/echo";
|
|
126
122
|
import { CredentialsService, TracingService as TracingService2, defineFunction as defineFunction2 } from "@dxos/functions";
|
|
127
123
|
import { log as log2 } from "@dxos/log";
|
|
128
|
-
import {
|
|
124
|
+
import { Message } from "@dxos/types";
|
|
129
125
|
var __dxlog_file2 = "/__w/dxos/dxos/packages/core/assistant-toolkit/src/functions/discord/fetch-messages.ts";
|
|
130
126
|
var TimeRange = class extends Schema2.String.pipe(Schema2.pattern(/\d+(s|m|h|d)/)).annotations({
|
|
131
127
|
description: "Time range. 1d - 1 day, 2h - 2 hours, 30m - 30 minutes, 15s - 15 seconds.",
|
|
@@ -198,11 +194,11 @@ var fetch_messages_default = defineFunction2({
|
|
|
198
194
|
description: "Exclude messages from these usernames."
|
|
199
195
|
})
|
|
200
196
|
}),
|
|
201
|
-
handler: Effect2.fnUntraced(function* ({ data: { serverId, channelId, after, last, pageSize = 100, limit = DEFAULT_LIMIT, ignoreUsernames = DEFAULT_IGNORE_USERNAMES } }) {
|
|
202
|
-
if (!after && !
|
|
197
|
+
handler: Effect2.fnUntraced(function* ({ data: { serverId, channelId, after, last: last2, pageSize = 100, limit = DEFAULT_LIMIT, ignoreUsernames = DEFAULT_IGNORE_USERNAMES } }) {
|
|
198
|
+
if (!after && !last2) {
|
|
203
199
|
throw new Error("cannot specify both `after` and `last`");
|
|
204
200
|
}
|
|
205
|
-
const afterTs =
|
|
201
|
+
const afterTs = last2 ? Date.now() / 1e3 - TimeRange.toSeconds(last2) : after ?? DEFAULT_AFTER;
|
|
206
202
|
const rest = yield* DiscordREST;
|
|
207
203
|
let channels = [];
|
|
208
204
|
channels.push(...yield* rest.listGuildChannels(serverId));
|
|
@@ -215,7 +211,15 @@ var fetch_messages_default = defineFunction2({
|
|
|
215
211
|
throw new Error("no channels found");
|
|
216
212
|
}
|
|
217
213
|
for (const channel of channels) {
|
|
218
|
-
|
|
214
|
+
log2.info("channel", {
|
|
215
|
+
id: channel.id,
|
|
216
|
+
name: "name" in channel ? channel.name : void 0
|
|
217
|
+
}, {
|
|
218
|
+
F: __dxlog_file2,
|
|
219
|
+
L: 136,
|
|
220
|
+
S: this,
|
|
221
|
+
C: (f, a) => f(...a)
|
|
222
|
+
});
|
|
219
223
|
}
|
|
220
224
|
yield* TracingService2.emitStatus({
|
|
221
225
|
message: `Will fetch from channels: ${channels.length}`
|
|
@@ -276,7 +280,7 @@ var parseSnowflake = (snowflake) => {
|
|
|
276
280
|
const discordEpoch = 1420070400000n;
|
|
277
281
|
return new Date(Number((BigInt(snowflake) >> 22n) + discordEpoch));
|
|
278
282
|
};
|
|
279
|
-
var makeMessage = (message) => Obj2.make(
|
|
283
|
+
var makeMessage = (message) => Obj2.make(Message.Message, {
|
|
280
284
|
[Obj2.Meta]: {
|
|
281
285
|
keys: [
|
|
282
286
|
{
|
|
@@ -316,7 +320,8 @@ var Discord;
|
|
|
316
320
|
import * as Effect3 from "effect/Effect";
|
|
317
321
|
import * as Schema3 from "effect/Schema";
|
|
318
322
|
import { ArtifactId } from "@dxos/assistant";
|
|
319
|
-
import {
|
|
323
|
+
import { Database as Database2 } from "@dxos/echo";
|
|
324
|
+
import { defineFunction as defineFunction3 } from "@dxos/functions";
|
|
320
325
|
import { Markdown } from "@dxos/plugin-markdown/types";
|
|
321
326
|
var read_default = defineFunction3({
|
|
322
327
|
key: "dxos.org/function/markdown/read",
|
|
@@ -331,8 +336,8 @@ var read_default = defineFunction3({
|
|
|
331
336
|
content: Schema3.String
|
|
332
337
|
}),
|
|
333
338
|
handler: Effect3.fn(function* ({ data: { id } }) {
|
|
334
|
-
const doc = yield*
|
|
335
|
-
const { content } = yield*
|
|
339
|
+
const doc = yield* Database2.Service.resolve(ArtifactId.toDXN(id), Markdown.Document);
|
|
340
|
+
const { content } = yield* Database2.Service.load(doc.content);
|
|
336
341
|
return {
|
|
337
342
|
content
|
|
338
343
|
};
|
|
@@ -343,7 +348,8 @@ var read_default = defineFunction3({
|
|
|
343
348
|
import * as Effect4 from "effect/Effect";
|
|
344
349
|
import * as Schema4 from "effect/Schema";
|
|
345
350
|
import { ArtifactId as ArtifactId2 } from "@dxos/assistant";
|
|
346
|
-
import {
|
|
351
|
+
import { Database as Database3, Obj as Obj3 } from "@dxos/echo";
|
|
352
|
+
import { defineFunction as defineFunction4 } from "@dxos/functions";
|
|
347
353
|
import { Markdown as Markdown2 } from "@dxos/plugin-markdown/types";
|
|
348
354
|
var update_default = defineFunction4({
|
|
349
355
|
key: "dxos.org/function/markdown/update",
|
|
@@ -359,9 +365,11 @@ var update_default = defineFunction4({
|
|
|
359
365
|
}),
|
|
360
366
|
outputSchema: Schema4.Void,
|
|
361
367
|
handler: Effect4.fn(function* ({ data: { id, content } }) {
|
|
362
|
-
const doc = yield*
|
|
363
|
-
const text = yield*
|
|
364
|
-
text
|
|
368
|
+
const doc = yield* Database3.Service.resolve(ArtifactId2.toDXN(id), Markdown2.Document);
|
|
369
|
+
const text = yield* Database3.Service.load(doc.content);
|
|
370
|
+
Obj3.change(text, (t) => {
|
|
371
|
+
t.content = content;
|
|
372
|
+
});
|
|
365
373
|
})
|
|
366
374
|
});
|
|
367
375
|
|
|
@@ -380,97 +388,375 @@ import * as Predicate from "effect/Predicate";
|
|
|
380
388
|
import * as Schema11 from "effect/Schema";
|
|
381
389
|
import { AiService as AiService3 } from "@dxos/ai";
|
|
382
390
|
import { AiSession as AiSession3, makeToolExecutionServiceFromFunctions as makeToolExecutionServiceFromFunctions2, makeToolResolverFromFunctions as makeToolResolverFromFunctions2 } from "@dxos/assistant";
|
|
383
|
-
import { Filter as Filter2, Obj as
|
|
384
|
-
import {
|
|
391
|
+
import { Filter as Filter2, Obj as Obj8, Ref as Ref3, Type as Type4 } from "@dxos/echo";
|
|
392
|
+
import { Database as Database8 } from "@dxos/echo";
|
|
393
|
+
import { defineFunction as defineFunction9 } from "@dxos/functions";
|
|
394
|
+
import { FunctionInvocationServiceLayerTest } from "@dxos/functions-runtime/testing";
|
|
385
395
|
import { log as log5 } from "@dxos/log";
|
|
386
|
-
import {
|
|
396
|
+
import { LegacyOrganization as LegacyOrganization2, Message as Message2, Organization, Person as Person2 } from "@dxos/types";
|
|
387
397
|
import { trim as trim4 } from "@dxos/util";
|
|
388
398
|
|
|
389
|
-
// src/
|
|
399
|
+
// src/crud/graph.ts
|
|
400
|
+
import * as Tool from "@effect/ai/Tool";
|
|
401
|
+
import * as Toolkit from "@effect/ai/Toolkit";
|
|
402
|
+
import * as Context from "effect/Context";
|
|
390
403
|
import * as Effect5 from "effect/Effect";
|
|
404
|
+
import * as Function3 from "effect/Function";
|
|
405
|
+
import * as Option3 from "effect/Option";
|
|
391
406
|
import * as Schema5 from "effect/Schema";
|
|
392
|
-
import
|
|
393
|
-
import {
|
|
394
|
-
import {
|
|
407
|
+
import * as SchemaAST from "effect/SchemaAST";
|
|
408
|
+
import { Entity, Filter, Obj as Obj4, Query, Type as Type2 } from "@dxos/echo";
|
|
409
|
+
import { Database as Database4 } from "@dxos/echo";
|
|
410
|
+
import { ReferenceAnnotationId, RelationSourceDXNId, RelationSourceId, RelationTargetDXNId, RelationTargetId, createObject, getTypeAnnotation, getTypeIdentifierAnnotation } from "@dxos/echo/internal";
|
|
411
|
+
import { isEncodedReference } from "@dxos/echo-protocol";
|
|
412
|
+
import { mapAst } from "@dxos/effect";
|
|
413
|
+
import { ContextQueueService } from "@dxos/functions";
|
|
395
414
|
import { DXN, ObjectId } from "@dxos/keys";
|
|
396
415
|
import { log as log3 } from "@dxos/log";
|
|
416
|
+
import { deepMapValues, isNonNullable, trim } from "@dxos/util";
|
|
417
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/core/assistant-toolkit/src/crud/graph.ts";
|
|
418
|
+
var Subgraph = Schema5.Struct({
|
|
419
|
+
/** Objects and relations. */
|
|
420
|
+
objects: Schema5.Array(Schema5.Any)
|
|
421
|
+
});
|
|
422
|
+
var findRelatedSchema = async (db, anchor) => {
|
|
423
|
+
const allSchemas = await db.graph.schemaRegistry.query().run();
|
|
424
|
+
return allSchemas.filter((schema) => {
|
|
425
|
+
if (getTypeAnnotation(schema)?.kind !== Entity.Kind.Relation) {
|
|
426
|
+
return false;
|
|
427
|
+
}
|
|
428
|
+
return isSchemaAddressableByDxn(anchor, DXN.parse(getTypeAnnotation(schema).sourceSchema)) || isSchemaAddressableByDxn(anchor, DXN.parse(getTypeAnnotation(schema).targetSchema));
|
|
429
|
+
}).map((schema) => ({
|
|
430
|
+
kind: "relation",
|
|
431
|
+
schema
|
|
432
|
+
}));
|
|
433
|
+
};
|
|
434
|
+
var isSchemaAddressableByDxn = (schema, dxn) => {
|
|
435
|
+
if (getTypeIdentifierAnnotation(schema) === dxn.toString()) {
|
|
436
|
+
return true;
|
|
437
|
+
}
|
|
438
|
+
const t = dxn.asTypeDXN();
|
|
439
|
+
if (t) {
|
|
440
|
+
return t.type === Type2.getTypename(schema);
|
|
441
|
+
}
|
|
442
|
+
return false;
|
|
443
|
+
};
|
|
444
|
+
var LocalSearchToolkit = Toolkit.make(Tool.make("search_local_search", {
|
|
445
|
+
description: "Search the local database for information using a vector index",
|
|
446
|
+
parameters: {
|
|
447
|
+
query: Schema5.String.annotations({
|
|
448
|
+
description: "The query to search for. Could be a question or a topic or a set of keywords."
|
|
449
|
+
})
|
|
450
|
+
},
|
|
451
|
+
success: Schema5.Unknown,
|
|
452
|
+
failure: Schema5.Never,
|
|
453
|
+
dependencies: [
|
|
454
|
+
Database4.Service
|
|
455
|
+
]
|
|
456
|
+
}));
|
|
457
|
+
var LocalSearchHandler = LocalSearchToolkit.toLayer({
|
|
458
|
+
search_local_search: Effect5.fn(function* ({ query }) {
|
|
459
|
+
const objects = yield* Database4.Service.runQuery(Query.select(Filter.text(query, {
|
|
460
|
+
type: "vector"
|
|
461
|
+
})));
|
|
462
|
+
const results = [
|
|
463
|
+
...objects
|
|
464
|
+
];
|
|
465
|
+
const option = yield* Effect5.serviceOption(ContextQueueService);
|
|
466
|
+
if (Option3.isSome(option)) {
|
|
467
|
+
const queueObjects = yield* Effect5.promise(() => option.value.queue.queryObjects());
|
|
468
|
+
results.push(...queueObjects);
|
|
469
|
+
}
|
|
470
|
+
return trim`
|
|
471
|
+
<local_context>
|
|
472
|
+
${JSON.stringify(results, null, 2)}
|
|
473
|
+
</local_context>
|
|
474
|
+
`;
|
|
475
|
+
})
|
|
476
|
+
});
|
|
477
|
+
var GraphWriterSchema = class extends Context.Tag("@dxos/assistant/GraphWriterSchema")() {
|
|
478
|
+
};
|
|
479
|
+
var makeGraphWriterToolkit = ({ schema }) => {
|
|
480
|
+
return Toolkit.make(Tool.make("graph_writer", {
|
|
481
|
+
description: "Write to the local graph database",
|
|
482
|
+
parameters: createExtractionSchema(schema).fields,
|
|
483
|
+
success: Schema5.Unknown,
|
|
484
|
+
failure: Schema5.Never,
|
|
485
|
+
dependencies: [
|
|
486
|
+
Database4.Service,
|
|
487
|
+
ContextQueueService
|
|
488
|
+
]
|
|
489
|
+
}).annotateContext(Context.make(GraphWriterSchema, {
|
|
490
|
+
schema
|
|
491
|
+
})));
|
|
492
|
+
};
|
|
493
|
+
var makeGraphWriterHandler = (toolkit, { onAppend } = {}) => {
|
|
494
|
+
const { schema } = Context.get(toolkit.tools.graph_writer.annotations, GraphWriterSchema);
|
|
495
|
+
return toolkit.toLayer({
|
|
496
|
+
graph_writer: Effect5.fn(function* (input) {
|
|
497
|
+
const { db } = yield* Database4.Service;
|
|
498
|
+
const { queue } = yield* ContextQueueService;
|
|
499
|
+
const data = yield* Effect5.promise(() => sanitizeObjects(schema, input, db, queue));
|
|
500
|
+
yield* Effect5.promise(() => queue.append(data));
|
|
501
|
+
const dxns = data.map((obj) => Obj4.getDXN(obj));
|
|
502
|
+
onAppend?.(dxns);
|
|
503
|
+
return dxns;
|
|
504
|
+
})
|
|
505
|
+
});
|
|
506
|
+
};
|
|
507
|
+
var createExtractionSchema = (types) => {
|
|
508
|
+
return Schema5.Struct({
|
|
509
|
+
...Object.fromEntries(types.map(preprocessSchema).map((schema, index) => [
|
|
510
|
+
`objects_${getSanitizedSchemaName(types[index])}`,
|
|
511
|
+
Schema5.optional(Schema5.Array(schema)).annotations({
|
|
512
|
+
description: `The objects of type: ${Type2.getDXN(types[index])?.asTypeDXN().type}. ${SchemaAST.getDescriptionAnnotation(types[index].ast).pipe(Option3.getOrElse(() => ""))}`
|
|
513
|
+
})
|
|
514
|
+
]))
|
|
515
|
+
});
|
|
516
|
+
};
|
|
517
|
+
var getSanitizedSchemaName = (schema) => {
|
|
518
|
+
return Type2.getDXN(schema).asTypeDXN().type.replaceAll(/[^a-zA-Z0-9]+/g, "_");
|
|
519
|
+
};
|
|
520
|
+
var sanitizeObjects = async (types, data, db, queue) => {
|
|
521
|
+
const entries = types.map((type) => data[`objects_${getSanitizedSchemaName(type)}`]?.map((object) => ({
|
|
522
|
+
data: object,
|
|
523
|
+
schema: type
|
|
524
|
+
})) ?? []).flat();
|
|
525
|
+
const idMap = /* @__PURE__ */ new Map();
|
|
526
|
+
const existingIds = /* @__PURE__ */ new Set();
|
|
527
|
+
const enitties = /* @__PURE__ */ new Map();
|
|
528
|
+
const resolveId = (id) => {
|
|
529
|
+
if (ObjectId.isValid(id)) {
|
|
530
|
+
existingIds.add(id);
|
|
531
|
+
return DXN.fromLocalObjectId(id);
|
|
532
|
+
}
|
|
533
|
+
const mappedId = idMap.get(id);
|
|
534
|
+
if (mappedId) {
|
|
535
|
+
return DXN.fromLocalObjectId(mappedId);
|
|
536
|
+
}
|
|
537
|
+
return void 0;
|
|
538
|
+
};
|
|
539
|
+
const res = entries.map((entry) => {
|
|
540
|
+
if (ObjectId.isValid(entry.data.id)) {
|
|
541
|
+
return entry;
|
|
542
|
+
}
|
|
543
|
+
idMap.set(entry.data.id, ObjectId.random());
|
|
544
|
+
entry.data.id = idMap.get(entry.data.id);
|
|
545
|
+
return entry;
|
|
546
|
+
}).map((entry) => {
|
|
547
|
+
const data2 = deepMapValues(entry.data, (value2, recurse) => {
|
|
548
|
+
if (isEncodedReference(value2)) {
|
|
549
|
+
const ref = value2["/"];
|
|
550
|
+
const id = resolveId(ref);
|
|
551
|
+
if (id) {
|
|
552
|
+
return {
|
|
553
|
+
"/": id.toString()
|
|
554
|
+
};
|
|
555
|
+
} else {
|
|
556
|
+
return {
|
|
557
|
+
"/": `search:?q=${encodeURIComponent(ref)}`
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
return recurse(value2);
|
|
562
|
+
});
|
|
563
|
+
if (Entity.getKind(entry.schema) === "relation") {
|
|
564
|
+
const sourceDxn = resolveId(data2.source);
|
|
565
|
+
if (!sourceDxn) {
|
|
566
|
+
log3.warn("source not found", {
|
|
567
|
+
source: data2.source
|
|
568
|
+
}, {
|
|
569
|
+
F: __dxlog_file3,
|
|
570
|
+
L: 273,
|
|
571
|
+
S: void 0,
|
|
572
|
+
C: (f, a) => f(...a)
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
const targetDxn = resolveId(data2.target);
|
|
576
|
+
if (!targetDxn) {
|
|
577
|
+
log3.warn("target not found", {
|
|
578
|
+
target: data2.target
|
|
579
|
+
}, {
|
|
580
|
+
F: __dxlog_file3,
|
|
581
|
+
L: 277,
|
|
582
|
+
S: void 0,
|
|
583
|
+
C: (f, a) => f(...a)
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
delete data2.source;
|
|
587
|
+
delete data2.target;
|
|
588
|
+
data2[RelationSourceDXNId] = sourceDxn;
|
|
589
|
+
data2[RelationTargetDXNId] = targetDxn;
|
|
590
|
+
}
|
|
591
|
+
return {
|
|
592
|
+
data: data2,
|
|
593
|
+
schema: entry.schema
|
|
594
|
+
};
|
|
595
|
+
}).filter((object) => !existingIds.has(object.data.id));
|
|
596
|
+
const dbObjects = await db.query(Query.select(Filter.id(...existingIds))).run();
|
|
597
|
+
const queueObjects = await queue?.getObjectsById([
|
|
598
|
+
...existingIds
|
|
599
|
+
]) ?? [];
|
|
600
|
+
const objects = [
|
|
601
|
+
...dbObjects,
|
|
602
|
+
...queueObjects
|
|
603
|
+
].filter(isNonNullable);
|
|
604
|
+
log3.info("objects", {
|
|
605
|
+
dbObjects,
|
|
606
|
+
queueObjects,
|
|
607
|
+
existingIds
|
|
608
|
+
}, {
|
|
609
|
+
F: __dxlog_file3,
|
|
610
|
+
L: 298,
|
|
611
|
+
S: void 0,
|
|
612
|
+
C: (f, a) => f(...a)
|
|
613
|
+
});
|
|
614
|
+
const missing = Array.from(existingIds).filter((id) => !objects.some((object) => object.id === id));
|
|
615
|
+
if (missing.length > 0) {
|
|
616
|
+
throw new Error(`Object IDs do not point to existing objects: ${missing.join(", ")}`);
|
|
617
|
+
}
|
|
618
|
+
return res.flatMap(({ data: data2, schema }) => {
|
|
619
|
+
let skip = false;
|
|
620
|
+
if (RelationSourceDXNId in data2) {
|
|
621
|
+
const id = data2[RelationSourceDXNId].asEchoDXN()?.echoId;
|
|
622
|
+
const obj = objects.find((object) => object.id === id) ?? enitties.get(id);
|
|
623
|
+
if (obj) {
|
|
624
|
+
delete data2[RelationSourceDXNId];
|
|
625
|
+
data2[RelationSourceId] = obj;
|
|
626
|
+
} else {
|
|
627
|
+
skip = true;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
if (RelationTargetDXNId in data2) {
|
|
631
|
+
const id = data2[RelationTargetDXNId].asEchoDXN()?.echoId;
|
|
632
|
+
const obj = objects.find((object) => object.id === id) ?? enitties.get(id);
|
|
633
|
+
if (obj) {
|
|
634
|
+
delete data2[RelationTargetDXNId];
|
|
635
|
+
data2[RelationTargetId] = obj;
|
|
636
|
+
} else {
|
|
637
|
+
skip = true;
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
if (!skip) {
|
|
641
|
+
const obj = createObject(schema, data2);
|
|
642
|
+
enitties.set(obj.id, obj);
|
|
643
|
+
return [
|
|
644
|
+
obj
|
|
645
|
+
];
|
|
646
|
+
}
|
|
647
|
+
return [];
|
|
648
|
+
});
|
|
649
|
+
};
|
|
650
|
+
var SoftRef = Schema5.Struct({
|
|
651
|
+
"/": Schema5.String
|
|
652
|
+
}).annotations({
|
|
653
|
+
description: "Reference to another object."
|
|
654
|
+
});
|
|
655
|
+
var preprocessSchema = (schema) => {
|
|
656
|
+
const isRelationSchema = Entity.getKind(schema) === "relation";
|
|
657
|
+
const go = (ast, visited = /* @__PURE__ */ new Set()) => {
|
|
658
|
+
if (visited.has(ast)) {
|
|
659
|
+
return ast;
|
|
660
|
+
}
|
|
661
|
+
visited.add(ast);
|
|
662
|
+
if (SchemaAST.getAnnotation(ast, ReferenceAnnotationId).pipe(Option3.isSome)) {
|
|
663
|
+
return SoftRef.ast;
|
|
664
|
+
}
|
|
665
|
+
return mapAst(ast, (child) => go(child, visited));
|
|
666
|
+
};
|
|
667
|
+
return Schema5.make(mapAst(schema.ast, (ast) => go(ast))).pipe(Schema5.omit("id"), Schema5.extend(Schema5.Struct({
|
|
668
|
+
id: Schema5.String.annotations({
|
|
669
|
+
description: "The id of this object. Come up with a unique id based on your judgement."
|
|
670
|
+
})
|
|
671
|
+
})), isRelationSchema ? Schema5.extend(Schema5.Struct({
|
|
672
|
+
source: Schema5.String.annotations({
|
|
673
|
+
description: "The id of the source object for this relation."
|
|
674
|
+
}),
|
|
675
|
+
target: Schema5.String.annotations({
|
|
676
|
+
description: "The id of the target object for this relation."
|
|
677
|
+
})
|
|
678
|
+
})) : Function3.identity);
|
|
679
|
+
};
|
|
680
|
+
|
|
681
|
+
// src/functions/research/document-create.ts
|
|
682
|
+
import * as Effect6 from "effect/Effect";
|
|
683
|
+
import * as Schema6 from "effect/Schema";
|
|
684
|
+
import { ArtifactId as ArtifactId3 } from "@dxos/assistant";
|
|
685
|
+
import { Obj as Obj5, Relation } from "@dxos/echo";
|
|
686
|
+
import { Database as Database5 } from "@dxos/echo";
|
|
687
|
+
import { TracingService as TracingService3, defineFunction as defineFunction5 } from "@dxos/functions";
|
|
688
|
+
import { log as log4 } from "@dxos/log";
|
|
397
689
|
import { Markdown as Markdown3 } from "@dxos/plugin-markdown/types";
|
|
398
|
-
import {
|
|
399
|
-
import { trim } from "@dxos/util";
|
|
400
|
-
var
|
|
401
|
-
var
|
|
402
|
-
key: "dxos.org/function/research/create
|
|
690
|
+
import { HasSubject } from "@dxos/types";
|
|
691
|
+
import { trim as trim2 } from "@dxos/util";
|
|
692
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/core/assistant-toolkit/src/functions/research/document-create.ts";
|
|
693
|
+
var document_create_default = defineFunction5({
|
|
694
|
+
key: "dxos.org/function/research/document-create",
|
|
403
695
|
name: "Create research document",
|
|
404
696
|
description: "Creates a note summarizing the research.",
|
|
405
|
-
inputSchema:
|
|
406
|
-
|
|
407
|
-
description:
|
|
697
|
+
inputSchema: Schema6.Struct({
|
|
698
|
+
subject: ArtifactId3.annotations({
|
|
699
|
+
description: trim2`
|
|
700
|
+
ID of the object (organization, contact, etc.) for which the research was performed.
|
|
701
|
+
`
|
|
702
|
+
}),
|
|
703
|
+
name: Schema6.String.annotations({
|
|
704
|
+
description: "Name of the document."
|
|
408
705
|
}),
|
|
409
|
-
content:
|
|
410
|
-
description:
|
|
706
|
+
content: Schema6.String.annotations({
|
|
707
|
+
description: trim2`
|
|
411
708
|
Content of the note.
|
|
412
709
|
Supports (and are prefered) references to research objects using @ syntax and <object> tags (refer to research blueprint instructions).
|
|
413
710
|
`
|
|
414
|
-
}),
|
|
415
|
-
// TODO(dmaretskyi): Use a specialized type for this (e.g., ArtifactId renamed as RefFromLLM).
|
|
416
|
-
target: Schema5.String.annotations({
|
|
417
|
-
description: trim`
|
|
418
|
-
Id of the object (organization, contact, etc.) for which the research was performed.
|
|
419
|
-
This must be a ulid.
|
|
420
|
-
`
|
|
421
711
|
})
|
|
422
712
|
}),
|
|
423
|
-
outputSchema:
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
713
|
+
outputSchema: Schema6.Struct({
|
|
714
|
+
document: ArtifactId3.annotations({
|
|
715
|
+
description: "DXN of the created document."
|
|
716
|
+
})
|
|
717
|
+
}),
|
|
718
|
+
handler: Effect6.fnUntraced(function* ({ data: { subject, name, content } }) {
|
|
719
|
+
log4.info("Creating research document", {
|
|
720
|
+
subject,
|
|
427
721
|
name,
|
|
428
722
|
content
|
|
429
723
|
}, {
|
|
430
|
-
F:
|
|
724
|
+
F: __dxlog_file4,
|
|
431
725
|
L: 43,
|
|
432
726
|
S: this,
|
|
433
727
|
C: (f, a) => f(...a)
|
|
434
728
|
});
|
|
435
|
-
yield*
|
|
729
|
+
yield* Database5.Service.flush({
|
|
436
730
|
indexes: true
|
|
437
731
|
});
|
|
438
732
|
yield* TracingService3.emitStatus({
|
|
439
733
|
message: "Creating research document..."
|
|
440
734
|
});
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
L: 47,
|
|
444
|
-
S: this,
|
|
445
|
-
A: [
|
|
446
|
-
"ObjectId.isValid(target)",
|
|
447
|
-
""
|
|
448
|
-
]
|
|
449
|
-
});
|
|
450
|
-
const targetObj = yield* DatabaseService4.resolve(DXN.fromLocalObjectId(target));
|
|
451
|
-
const doc = yield* DatabaseService4.add(Markdown3.makeDocument({
|
|
735
|
+
const target = yield* Database5.Service.resolve(ArtifactId3.toDXN(subject));
|
|
736
|
+
const object = yield* Database5.Service.add(Markdown3.make({
|
|
452
737
|
name,
|
|
453
738
|
content
|
|
454
739
|
}));
|
|
455
|
-
yield*
|
|
456
|
-
[Relation.Source]:
|
|
457
|
-
[Relation.Target]:
|
|
740
|
+
yield* Database5.Service.add(Relation.make(HasSubject.HasSubject, {
|
|
741
|
+
[Relation.Source]: object,
|
|
742
|
+
[Relation.Target]: target,
|
|
458
743
|
completedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
459
744
|
}));
|
|
460
|
-
yield*
|
|
745
|
+
yield* Database5.Service.flush({
|
|
461
746
|
indexes: true
|
|
462
747
|
});
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
content
|
|
748
|
+
log4.info("Created research document", {
|
|
749
|
+
subject,
|
|
750
|
+
object
|
|
467
751
|
}, {
|
|
468
|
-
F:
|
|
469
|
-
L:
|
|
752
|
+
F: __dxlog_file4,
|
|
753
|
+
L: 70,
|
|
470
754
|
S: this,
|
|
471
755
|
C: (f, a) => f(...a)
|
|
472
756
|
});
|
|
473
|
-
return {
|
|
757
|
+
return {
|
|
758
|
+
document: Obj5.getDXN(object).toString()
|
|
759
|
+
};
|
|
474
760
|
})
|
|
475
761
|
});
|
|
476
762
|
|
|
@@ -479,36 +765,42 @@ import * as Toolkit2 from "@effect/ai/Toolkit";
|
|
|
479
765
|
import * as AnthropicTool from "@effect/ai-anthropic/AnthropicTool";
|
|
480
766
|
import * as Array6 from "effect/Array";
|
|
481
767
|
import * as Effect10 from "effect/Effect";
|
|
768
|
+
import * as Function4 from "effect/Function";
|
|
482
769
|
import * as Layer3 from "effect/Layer";
|
|
770
|
+
import * as Option4 from "effect/Option";
|
|
483
771
|
import * as Schema10 from "effect/Schema";
|
|
772
|
+
import * as String10 from "effect/String";
|
|
484
773
|
import { AiService as AiService2, ConsolePrinter as ConsolePrinter2 } from "@dxos/ai";
|
|
485
774
|
import { AiSession as AiSession2, GenerationObserver as GenerationObserver2, createToolkit as createToolkit2, makeToolExecutionServiceFromFunctions, makeToolResolverFromFunctions } from "@dxos/assistant";
|
|
486
|
-
import {
|
|
487
|
-
import {
|
|
488
|
-
import {
|
|
775
|
+
import { Template as Template2 } from "@dxos/blueprints";
|
|
776
|
+
import { Entity as Entity2, Obj as Obj7 } from "@dxos/echo";
|
|
777
|
+
import { Database as Database7 } from "@dxos/echo";
|
|
778
|
+
import { TracingService as TracingService4, defineFunction as defineFunction8 } from "@dxos/functions";
|
|
779
|
+
import { FunctionInvocationServiceLayerTestMocked } from "@dxos/functions-runtime/testing";
|
|
780
|
+
import { Person } from "@dxos/types";
|
|
489
781
|
import { trim as trim3 } from "@dxos/util";
|
|
490
782
|
|
|
491
783
|
// src/functions/exa/exa.ts
|
|
492
|
-
import * as
|
|
493
|
-
import * as
|
|
784
|
+
import * as Effect7 from "effect/Effect";
|
|
785
|
+
import * as Schema7 from "effect/Schema";
|
|
494
786
|
import Exa from "exa-js";
|
|
495
787
|
import { CredentialsService as CredentialsService2, defineFunction as defineFunction6 } from "@dxos/functions";
|
|
496
788
|
var exa_default = defineFunction6({
|
|
497
789
|
key: "dxos.org/function/exa",
|
|
498
790
|
name: "Exa",
|
|
499
791
|
description: "Search the web for information",
|
|
500
|
-
inputSchema:
|
|
501
|
-
query:
|
|
792
|
+
inputSchema: Schema7.Struct({
|
|
793
|
+
query: Schema7.String.annotations({
|
|
502
794
|
description: "The query to search for."
|
|
503
795
|
})
|
|
504
796
|
}),
|
|
505
|
-
outputSchema:
|
|
506
|
-
handler:
|
|
797
|
+
outputSchema: Schema7.Unknown,
|
|
798
|
+
handler: Effect7.fnUntraced(function* ({ data: { query } }) {
|
|
507
799
|
const credential = yield* CredentialsService2.getCredential({
|
|
508
800
|
service: "exa.ai"
|
|
509
801
|
});
|
|
510
802
|
const exa = new Exa(credential.apiKey);
|
|
511
|
-
const context = yield*
|
|
803
|
+
const context = yield* Effect7.promise(async () => exa.searchAndContents(query, {
|
|
512
804
|
type: "auto",
|
|
513
805
|
text: {
|
|
514
806
|
maxCharacters: 3e3
|
|
@@ -520,11 +812,11 @@ var exa_default = defineFunction6({
|
|
|
520
812
|
});
|
|
521
813
|
|
|
522
814
|
// src/functions/exa/mock.ts
|
|
523
|
-
import * as
|
|
524
|
-
import * as
|
|
815
|
+
import * as Effect8 from "effect/Effect";
|
|
816
|
+
import * as Schema8 from "effect/Schema";
|
|
525
817
|
import { defineFunction as defineFunction7 } from "@dxos/functions";
|
|
526
818
|
|
|
527
|
-
// src/
|
|
819
|
+
// src/functions/exa/data/exa-search-1748337321991.ts
|
|
528
820
|
var exa_search_1748337321991_default = {
|
|
529
821
|
requestId: "324936368a74f4db978982172bc18a6c",
|
|
530
822
|
autopromptString: "AI personal knowledge management tools projects 2024",
|
|
@@ -680,7 +972,7 @@ var exa_search_1748337321991_default = {
|
|
|
680
972
|
}
|
|
681
973
|
};
|
|
682
974
|
|
|
683
|
-
// src/
|
|
975
|
+
// src/functions/exa/data/exa-search-1748337331526.ts
|
|
684
976
|
var exa_search_1748337331526_default = {
|
|
685
977
|
requestId: "0dc12e344fa649884456960ca1a54954",
|
|
686
978
|
autopromptString: "PKM software artificial intelligence integration open source projects",
|
|
@@ -903,7 +1195,7 @@ npm run tauri dev
|
|
|
903
1195
|
}
|
|
904
1196
|
};
|
|
905
1197
|
|
|
906
|
-
// src/
|
|
1198
|
+
// src/functions/exa/data/exa-search-1748337344119.ts
|
|
907
1199
|
var exa_search_1748337344119_default = {
|
|
908
1200
|
requestId: "32df0c541f9883180b35e04caece4374",
|
|
909
1201
|
autopromptString: "open source AI knowledge management projects features comparison 2024",
|
|
@@ -1002,414 +1294,133 @@ var exa_search_1748337344119_default = {
|
|
|
1002
1294
|
author: "",
|
|
1003
1295
|
score: 0.37101393938064575,
|
|
1004
1296
|
text: "SciPhi simplifies building, deploying, and optimizing Retrieval-Augmented Generation (RAG) systems, empowering developers to focus on AI innovation. Added on: Social & Email: Platform: SciPhi SciPhi simplifies building, deploying, and optimizing Retrieval-Augmented Generation (RAG) systems, empowering developers to focus on AI innovation. Added on: Social & Email: Platform: What is SciPhi? SciPhi is an open-source platform designed to simplify the building, deploying, and scaling of Retrieval-Augmented Generation (RAG) systems. It provides an end-to-end solution for developers, enabling them to focus on AI innovation without worrying about the underlying infrastructure. With tools for automated knowledge graph extraction, document and user management, and robust observability, SciPhi ensures efficient and optimized RAG system deployment. Who will use SciPhi? Developers AI Engineers Data Scientists Tech Startups Research Institutions How to use the SciPhi? Step1: Visit the SciPhi website. Step2: Sign up for an account or log in. Step3: Access the platform's dashboard. Step4: Follow guides to build and deploy your RAG system. Step5: Use tools for knowledge graph extraction and management. Step6: Optimize and monitor your system using provided observability features. SciPhi's Core Features & Benefits The Core Features of SciPhi End-to-End RAG System Deployment Automated Knowledge Graph Extraction Document and User Management Robust Observability Tools The Benefits of SciPhi Simplifies AI Development Speeds Up Deployment Time Enhances System Optimization Reduces Infrastructure Complexity SciPhi's Main Use Cases & Applications Building RAG Systems for AI Applications Deploying Knowledge Graphs Managing Large Document Repositories Optimizing AI System Performance FAQs of SciPhi SciPhi is an open-source platform designed to simplify building, deploying, and optimizing Retrieval-Augmented Generation (RAG) systems. SciPhi is intended for developers, AI engineers, data scientists, tech startups, and research institutions. Core features include end-to-end RAG system deployment, automated knowledge graph extraction, document and user management, and robust observability tools. Visit the SciPhi website, sign up for an account, and follow the guides to build and deploy your RAG system. SciPhi supports web platforms. SciPhi simplifies AI development, speeds up deployment time, enhances system optimization, and reduces infrastructure complexity. Yes, alternatives include LangChain, LlamaIndex, Haystack, and Flower. SciPhi supports building RAG systems for AI applications, deploying knowledge graphs, managing large document repositories, and optimizing AI system performance. You can reach out to their support team via their support email provided on the website. SciPhi offers both free and paid plans. Details on pricing can be found on their website. SciPhi Company Information Website: https://www.sciphi.ai Company Name: SciPhi Support Email: [ema",
|
|
1005
|
-
image: "https://cdn-image.creati.ai/ai-tools/product-image/sciphi.webp",
|
|
1006
|
-
favicon: "https://cdn-image.creati.ai/image/Creatiai.ico"
|
|
1007
|
-
},
|
|
1008
|
-
{
|
|
1009
|
-
id: "https://helpjuice.com/blog/open-source-knowledge-base",
|
|
1010
|
-
title: "The 12 Best Open Source Knowledge Base Software for 2024",
|
|
1011
|
-
url: "https://helpjuice.com/blog/open-source-knowledge-base",
|
|
1012
|
-
author: "Zeeshan Khan",
|
|
1013
|
-
text: "\n \n \n \n \n At Helpjuice / \n \n #Software & Alternatives\n May 15 2025 \n 11m read \n \n \n \n \n On the hunt for the perfect knowledge base software that\u2019s open source? This post will walk you through the best options for your business. \n \n \n \n \n There\u2019s no denying that a knowledge base can make a major impact on your organization.\xA0 Whether it's to help provide better support to your customers or to enable your employees to find the information they need to do their job, a finely-tuned knowledge base can make all the difference when it comes to how knowledge and information flows through your business. And with plenty of options on the market out there, there\u2019s certainly no shortage of open source knowledge base software. But how can you tell you\u2019re not investing time into installing and learning new software that your team won't use anyway? How can you avoid the time and effort put into an open source option that you later determine to not be a good fit for your needs?\xA0 It\u2019s simple\u2014do a little research beforehand. We know, we know\u2014you don\u2019t have endless time to invest in that kind of thing (what with a business to run and all). That\u2019s why we\u2019ve created a helpful list of the must-consider open source knowledge base software that companies of all niches, industries, and sizes should consider.\xA0 We\u2019re even throwing in a little helpful knowledge that should equip you with the information needed to choose the right software for you\u2014like what knowledge base software is in the first place, the benefits of open source software, and how to address your unique needs as a company to choose the right software for you.\xA0 Want to skip ahead on some of the basics of open-source knowledge base software?\xA0 Be our guest.\xA0 The best open source knowledge base software includes: \n BookStack \n OpenKM \n myBase \n eXo \n PHPKB \n Documize \n DocuWiki \n phpMyFAQ \n MediaWiki \n xWiki \n TWiki \n TiddlyWiki \n What is an Open Source Knowledge Base? Before we dive into which open-source knowledge base software you should consider for your business, we should probably ensure we\u2019re on the same page about what exactly open-source knowledge base software is.\xA0 First things first, let\u2019s start with the term knowledge base. A knowledge base is a central place that allows structured storage of information where users can search for and access this information. \xA0Knowledge base software should be the key tool that helps make this process seamless, simplified, and efficient. Knowledge base software is designed to help you create and manage your knowledge base to the best of your ability. this usually includes setting up the knowledge base architecture, creating and editing documentation, searching, and analyzing your knowledge base, and more. Ideally, this is the irreplaceable piece of the puzzle that operates your entire knowledge management system that helps orchestrate, manage, and optimize the flow of knowledge within your organization.\xA0 That part seems pretty clear, right? Next, we\u2019ll move on to",
|
|
1014
|
-
image: "https://static.helpjuice.com/helpjuice_production/uploads/upload/image/4752/direct/1636499945090-Open%20Source%20Knowledge%20Base%20Software.jpg",
|
|
1015
|
-
favicon: "https://static.helpjuice.com/assets/favicon-32x32-161f2153235b710a8ed7b9233ed6b195936bdb57bf1310e720f7fea79547cf9d.png"
|
|
1016
|
-
}
|
|
1017
|
-
],
|
|
1018
|
-
costDollars: {
|
|
1019
|
-
total: 0.015,
|
|
1020
|
-
search: {
|
|
1021
|
-
neural: 5e-3
|
|
1022
|
-
},
|
|
1023
|
-
contents: {
|
|
1024
|
-
text: 0.01
|
|
1025
|
-
}
|
|
1026
|
-
}
|
|
1027
|
-
};
|
|
1028
|
-
|
|
1029
|
-
// src/testing/data/index.ts
|
|
1030
|
-
var SEARCH_RESULTS = [
|
|
1031
|
-
exa_search_1748337321991_default,
|
|
1032
|
-
exa_search_1748337331526_default,
|
|
1033
|
-
exa_search_1748337344119_default
|
|
1034
|
-
];
|
|
1035
|
-
|
|
1036
|
-
// src/functions/exa/mock.ts
|
|
1037
|
-
var mock_default = defineFunction7({
|
|
1038
|
-
key: "dxos.org/function/exa-mock",
|
|
1039
|
-
name: "Exa mock",
|
|
1040
|
-
description: "Search the web for information",
|
|
1041
|
-
inputSchema: Schema7.Struct({
|
|
1042
|
-
query: Schema7.String.annotations({
|
|
1043
|
-
description: "The query to search for."
|
|
1044
|
-
})
|
|
1045
|
-
}),
|
|
1046
|
-
outputSchema: Schema7.Unknown,
|
|
1047
|
-
handler: Effect7.fnUntraced(function* ({ data: { query } }) {
|
|
1048
|
-
const result = SEARCH_RESULTS.reduce((closest, current) => {
|
|
1049
|
-
if (!current.autopromptString) {
|
|
1050
|
-
return closest;
|
|
1051
|
-
}
|
|
1052
|
-
if (!closest) {
|
|
1053
|
-
return current;
|
|
1054
|
-
}
|
|
1055
|
-
const dist1 = levenshteinDistance(query, current.autopromptString);
|
|
1056
|
-
const dist2 = levenshteinDistance(query, closest.autopromptString || "");
|
|
1057
|
-
const weight1 = dist1 / Math.max(query.length, current.autopromptString.length);
|
|
1058
|
-
const weight2 = dist2 / Math.max(query.length, closest.autopromptString?.length || 0);
|
|
1059
|
-
return weight1 < weight2 ? current : closest;
|
|
1060
|
-
}, null);
|
|
1061
|
-
return result;
|
|
1062
|
-
})
|
|
1063
|
-
});
|
|
1064
|
-
var levenshteinDistance = (str1, str2) => {
|
|
1065
|
-
const m = str1.length;
|
|
1066
|
-
const n = str2.length;
|
|
1067
|
-
const dp = Array(m + 1).fill(null).map(() => Array(n + 1).fill(0));
|
|
1068
|
-
for (let i = 0; i <= m; i++) {
|
|
1069
|
-
dp[i][0] = i;
|
|
1070
|
-
}
|
|
1071
|
-
for (let j = 0; j <= n; j++) {
|
|
1072
|
-
dp[0][j] = j;
|
|
1073
|
-
}
|
|
1074
|
-
for (let i = 1; i <= m; i++) {
|
|
1075
|
-
for (let j = 1; j <= n; j++) {
|
|
1076
|
-
dp[i][j] = str1[i - 1] === str2[j - 1] ? dp[i - 1][j - 1] : Math.min(dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]) + 1;
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
1079
|
-
return dp[m][n];
|
|
1080
|
-
};
|
|
1081
|
-
|
|
1082
|
-
// src/functions/research/graph.ts
|
|
1083
|
-
import * as Tool from "@effect/ai/Tool";
|
|
1084
|
-
import * as Toolkit from "@effect/ai/Toolkit";
|
|
1085
|
-
import * as Context from "effect/Context";
|
|
1086
|
-
import * as Effect8 from "effect/Effect";
|
|
1087
|
-
import * as Function3 from "effect/Function";
|
|
1088
|
-
import * as Option3 from "effect/Option";
|
|
1089
|
-
import * as Schema8 from "effect/Schema";
|
|
1090
|
-
import * as SchemaAST from "effect/SchemaAST";
|
|
1091
|
-
import { Obj as Obj3 } from "@dxos/echo";
|
|
1092
|
-
import { Filter, Query } from "@dxos/echo";
|
|
1093
|
-
import { EntityKind, ObjectId as ObjectId2, ReferenceAnnotationId, RelationSourceDXNId, RelationSourceId, RelationTargetDXNId, RelationTargetId, create, getEntityKind, getSchemaDXN, getSchemaTypename, getTypeAnnotation, getTypeIdentifierAnnotation } from "@dxos/echo/internal";
|
|
1094
|
-
import { isEncodedReference } from "@dxos/echo-protocol";
|
|
1095
|
-
import { mapAst } from "@dxos/effect";
|
|
1096
|
-
import { ContextQueueService, DatabaseService as DatabaseService5 } from "@dxos/functions";
|
|
1097
|
-
import { DXN as DXN2 } from "@dxos/keys";
|
|
1098
|
-
import { log as log4 } from "@dxos/log";
|
|
1099
|
-
import { deepMapValues, isNonNullable, trim as trim2 } from "@dxos/util";
|
|
1100
|
-
var __dxlog_file4 = "/__w/dxos/dxos/packages/core/assistant-toolkit/src/functions/research/graph.ts";
|
|
1101
|
-
var Subgraph = Schema8.Struct({
|
|
1102
|
-
/** Objects and relations. */
|
|
1103
|
-
objects: Schema8.Array(Schema8.Any)
|
|
1104
|
-
});
|
|
1105
|
-
var findRelatedSchema = async (db, anchor) => {
|
|
1106
|
-
const allSchemas = [
|
|
1107
|
-
...db.graph.schemaRegistry.schemas
|
|
1108
|
-
];
|
|
1109
|
-
return allSchemas.filter((schema) => {
|
|
1110
|
-
if (getTypeAnnotation(schema)?.kind !== EntityKind.Relation) {
|
|
1111
|
-
return false;
|
|
1112
|
-
}
|
|
1113
|
-
return isSchemaAddressableByDxn(anchor, DXN2.parse(getTypeAnnotation(schema).sourceSchema)) || isSchemaAddressableByDxn(anchor, DXN2.parse(getTypeAnnotation(schema).targetSchema));
|
|
1114
|
-
}).map((schema) => ({
|
|
1115
|
-
schema,
|
|
1116
|
-
kind: "relation"
|
|
1117
|
-
}));
|
|
1118
|
-
};
|
|
1119
|
-
var isSchemaAddressableByDxn = (schema, dxn) => {
|
|
1120
|
-
if (getTypeIdentifierAnnotation(schema) === dxn.toString()) {
|
|
1121
|
-
return true;
|
|
1122
|
-
}
|
|
1123
|
-
const t = dxn.asTypeDXN();
|
|
1124
|
-
if (t) {
|
|
1125
|
-
return t.type === getSchemaTypename(schema);
|
|
1126
|
-
}
|
|
1127
|
-
return false;
|
|
1128
|
-
};
|
|
1129
|
-
var LocalSearchToolkit = Toolkit.make(Tool.make("search_local_search", {
|
|
1130
|
-
description: "Search the local database for information using a vector index",
|
|
1131
|
-
parameters: {
|
|
1132
|
-
query: Schema8.String.annotations({
|
|
1133
|
-
description: "The query to search for. Could be a question or a topic or a set of keywords."
|
|
1134
|
-
})
|
|
1135
|
-
},
|
|
1136
|
-
success: Schema8.Unknown,
|
|
1137
|
-
failure: Schema8.Never,
|
|
1138
|
-
dependencies: [
|
|
1139
|
-
DatabaseService5
|
|
1140
|
-
]
|
|
1141
|
-
}));
|
|
1142
|
-
var LocalSearchHandler = LocalSearchToolkit.toLayer({
|
|
1143
|
-
search_local_search: Effect8.fn(function* ({ query }) {
|
|
1144
|
-
const { objects } = yield* DatabaseService5.runQuery(Query.select(Filter.text(query, {
|
|
1145
|
-
type: "vector"
|
|
1146
|
-
})));
|
|
1147
|
-
const results = [
|
|
1148
|
-
...objects
|
|
1149
|
-
];
|
|
1150
|
-
const option = yield* Effect8.serviceOption(ContextQueueService);
|
|
1151
|
-
if (Option3.isSome(option)) {
|
|
1152
|
-
const queueObjects = yield* Effect8.promise(() => option.value.queue.queryObjects());
|
|
1153
|
-
results.push(...queueObjects);
|
|
1154
|
-
}
|
|
1155
|
-
return trim2`
|
|
1156
|
-
<local_context>
|
|
1157
|
-
${JSON.stringify(results, null, 2)}
|
|
1158
|
-
</local_context>
|
|
1159
|
-
`;
|
|
1160
|
-
})
|
|
1161
|
-
});
|
|
1162
|
-
var GraphWriterSchema = class extends Context.Tag("@dxos/assistant/GraphWriterSchema")() {
|
|
1163
|
-
};
|
|
1164
|
-
var makeGraphWriterToolkit = ({ schema }) => {
|
|
1165
|
-
return Toolkit.make(Tool.make("graph_writer", {
|
|
1166
|
-
description: "Write to the local graph database",
|
|
1167
|
-
parameters: createExtractionSchema(schema).fields,
|
|
1168
|
-
success: Schema8.Unknown,
|
|
1169
|
-
failure: Schema8.Never,
|
|
1170
|
-
dependencies: [
|
|
1171
|
-
DatabaseService5,
|
|
1172
|
-
ContextQueueService
|
|
1173
|
-
]
|
|
1174
|
-
}).annotateContext(Context.make(GraphWriterSchema, {
|
|
1175
|
-
schema
|
|
1176
|
-
})));
|
|
1177
|
-
};
|
|
1178
|
-
var makeGraphWriterHandler = (toolkit, { onAppend } = {}) => {
|
|
1179
|
-
const { schema } = Context.get(toolkit.tools.graph_writer.annotations, GraphWriterSchema);
|
|
1180
|
-
return toolkit.toLayer({
|
|
1181
|
-
graph_writer: Effect8.fn(function* (input) {
|
|
1182
|
-
const { db } = yield* DatabaseService5;
|
|
1183
|
-
const { queue } = yield* ContextQueueService;
|
|
1184
|
-
const data = yield* Effect8.promise(() => sanitizeObjects(schema, input, db, queue));
|
|
1185
|
-
yield* Effect8.promise(() => queue.append(data));
|
|
1186
|
-
const dxns = data.map((obj) => Obj3.getDXN(obj));
|
|
1187
|
-
onAppend?.(dxns);
|
|
1188
|
-
return dxns;
|
|
1189
|
-
})
|
|
1190
|
-
});
|
|
1191
|
-
};
|
|
1192
|
-
var createExtractionSchema = (types) => {
|
|
1193
|
-
return Schema8.Struct({
|
|
1194
|
-
...Object.fromEntries(types.map(preprocessSchema).map((schema, index) => [
|
|
1195
|
-
`objects_${getSanitizedSchemaName(types[index])}`,
|
|
1196
|
-
Schema8.optional(Schema8.Array(schema)).annotations({
|
|
1197
|
-
description: `The objects of type: ${getSchemaDXN(types[index])?.asTypeDXN().type}. ${SchemaAST.getDescriptionAnnotation(types[index].ast).pipe(Option3.getOrElse(() => ""))}`
|
|
1198
|
-
})
|
|
1199
|
-
]))
|
|
1200
|
-
});
|
|
1201
|
-
};
|
|
1202
|
-
var getSanitizedSchemaName = (schema) => {
|
|
1203
|
-
return getSchemaDXN(schema).asTypeDXN().type.replaceAll(/[^a-zA-Z0-9]+/g, "_");
|
|
1204
|
-
};
|
|
1205
|
-
var sanitizeObjects = async (types, data, db, queue) => {
|
|
1206
|
-
const entries = types.map((type) => data[`objects_${getSanitizedSchemaName(type)}`]?.map((object) => ({
|
|
1207
|
-
data: object,
|
|
1208
|
-
schema: type
|
|
1209
|
-
})) ?? []).flat();
|
|
1210
|
-
const idMap = /* @__PURE__ */ new Map();
|
|
1211
|
-
const existingIds = /* @__PURE__ */ new Set();
|
|
1212
|
-
const enitties = /* @__PURE__ */ new Map();
|
|
1213
|
-
const resolveId = (id) => {
|
|
1214
|
-
if (ObjectId2.isValid(id)) {
|
|
1215
|
-
existingIds.add(id);
|
|
1216
|
-
return DXN2.fromLocalObjectId(id);
|
|
1217
|
-
}
|
|
1218
|
-
const mappedId = idMap.get(id);
|
|
1219
|
-
if (mappedId) {
|
|
1220
|
-
return DXN2.fromLocalObjectId(mappedId);
|
|
1221
|
-
}
|
|
1222
|
-
return void 0;
|
|
1223
|
-
};
|
|
1224
|
-
const res = entries.map((entry) => {
|
|
1225
|
-
if (ObjectId2.isValid(entry.data.id)) {
|
|
1226
|
-
return entry;
|
|
1227
|
-
}
|
|
1228
|
-
idMap.set(entry.data.id, ObjectId2.random());
|
|
1229
|
-
entry.data.id = idMap.get(entry.data.id);
|
|
1230
|
-
return entry;
|
|
1231
|
-
}).map((entry) => {
|
|
1232
|
-
const data2 = deepMapValues(entry.data, (value, recurse) => {
|
|
1233
|
-
if (isEncodedReference(value)) {
|
|
1234
|
-
const ref = value["/"];
|
|
1235
|
-
const id = resolveId(ref);
|
|
1236
|
-
if (id) {
|
|
1237
|
-
return {
|
|
1238
|
-
"/": id.toString()
|
|
1239
|
-
};
|
|
1240
|
-
} else {
|
|
1241
|
-
return {
|
|
1242
|
-
"/": `search:?q=${encodeURIComponent(ref)}`
|
|
1243
|
-
};
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
return recurse(value);
|
|
1247
|
-
});
|
|
1248
|
-
if (getEntityKind(entry.schema) === "relation") {
|
|
1249
|
-
const sourceDxn = resolveId(data2.source);
|
|
1250
|
-
if (!sourceDxn) {
|
|
1251
|
-
log4.warn("source not found", {
|
|
1252
|
-
source: data2.source
|
|
1253
|
-
}, {
|
|
1254
|
-
F: __dxlog_file4,
|
|
1255
|
-
L: 281,
|
|
1256
|
-
S: void 0,
|
|
1257
|
-
C: (f, a) => f(...a)
|
|
1258
|
-
});
|
|
1259
|
-
}
|
|
1260
|
-
const targetDxn = resolveId(data2.target);
|
|
1261
|
-
if (!targetDxn) {
|
|
1262
|
-
log4.warn("target not found", {
|
|
1263
|
-
target: data2.target
|
|
1264
|
-
}, {
|
|
1265
|
-
F: __dxlog_file4,
|
|
1266
|
-
L: 285,
|
|
1267
|
-
S: void 0,
|
|
1268
|
-
C: (f, a) => f(...a)
|
|
1269
|
-
});
|
|
1270
|
-
}
|
|
1271
|
-
delete data2.source;
|
|
1272
|
-
delete data2.target;
|
|
1273
|
-
data2[RelationSourceDXNId] = sourceDxn;
|
|
1274
|
-
data2[RelationTargetDXNId] = targetDxn;
|
|
1275
|
-
}
|
|
1276
|
-
return {
|
|
1277
|
-
data: data2,
|
|
1278
|
-
schema: entry.schema
|
|
1279
|
-
};
|
|
1280
|
-
}).filter((object) => !existingIds.has(object.data.id));
|
|
1281
|
-
const { objects: dbObjects } = await db.query(Query.select(Filter.ids(...existingIds))).run();
|
|
1282
|
-
const queueObjects = await queue?.getObjectsById([
|
|
1283
|
-
...existingIds
|
|
1284
|
-
]) ?? [];
|
|
1285
|
-
const objects = [
|
|
1286
|
-
...dbObjects,
|
|
1287
|
-
...queueObjects
|
|
1288
|
-
].filter(isNonNullable);
|
|
1289
|
-
log4.info("objects", {
|
|
1290
|
-
dbObjects,
|
|
1291
|
-
queueObjects,
|
|
1292
|
-
existingIds
|
|
1293
|
-
}, {
|
|
1294
|
-
F: __dxlog_file4,
|
|
1295
|
-
L: 306,
|
|
1296
|
-
S: void 0,
|
|
1297
|
-
C: (f, a) => f(...a)
|
|
1298
|
-
});
|
|
1299
|
-
const missing = Array.from(existingIds).filter((id) => !objects.some((object) => object.id === id));
|
|
1300
|
-
if (missing.length > 0) {
|
|
1301
|
-
throw new Error(`Object IDs do not point to existing objects: ${missing.join(", ")}`);
|
|
1302
|
-
}
|
|
1303
|
-
return res.flatMap(({ data: data2, schema }) => {
|
|
1304
|
-
let skip = false;
|
|
1305
|
-
if (RelationSourceDXNId in data2) {
|
|
1306
|
-
const id = data2[RelationSourceDXNId].asEchoDXN()?.echoId;
|
|
1307
|
-
const obj = objects.find((object) => object.id === id) ?? enitties.get(id);
|
|
1308
|
-
if (obj) {
|
|
1309
|
-
delete data2[RelationSourceDXNId];
|
|
1310
|
-
data2[RelationSourceId] = obj;
|
|
1311
|
-
} else {
|
|
1312
|
-
skip = true;
|
|
1313
|
-
}
|
|
1314
|
-
}
|
|
1315
|
-
if (RelationTargetDXNId in data2) {
|
|
1316
|
-
const id = data2[RelationTargetDXNId].asEchoDXN()?.echoId;
|
|
1317
|
-
const obj = objects.find((object) => object.id === id) ?? enitties.get(id);
|
|
1318
|
-
if (obj) {
|
|
1319
|
-
delete data2[RelationTargetDXNId];
|
|
1320
|
-
data2[RelationTargetId] = obj;
|
|
1321
|
-
} else {
|
|
1322
|
-
skip = true;
|
|
1323
|
-
}
|
|
1297
|
+
image: "https://cdn-image.creati.ai/ai-tools/product-image/sciphi.webp",
|
|
1298
|
+
favicon: "https://cdn-image.creati.ai/image/Creatiai.ico"
|
|
1299
|
+
},
|
|
1300
|
+
{
|
|
1301
|
+
id: "https://helpjuice.com/blog/open-source-knowledge-base",
|
|
1302
|
+
title: "The 12 Best Open Source Knowledge Base Software for 2024",
|
|
1303
|
+
url: "https://helpjuice.com/blog/open-source-knowledge-base",
|
|
1304
|
+
author: "Zeeshan Khan",
|
|
1305
|
+
text: "\n \n \n \n \n At Helpjuice / \n \n #Software & Alternatives\n May 15 2025 \n 11m read \n \n \n \n \n On the hunt for the perfect knowledge base software that\u2019s open source? This post will walk you through the best options for your business. \n \n \n \n \n There\u2019s no denying that a knowledge base can make a major impact on your organization.\xA0 Whether it's to help provide better support to your customers or to enable your employees to find the information they need to do their job, a finely-tuned knowledge base can make all the difference when it comes to how knowledge and information flows through your business. And with plenty of options on the market out there, there\u2019s certainly no shortage of open source knowledge base software. But how can you tell you\u2019re not investing time into installing and learning new software that your team won't use anyway? How can you avoid the time and effort put into an open source option that you later determine to not be a good fit for your needs?\xA0 It\u2019s simple\u2014do a little research beforehand. We know, we know\u2014you don\u2019t have endless time to invest in that kind of thing (what with a business to run and all). That\u2019s why we\u2019ve created a helpful list of the must-consider open source knowledge base software that companies of all niches, industries, and sizes should consider.\xA0 We\u2019re even throwing in a little helpful knowledge that should equip you with the information needed to choose the right software for you\u2014like what knowledge base software is in the first place, the benefits of open source software, and how to address your unique needs as a company to choose the right software for you.\xA0 Want to skip ahead on some of the basics of open-source knowledge base software?\xA0 Be our guest.\xA0 The best open source knowledge base software includes: \n BookStack \n OpenKM \n myBase \n eXo \n PHPKB \n Documize \n DocuWiki \n phpMyFAQ \n MediaWiki \n xWiki \n TWiki \n TiddlyWiki \n What is an Open Source Knowledge Base? Before we dive into which open-source knowledge base software you should consider for your business, we should probably ensure we\u2019re on the same page about what exactly open-source knowledge base software is.\xA0 First things first, let\u2019s start with the term knowledge base. A knowledge base is a central place that allows structured storage of information where users can search for and access this information. \xA0Knowledge base software should be the key tool that helps make this process seamless, simplified, and efficient. Knowledge base software is designed to help you create and manage your knowledge base to the best of your ability. this usually includes setting up the knowledge base architecture, creating and editing documentation, searching, and analyzing your knowledge base, and more. Ideally, this is the irreplaceable piece of the puzzle that operates your entire knowledge management system that helps orchestrate, manage, and optimize the flow of knowledge within your organization.\xA0 That part seems pretty clear, right? Next, we\u2019ll move on to",
|
|
1306
|
+
image: "https://static.helpjuice.com/helpjuice_production/uploads/upload/image/4752/direct/1636499945090-Open%20Source%20Knowledge%20Base%20Software.jpg",
|
|
1307
|
+
favicon: "https://static.helpjuice.com/assets/favicon-32x32-161f2153235b710a8ed7b9233ed6b195936bdb57bf1310e720f7fea79547cf9d.png"
|
|
1324
1308
|
}
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1309
|
+
],
|
|
1310
|
+
costDollars: {
|
|
1311
|
+
total: 0.015,
|
|
1312
|
+
search: {
|
|
1313
|
+
neural: 5e-3
|
|
1314
|
+
},
|
|
1315
|
+
contents: {
|
|
1316
|
+
text: 0.01
|
|
1331
1317
|
}
|
|
1332
|
-
|
|
1333
|
-
});
|
|
1318
|
+
}
|
|
1334
1319
|
};
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1320
|
+
|
|
1321
|
+
// src/functions/exa/data/index.ts
|
|
1322
|
+
var SEARCH_RESULTS = [
|
|
1323
|
+
exa_search_1748337321991_default,
|
|
1324
|
+
exa_search_1748337331526_default,
|
|
1325
|
+
exa_search_1748337344119_default
|
|
1326
|
+
];
|
|
1327
|
+
|
|
1328
|
+
// src/functions/exa/mock.ts
|
|
1329
|
+
var mock_default = defineFunction7({
|
|
1330
|
+
key: "dxos.org/function/exa-mock",
|
|
1331
|
+
name: "Exa mock",
|
|
1332
|
+
description: "Search the web for information",
|
|
1333
|
+
inputSchema: Schema8.Struct({
|
|
1334
|
+
query: Schema8.String.annotations({
|
|
1335
|
+
description: "The query to search for."
|
|
1336
|
+
})
|
|
1337
|
+
}),
|
|
1338
|
+
outputSchema: Schema8.Unknown,
|
|
1339
|
+
handler: Effect8.fnUntraced(function* ({ data: { query } }) {
|
|
1340
|
+
const result = SEARCH_RESULTS.reduce((closest, current) => {
|
|
1341
|
+
if (!current.autopromptString) {
|
|
1342
|
+
return closest;
|
|
1343
|
+
}
|
|
1344
|
+
if (!closest) {
|
|
1345
|
+
return current;
|
|
1346
|
+
}
|
|
1347
|
+
const dist1 = levenshteinDistance(query, current.autopromptString);
|
|
1348
|
+
const dist2 = levenshteinDistance(query, closest.autopromptString || "");
|
|
1349
|
+
const weight1 = dist1 / Math.max(query.length, current.autopromptString.length);
|
|
1350
|
+
const weight2 = dist2 / Math.max(query.length, closest.autopromptString?.length || 0);
|
|
1351
|
+
return weight1 < weight2 ? current : closest;
|
|
1352
|
+
}, null);
|
|
1353
|
+
return result;
|
|
1354
|
+
})
|
|
1339
1355
|
});
|
|
1340
|
-
var
|
|
1341
|
-
const
|
|
1342
|
-
const
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1356
|
+
var levenshteinDistance = (str1, str2) => {
|
|
1357
|
+
const m = str1.length;
|
|
1358
|
+
const n = str2.length;
|
|
1359
|
+
const dp = Array(m + 1).fill(null).map(() => Array(n + 1).fill(0));
|
|
1360
|
+
for (let i = 0; i <= m; i++) {
|
|
1361
|
+
dp[i][0] = i;
|
|
1362
|
+
}
|
|
1363
|
+
for (let j = 0; j <= n; j++) {
|
|
1364
|
+
dp[0][j] = j;
|
|
1365
|
+
}
|
|
1366
|
+
for (let i = 1; i <= m; i++) {
|
|
1367
|
+
for (let j = 1; j <= n; j++) {
|
|
1368
|
+
dp[i][j] = str1[i - 1] === str2[j - 1] ? dp[i - 1][j - 1] : Math.min(dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]) + 1;
|
|
1349
1369
|
}
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
return Schema8.make(mapAst(schema.ast, (ast) => go(ast))).pipe(Schema8.omit("id"), Schema8.extend(Schema8.Struct({
|
|
1353
|
-
id: Schema8.String.annotations({
|
|
1354
|
-
description: "The id of this object. Come up with a unique id based on your judgement."
|
|
1355
|
-
})
|
|
1356
|
-
})), isRelationSchema ? Schema8.extend(Schema8.Struct({
|
|
1357
|
-
source: Schema8.String.annotations({
|
|
1358
|
-
description: "The id of the source object for this relation."
|
|
1359
|
-
}),
|
|
1360
|
-
target: Schema8.String.annotations({
|
|
1361
|
-
description: "The id of the target object for this relation."
|
|
1362
|
-
})
|
|
1363
|
-
})) : Function3.identity);
|
|
1370
|
+
}
|
|
1371
|
+
return dp[m][n];
|
|
1364
1372
|
};
|
|
1365
1373
|
|
|
1366
|
-
// raw-loader:/__w/dxos/dxos/packages/core/assistant-toolkit/src/functions/research/instructions-research.tpl?raw
|
|
1367
|
-
var instructions_research_default = "You are the Research Agent.\n\nThe Research Agent is an expert assistant that conducts in-depth research using real-time web search.\nThe Research Agent outputs results in a structured format matching the schema provided.\n\nThe Research Agent is equipped with the ability to:\n\n- Generate precise and effective search queries \n- Request web pages by query (through a `web_search` tool)\n- Read the full content of retrieved pages\n- Synthesize accurate, clear, and structured answers using reliable information from the retrieved content\n- Search the local database for information using a vector index (through a `local_search` tool)\n\nThe Research Agent always follows these principles:\n\n- Relevance First: The Research Agent only returns facts supported by content in retrieved web pages. The Research Agent never fabricates or guesses information.\n- Summarize, Don't Copy: The Research Agent synthesizes and rephrases content in its own words. The Research Agent quotes only when necessary.\n- Multiple Sources: The Research Agent cross-references at least 2 sources before drawing conclusions, unless the information is directly stated and non-controversial.\n- Transparency: The Research Agent mentions which sources were used and explains how it arrived at conclusions.\n- Accuracy Over Brevity: The Research Agent prefers detailed, technically accurate explanations over shallow summaries.\n- The Research Agent admits uncertainty rather than misleading.\n- The Research Agent picks the most concrete schema types for extracted information.\n- The Research Agent fills schema fields completely with information it is confident about, and omits fields it is not confident about.\n- When outputting results, the Research Agent adds extra data that fits the schema even if not directly related to the user's question.\n- The Research Agent creates relations and references between new objects found and what's already in the database.\n- The Research Agent does not create objects that are already in the database.\n- The Research Agent re-uses existing object IDs as references when enriching existing objects.\n- The Research Agent ALWAYS calls the `graph_writer` at the end to save the data. This conversation will be deleted, so only the data written to the graph will be preserved.\n\nThe Research Agent may be asked for:\n\n- Technical explanations\n- Literature reviews \n- Comparisons\n- Emerging trends\n- Implementation strategies\n\nThe Research Agent begins by interpreting the user's request, then:\n\nThe Research Agent breaks it into sub-questions (if applicable).\n\nFor each sub-question, the Research Agent generates a clear, concise web search query.\n\nThe Research Agent uses `web_search`(query) to retrieve information.\n\nThe Research Agent extracts and synthesizes relevant answers.\n\nThe Research Agent's output includes:\n\n- A clear, structured answer to the user's question\n- A citation list or link list of sources used\n\nOptionally, the Research Agent provides follow-up suggestions or questions for deeper inquiry.\n\nHere's how the Research Agent operates:\n\n1. The Research Agent analyzes the user's request and identifies key topics to search for (3 or more), printing them out.\n2. The Research Agent performs a web search for each topic.\n3. The Research Agent reads and analyzes results, cross references information from multiple sources, and represents conflicting information as ranges of possible values.\n\n4. The Research Agent searches the local database for information using a vector index that might link to the user's question.\n6. The Research Agent creates relations and references between new objects and existing database objects when related, using existing object IDs as references.\n7. The Research Agent selects the most concrete schema types for extracted information, using multiple types as needed, and prints its decision and reasoning.\n5. The Research Agent creates a clear, structured answer to the user's question.\n8. The Research Agent submits results using the specific schema.\n\nIMPORTANT:\n\n- The Research Agent always runs the `local_search` tool to search the local database at least once before submitting results.\n- The Research Agent does not create objects that already exist in the database.\n- Ids that are not in the database are human-readable strings like `ivan_zhao_1`.\n\nStatus reporting:\n\nThe Research Agent reports its status frequently using the `<status>` tags: <status>Searching for Google Founders</status>\nThe Research Agent reports its status in-between each tool call and before submitting results.\n\n<example>\n\nBased on my research, I can now provide information about Google and it's founders.\n\nThe following objects are already in the database, I will not submit them again, but I'll re-use their IDs as references:\n\n- 01JWRDEHPB5TT2JQQQC15038BT Google\n- 01JWRDEHPA14CYW2NW9FAH6DJJ Larry Page\n- 01JWRDEHPBN0BBJP57B9S108W6 Sergey Brin\n\nI will use the following schema to construct new objects:\n\n- type:dxos.org/type/Organization for Alphabet Inc.\n- type:dxos.org/type/Person for Ivan Zhao\n- type:dxos.org/type/Person for Simon Last\n- dxn:type:dxos.org/relation/Employer for Ivan's employer\n- dxn:type:dxos.org/relation/Employer for Simon's employer\n\n<status>Formatting results</status>\n\n</example>";
|
|
1368
|
-
|
|
1369
1374
|
// src/functions/research/research-graph.ts
|
|
1370
1375
|
import * as Effect9 from "effect/Effect";
|
|
1371
1376
|
import * as Layer2 from "effect/Layer";
|
|
1372
1377
|
import * as Schema9 from "effect/Schema";
|
|
1373
|
-
import { Obj as
|
|
1378
|
+
import { Obj as Obj6, Query as Query2, Ref as Ref2, Type as Type3 } from "@dxos/echo";
|
|
1379
|
+
import { Database as Database6 } from "@dxos/echo";
|
|
1380
|
+
import { SystemTypeAnnotation } from "@dxos/echo/internal";
|
|
1374
1381
|
import { Queue } from "@dxos/echo-db";
|
|
1375
|
-
import { ContextQueueService as ContextQueueService2,
|
|
1382
|
+
import { ContextQueueService as ContextQueueService2, QueueService } from "@dxos/functions";
|
|
1376
1383
|
var ResearchGraph = Schema9.Struct({
|
|
1377
|
-
queue:
|
|
1378
|
-
}).pipe(
|
|
1384
|
+
queue: Type3.Ref(Queue)
|
|
1385
|
+
}).pipe(Type3.object({
|
|
1379
1386
|
typename: "dxos.org/type/ResearchGraph",
|
|
1380
1387
|
version: "0.1.0"
|
|
1381
|
-
}));
|
|
1388
|
+
}), SystemTypeAnnotation.set(true));
|
|
1382
1389
|
var queryResearchGraph = Effect9.fn("queryResearchGraph")(function* () {
|
|
1383
|
-
const
|
|
1390
|
+
const objects = yield* Database6.Service.runQuery(Query2.type(ResearchGraph));
|
|
1384
1391
|
return objects.at(0);
|
|
1385
1392
|
});
|
|
1386
1393
|
var createResearchGraph = Effect9.fn("createResearchGraph")(function* () {
|
|
1387
1394
|
const queue = yield* QueueService.createQueue();
|
|
1388
|
-
return yield*
|
|
1395
|
+
return yield* Database6.Service.add(Obj6.make(ResearchGraph, {
|
|
1389
1396
|
queue: Ref2.fromDXN(queue.dxn)
|
|
1390
1397
|
}));
|
|
1391
1398
|
});
|
|
1392
1399
|
var contextQueueLayerFromResearchGraph = Layer2.unwrapEffect(Effect9.gen(function* () {
|
|
1393
1400
|
const researchGraph = (yield* queryResearchGraph()) ?? (yield* createResearchGraph());
|
|
1394
|
-
const researchQueue = yield*
|
|
1401
|
+
const researchQueue = yield* Database6.Service.load(researchGraph.queue);
|
|
1395
1402
|
return ContextQueueService2.layer(researchQueue);
|
|
1396
1403
|
}));
|
|
1397
1404
|
|
|
1405
|
+
// raw-loader:/__w/dxos/dxos/packages/core/assistant-toolkit/src/functions/research/research-instructions.tpl?raw
|
|
1406
|
+
var research_instructions_default = "You are the Research Agent.\n\nThe Research Agent is an expert assistant that conducts in-depth research using real-time web search.\nThe Research Agent outputs results in a structured format matching the schema provided.\n\nThe Research Agent is equipped with the ability to:\n\n- Generate precise and effective search queries \n- Request web pages by query.\n- Synthesize accurate, clear, and structured answers using reliable information from the retrieved content\n{{#if entityExtraction}}\n- Search the local database for information using a vector index (through a `local_search` tool)\n{{/if}}\n\nThe Research Agent always follows these principles:\n\n- Relevance First: The Research Agent only returns facts supported by content in retrieved web pages. The Research Agent never fabricates or guesses information.\n- Summarize, Don't Copy: The Research Agent synthesizes and rephrases content in its own words. The Research Agent quotes only when necessary.\n- Multiple Sources: The Research Agent cross-references at least 2 sources before drawing conclusions, unless the information is directly stated and non-controversial.\n- Transparency: The Research Agent mentions which sources were used and explains how it arrived at conclusions.\n- Accuracy Over Brevity: The Research Agent prefers detailed, technically accurate explanations over shallow summaries.\n- The Research Agent admits uncertainty rather than misleading.\n{{#if entityExtraction}}\n- The Research Agent picks the most concrete schema types for extracted information.\n- The Research Agent fills schema fields completely with information it is confident about, and omits fields it is not confident about.\n- When outputting results, the Research Agent adds extra data that fits the schema even if not directly related to the user's question.\n- The Research Agent creates relations and references between new objects found and what's already in the database.\n- The Research Agent does not create objects that are already in the database.\n- The Research Agent re-uses existing object IDs as references when enriching existing objects.\n- The Research Agent ALWAYS calls the `graph_writer` at the end to save the data. This conversation will be deleted, so only the data written to the graph will be preserved.\n{{/if}}\n\nThe Research Agent may be asked for:\n\n- Technical explanations\n- Literature reviews \n- Comparisons\n- Emerging trends\n- Implementation strategies\n\nThe Research Agent begins by interpreting the user's request, then:\n\nThe Research Agent breaks it into sub-questions (if applicable).\n\nFor each sub-question, the Research Agent generates a clear, concise web search query.\n\nThe Research Agent extracts and synthesizes relevant answers.\n\nThe Research Agent's output includes:\n\n- A clear, structured answer to the user's question\n- A citation list or link list of sources used\n\nOptionally, the Research Agent provides follow-up suggestions or questions for deeper inquiry.\n\nHere's how the Research Agent operates:\n\n1. The Research Agent analyzes the user's request and identifies key topics to search for (3 or more), printing them out.\n2. The Research Agent performs a web search for each topic.\n3. The Research Agent reads and analyzes results, cross references information from multiple sources, and represents conflicting information as ranges of possible values.\n\n{{#if entityExtraction}}\n4. The Research Agent searches the local database for information using a vector index that might link to the user's question.\n6. The Research Agent creates relations and references between new objects and existing database objects when related, using existing object IDs as references.\n7. The Research Agent selects the most concrete schema types for extracted information, using multiple types as needed, and prints its decision and reasoning.\n5. The Research Agent creates a clear, structured answer to the user's question.\n8. The Research Agent submits results using the specific schema.\n{{/if}}\n\n{{#if entityExtraction}}\nIMPORTANT:\n- The Research Agent always runs the `local_search` tool to search the local database at least once before submitting results.\n- The Research Agent does not create objects that already exist in the database.\n- Ids that are not in the database are human-readable strings like `ivan_zhao_1`.\n{{/if}}\n\nStatus reporting:\n\nThe Research Agent reports its status frequently using the `<status>` tags: <status>Searching for Google Founders</status>\nThe Research Agent reports its status in-between each tool call and before submitting results.\n\n{{#if entityExtraction}}\n<example>\n\nBased on my research, I can now provide information about Google and it's founders.\n\nThe following objects are already in the database, I will not submit them again, but I'll re-use their IDs as references:\n\n- 01JWRDEHPB5TT2JQQQC15038BT Google\n- 01JWRDEHPA14CYW2NW9FAH6DJJ Larry Page\n- 01JWRDEHPBN0BBJP57B9S108W6 Sergey Brin\n\nI will use the following schema to construct new objects:\n\n- type:dxos.org/type/Organization for Alphabet Inc.\n- type:dxos.org/type/Person for Ivan Zhao\n- type:dxos.org/type/Person for Simon Last\n- dxn:type:dxos.org/relation/Employer for Ivan's employer\n- dxn:type:dxos.org/relation/Employer for Simon's employer\n\n<status>Formatting results</status>\n\n</example>\n{{/if}}\n\nLast content block is the full research note -- the result of the research.\n";
|
|
1407
|
+
|
|
1398
1408
|
// src/functions/research/types.ts
|
|
1399
|
-
import {
|
|
1409
|
+
import { Text } from "@dxos/schema";
|
|
1410
|
+
import { Event, HasConnection, HasRelationship, LegacyOrganization, LegacyPerson, Project, Task } from "@dxos/types";
|
|
1400
1411
|
var ResearchDataTypes = [
|
|
1401
1412
|
// Objects
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
DataType3.Task,
|
|
1407
|
-
DataType3.Text,
|
|
1413
|
+
Event.Event,
|
|
1414
|
+
LegacyOrganization,
|
|
1415
|
+
Task.Task,
|
|
1416
|
+
Text.Text,
|
|
1408
1417
|
// Relations
|
|
1409
|
-
// TODO(wittjosiah): Until views (e.g
|
|
1410
|
-
//
|
|
1411
|
-
|
|
1412
|
-
|
|
1418
|
+
// TODO(wittjosiah): Until views (e.g., Table) support relations this needs to be expressed via organization ref.
|
|
1419
|
+
// Employer.Employer,
|
|
1420
|
+
LegacyPerson,
|
|
1421
|
+
Project.Project,
|
|
1422
|
+
HasRelationship.HasRelationship,
|
|
1423
|
+
HasConnection.HasConnection
|
|
1413
1424
|
];
|
|
1414
1425
|
|
|
1415
1426
|
// src/functions/research/research.ts
|
|
@@ -1417,40 +1428,46 @@ var research_default = defineFunction8({
|
|
|
1417
1428
|
key: "dxos.org/function/research",
|
|
1418
1429
|
name: "Research",
|
|
1419
1430
|
description: trim3`
|
|
1420
|
-
|
|
1431
|
+
Search the web to research information about the given subject.
|
|
1421
1432
|
Inserts structured data into the research graph.
|
|
1422
|
-
|
|
1433
|
+
Creates a research summary and returns the objects created.
|
|
1423
1434
|
`,
|
|
1424
1435
|
inputSchema: Schema10.Struct({
|
|
1425
1436
|
query: Schema10.String.annotations({
|
|
1426
1437
|
description: trim3`
|
|
1427
|
-
The
|
|
1428
|
-
If doing research on an object
|
|
1438
|
+
The search query.
|
|
1439
|
+
If doing research on an object then load it first and pass it as JSON.
|
|
1429
1440
|
`
|
|
1430
1441
|
}),
|
|
1431
|
-
|
|
1442
|
+
instructions: Schema10.optional(Schema10.String).annotations({
|
|
1432
1443
|
description: trim3`
|
|
1433
1444
|
The instructions for the research agent.
|
|
1434
|
-
E.g., preference on fast responses or in-depth analysis, number of web searcher or the objects created.
|
|
1435
1445
|
`
|
|
1436
1446
|
}),
|
|
1437
1447
|
// TOOD(burdon): Move to context.
|
|
1438
1448
|
mockSearch: Schema10.optional(Schema10.Boolean).annotations({
|
|
1439
1449
|
description: "Whether to use the mock search tool.",
|
|
1440
1450
|
default: false
|
|
1451
|
+
}),
|
|
1452
|
+
entityExtraction: Schema10.optional(Schema10.Boolean).annotations({
|
|
1453
|
+
description: trim3`
|
|
1454
|
+
Whether to extract structured entities from the research.
|
|
1455
|
+
Experimental feature only enable if user explicitly requests it.
|
|
1456
|
+
`,
|
|
1457
|
+
default: false
|
|
1441
1458
|
})
|
|
1442
1459
|
}),
|
|
1443
1460
|
outputSchema: Schema10.Struct({
|
|
1444
|
-
|
|
1445
|
-
description: "
|
|
1461
|
+
document: Schema10.optional(Schema10.String).annotations({
|
|
1462
|
+
description: "The generated research document."
|
|
1446
1463
|
}),
|
|
1447
1464
|
objects: Schema10.Array(Schema10.Unknown).annotations({
|
|
1448
|
-
description: "
|
|
1465
|
+
description: "Structured objects created during the research process."
|
|
1449
1466
|
})
|
|
1450
1467
|
}),
|
|
1451
|
-
handler: Effect10.fnUntraced(function* ({ data: { query, mockSearch,
|
|
1468
|
+
handler: Effect10.fnUntraced(function* ({ data: { query, instructions: instructions6, mockSearch = false, entityExtraction = false } }) {
|
|
1452
1469
|
if (mockSearch) {
|
|
1453
|
-
const mockPerson = yield*
|
|
1470
|
+
const mockPerson = yield* Database7.Service.add(Obj7.make(Person.Person, {
|
|
1454
1471
|
preferredName: "John Doe",
|
|
1455
1472
|
emails: [
|
|
1456
1473
|
{
|
|
@@ -1464,52 +1481,52 @@ var research_default = defineFunction8({
|
|
|
1464
1481
|
]
|
|
1465
1482
|
}));
|
|
1466
1483
|
return {
|
|
1467
|
-
|
|
1468
|
-
The research
|
|
1469
|
-
|
|
1470
|
-
We reference John Doe to test reference: ${Obj5.getDXN(mockPerson)}
|
|
1484
|
+
document: trim3`
|
|
1485
|
+
The research ran in test-mode and was mocked. Proceed as usual.
|
|
1486
|
+
We reference John Doe to test reference: ${Obj7.getDXN(mockPerson)}
|
|
1471
1487
|
`,
|
|
1472
1488
|
objects: [
|
|
1473
|
-
|
|
1489
|
+
Obj7.toJSON(mockPerson)
|
|
1474
1490
|
]
|
|
1475
1491
|
};
|
|
1476
1492
|
}
|
|
1477
|
-
yield*
|
|
1493
|
+
yield* Database7.Service.flush({
|
|
1478
1494
|
indexes: true
|
|
1479
1495
|
});
|
|
1480
1496
|
yield* TracingService4.emitStatus({
|
|
1481
|
-
message: "
|
|
1482
|
-
});
|
|
1483
|
-
const objectDXNs = [];
|
|
1484
|
-
const GraphWriterToolkit = makeGraphWriterToolkit({
|
|
1485
|
-
schema: ResearchDataTypes
|
|
1486
|
-
});
|
|
1487
|
-
const GraphWriterHandler = makeGraphWriterHandler(GraphWriterToolkit, {
|
|
1488
|
-
onAppend: (dxns) => objectDXNs.push(...dxns)
|
|
1497
|
+
message: "Starting research..."
|
|
1489
1498
|
});
|
|
1490
1499
|
const NativeWebSearch = Toolkit2.make(AnthropicTool.WebSearch_20250305({}));
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1500
|
+
let toolkit = NativeWebSearch;
|
|
1501
|
+
let handlers = Layer3.empty;
|
|
1502
|
+
const objectDXNs = [];
|
|
1503
|
+
if (entityExtraction) {
|
|
1504
|
+
const GraphWriterToolkit = makeGraphWriterToolkit({
|
|
1505
|
+
schema: ResearchDataTypes
|
|
1506
|
+
});
|
|
1507
|
+
const GraphWriterHandler = makeGraphWriterHandler(GraphWriterToolkit, {
|
|
1508
|
+
onAppend: (dxns) => objectDXNs.push(...dxns)
|
|
1509
|
+
});
|
|
1510
|
+
toolkit = Toolkit2.merge(toolkit, LocalSearchToolkit, GraphWriterToolkit);
|
|
1511
|
+
handlers = Layer3.mergeAll(handlers, LocalSearchHandler, GraphWriterHandler).pipe(Layer3.provide(contextQueueLayerFromResearchGraph));
|
|
1512
|
+
}
|
|
1513
|
+
const finishedToolkit = yield* createToolkit2({
|
|
1514
|
+
toolkit
|
|
1515
|
+
}).pipe(Effect10.provide(handlers));
|
|
1498
1516
|
const session = new AiSession2();
|
|
1499
1517
|
const result = yield* session.run({
|
|
1500
1518
|
prompt: query,
|
|
1501
|
-
system:
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
toolkit,
|
|
1519
|
+
system: join(Template2.process(research_instructions_default, {
|
|
1520
|
+
entityExtraction
|
|
1521
|
+
}), instructions6 && `<instructions>${instructions6}</instructions>`),
|
|
1522
|
+
toolkit: finishedToolkit,
|
|
1505
1523
|
observer: GenerationObserver2.fromPrinter(new ConsolePrinter2({
|
|
1506
1524
|
tag: "research"
|
|
1507
1525
|
}))
|
|
1508
1526
|
});
|
|
1509
|
-
const
|
|
1510
|
-
const objects = yield* Effect10.forEach(objectDXNs, (dxn) => DatabaseService7.resolve(dxn)).pipe(Effect10.map(Array6.map((obj) => Obj5.toJSON(obj))));
|
|
1527
|
+
const objects = yield* Effect10.forEach(objectDXNs, (dxn) => Database7.Service.resolve(dxn)).pipe(Effect10.map(Array6.map((obj) => Entity2.toJSON(obj))));
|
|
1511
1528
|
return {
|
|
1512
|
-
|
|
1529
|
+
document: extractLastTextBlock(result),
|
|
1513
1530
|
objects
|
|
1514
1531
|
};
|
|
1515
1532
|
}, Effect10.provide(Layer3.mergeAll(
|
|
@@ -1522,7 +1539,7 @@ var research_default = defineFunction8({
|
|
|
1522
1539
|
makeToolExecutionServiceFromFunctions(Toolkit2.make(), Layer3.empty)
|
|
1523
1540
|
).pipe(Layer3.provide(
|
|
1524
1541
|
// TODO(dmaretskyi): This should be provided by environment.
|
|
1525
|
-
Layer3.mergeAll(
|
|
1542
|
+
Layer3.mergeAll(FunctionInvocationServiceLayerTestMocked({
|
|
1526
1543
|
functions: [
|
|
1527
1544
|
exa_default,
|
|
1528
1545
|
mock_default
|
|
@@ -1530,10 +1547,14 @@ var research_default = defineFunction8({
|
|
|
1530
1547
|
}))
|
|
1531
1548
|
))))
|
|
1532
1549
|
});
|
|
1550
|
+
var join = (...strings) => strings.filter(Boolean).join("\n\n");
|
|
1551
|
+
var extractLastTextBlock = (result) => {
|
|
1552
|
+
return Function4.pipe(result, Array6.last, Option4.map(Function4.flow((_) => _.blocks, Array6.reverse, Array6.dropWhile((_) => _._tag === "summary"), Array6.takeWhile((_) => _._tag === "text"), Array6.reverse, Array6.map((_) => _.text), Array6.reduce("", String10.concat))), Option4.getOrElse(() => ""));
|
|
1553
|
+
};
|
|
1533
1554
|
|
|
1534
1555
|
// src/functions/research/index.ts
|
|
1535
1556
|
(function(Research2) {
|
|
1536
|
-
Research2.create =
|
|
1557
|
+
Research2.create = document_create_default;
|
|
1537
1558
|
Research2.research = research_default;
|
|
1538
1559
|
})(Research || (Research = {}));
|
|
1539
1560
|
var Research;
|
|
@@ -1545,7 +1566,7 @@ var entity_extraction_default = defineFunction9({
|
|
|
1545
1566
|
name: "Entity Extraction",
|
|
1546
1567
|
description: "Extracts entities from emails and transcripts.",
|
|
1547
1568
|
inputSchema: Schema11.Struct({
|
|
1548
|
-
source:
|
|
1569
|
+
source: Message2.Message.annotations({
|
|
1549
1570
|
description: "Email or transcript to extract entities from."
|
|
1550
1571
|
}),
|
|
1551
1572
|
// TODO(dmaretskyi): Consider making this an array of blueprints instead.
|
|
@@ -1554,18 +1575,19 @@ var entity_extraction_default = defineFunction9({
|
|
|
1554
1575
|
})
|
|
1555
1576
|
}),
|
|
1556
1577
|
outputSchema: Schema11.Struct({
|
|
1557
|
-
entities: Schema11.optional(Schema11.Array(
|
|
1578
|
+
entities: Schema11.optional(Schema11.Array(Type4.Obj).annotations({
|
|
1558
1579
|
description: "Extracted entities."
|
|
1559
1580
|
}))
|
|
1560
1581
|
}),
|
|
1561
|
-
handler: Effect11.fnUntraced(function* ({ data: { source, instructions: instructions6 } }) {
|
|
1562
|
-
const
|
|
1582
|
+
handler: Effect11.fnUntraced(function* ({ data: { source: message, instructions: instructions6 } }) {
|
|
1583
|
+
const tags = Obj8.getMeta(message)?.tags;
|
|
1584
|
+
const contact = yield* extractContact(message.sender, tags);
|
|
1563
1585
|
let organization = null;
|
|
1564
1586
|
if (contact && !contact.organization) {
|
|
1565
1587
|
const created = [];
|
|
1566
1588
|
const GraphWriterToolkit = makeGraphWriterToolkit({
|
|
1567
1589
|
schema: [
|
|
1568
|
-
|
|
1590
|
+
LegacyOrganization2
|
|
1569
1591
|
]
|
|
1570
1592
|
}).pipe();
|
|
1571
1593
|
const GraphWriterHandler = makeGraphWriterHandler(GraphWriterToolkit, {
|
|
@@ -1579,7 +1601,7 @@ var entity_extraction_default = defineFunction9({
|
|
|
1579
1601
|
${instructions6 ? "<user_intructions>" + instructions6 + "</user_intructions>" : ""},
|
|
1580
1602
|
`,
|
|
1581
1603
|
prompt: JSON.stringify({
|
|
1582
|
-
source,
|
|
1604
|
+
source: message,
|
|
1583
1605
|
contact
|
|
1584
1606
|
}),
|
|
1585
1607
|
toolkit
|
|
@@ -1587,10 +1609,15 @@ var entity_extraction_default = defineFunction9({
|
|
|
1587
1609
|
if (created.length > 1) {
|
|
1588
1610
|
throw new Error("Multiple organizations created");
|
|
1589
1611
|
} else if (created.length === 1) {
|
|
1590
|
-
organization = yield*
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1612
|
+
organization = yield* Database8.Service.resolve(created[0], Organization.Organization);
|
|
1613
|
+
Obj8.change(organization, (org) => {
|
|
1614
|
+
const meta = Obj8.getMeta(org);
|
|
1615
|
+
meta.tags ??= [];
|
|
1616
|
+
meta.tags.push(...tags ?? []);
|
|
1617
|
+
});
|
|
1618
|
+
Obj8.change(contact, (c) => {
|
|
1619
|
+
c.organization = Ref3.make(organization);
|
|
1620
|
+
});
|
|
1594
1621
|
}
|
|
1595
1622
|
}
|
|
1596
1623
|
return {
|
|
@@ -1601,24 +1628,24 @@ var entity_extraction_default = defineFunction9({
|
|
|
1601
1628
|
};
|
|
1602
1629
|
}, Effect11.provide(Layer4.mergeAll(AiService3.model("@anthropic/claude-sonnet-4-0"), makeToolResolverFromFunctions2([], Toolkit3.make()), makeToolExecutionServiceFromFunctions2(Toolkit3.make(), Layer4.empty)).pipe(Layer4.provide(
|
|
1603
1630
|
// TODO(dmaretskyi): This should be provided by environment.
|
|
1604
|
-
Layer4.mergeAll(
|
|
1631
|
+
Layer4.mergeAll(FunctionInvocationServiceLayerTest())
|
|
1605
1632
|
))))
|
|
1606
1633
|
});
|
|
1607
|
-
var extractContact = Effect11.fn("extractContact")(function* (
|
|
1608
|
-
const name =
|
|
1609
|
-
const email =
|
|
1634
|
+
var extractContact = Effect11.fn("extractContact")(function* (actor, tags) {
|
|
1635
|
+
const name = actor.name;
|
|
1636
|
+
const email = actor.email;
|
|
1610
1637
|
if (!email) {
|
|
1611
1638
|
log5.warn("email is required for contact extraction", {
|
|
1612
|
-
|
|
1639
|
+
actor
|
|
1613
1640
|
}, {
|
|
1614
1641
|
F: __dxlog_file5,
|
|
1615
|
-
L:
|
|
1642
|
+
L: 112,
|
|
1616
1643
|
S: this,
|
|
1617
1644
|
C: (f, a) => f(...a)
|
|
1618
1645
|
});
|
|
1619
1646
|
return void 0;
|
|
1620
1647
|
}
|
|
1621
|
-
const
|
|
1648
|
+
const existingContacts = yield* Database8.Service.runQuery(Filter2.type(Person2.Person));
|
|
1622
1649
|
const existingContact = existingContacts.find((contact) => contact.emails?.some((contactEmail) => contactEmail.value === email));
|
|
1623
1650
|
if (existingContact) {
|
|
1624
1651
|
log5.info("Contact already exists", {
|
|
@@ -1626,25 +1653,31 @@ var extractContact = Effect11.fn("extractContact")(function* (message) {
|
|
|
1626
1653
|
existingContact
|
|
1627
1654
|
}, {
|
|
1628
1655
|
F: __dxlog_file5,
|
|
1629
|
-
L:
|
|
1656
|
+
L: 125,
|
|
1630
1657
|
S: this,
|
|
1631
1658
|
C: (f, a) => f(...a)
|
|
1632
1659
|
});
|
|
1633
1660
|
return existingContact;
|
|
1634
1661
|
}
|
|
1635
|
-
const newContact =
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1662
|
+
const newContact = Obj8.make(Person2.Person, {
|
|
1663
|
+
...tags ? {
|
|
1664
|
+
[Obj8.Meta]: {
|
|
1665
|
+
tags: [
|
|
1666
|
+
...tags
|
|
1667
|
+
]
|
|
1668
|
+
}
|
|
1669
|
+
} : {},
|
|
1639
1670
|
emails: [
|
|
1640
1671
|
{
|
|
1641
1672
|
value: email
|
|
1642
1673
|
}
|
|
1643
1674
|
]
|
|
1644
1675
|
});
|
|
1645
|
-
yield*
|
|
1676
|
+
yield* Database8.Service.add(newContact);
|
|
1646
1677
|
if (name) {
|
|
1647
|
-
newContact
|
|
1678
|
+
Obj8.change(newContact, (c) => {
|
|
1679
|
+
c.fullName = name;
|
|
1680
|
+
});
|
|
1648
1681
|
}
|
|
1649
1682
|
const emailDomain = email.split("@")[1]?.toLowerCase();
|
|
1650
1683
|
if (!emailDomain) {
|
|
@@ -1652,7 +1685,7 @@ var extractContact = Effect11.fn("extractContact")(function* (message) {
|
|
|
1652
1685
|
email
|
|
1653
1686
|
}, {
|
|
1654
1687
|
F: __dxlog_file5,
|
|
1655
|
-
L:
|
|
1688
|
+
L: 143,
|
|
1656
1689
|
S: this,
|
|
1657
1690
|
C: (f, a) => f(...a)
|
|
1658
1691
|
});
|
|
@@ -1662,11 +1695,11 @@ var extractContact = Effect11.fn("extractContact")(function* (message) {
|
|
|
1662
1695
|
emailDomain
|
|
1663
1696
|
}, {
|
|
1664
1697
|
F: __dxlog_file5,
|
|
1665
|
-
L:
|
|
1698
|
+
L: 147,
|
|
1666
1699
|
S: this,
|
|
1667
1700
|
C: (f, a) => f(...a)
|
|
1668
1701
|
});
|
|
1669
|
-
const
|
|
1702
|
+
const existingOrganisations = yield* Database8.Service.runQuery(Filter2.type(Organization.Organization));
|
|
1670
1703
|
const matchingOrg = existingOrganisations.find((org) => {
|
|
1671
1704
|
if (org.website) {
|
|
1672
1705
|
try {
|
|
@@ -1679,7 +1712,7 @@ var extractContact = Effect11.fn("extractContact")(function* (message) {
|
|
|
1679
1712
|
error: e
|
|
1680
1713
|
}, {
|
|
1681
1714
|
F: __dxlog_file5,
|
|
1682
|
-
L:
|
|
1715
|
+
L: 165,
|
|
1683
1716
|
S: this,
|
|
1684
1717
|
C: (f, a) => f(...a)
|
|
1685
1718
|
});
|
|
@@ -1693,11 +1726,13 @@ var extractContact = Effect11.fn("extractContact")(function* (message) {
|
|
|
1693
1726
|
organization: matchingOrg
|
|
1694
1727
|
}, {
|
|
1695
1728
|
F: __dxlog_file5,
|
|
1696
|
-
L:
|
|
1729
|
+
L: 176,
|
|
1697
1730
|
S: this,
|
|
1698
1731
|
C: (f, a) => f(...a)
|
|
1699
1732
|
});
|
|
1700
|
-
newContact
|
|
1733
|
+
Obj8.change(newContact, (c) => {
|
|
1734
|
+
c.organization = Ref3.make(matchingOrg);
|
|
1735
|
+
});
|
|
1701
1736
|
}
|
|
1702
1737
|
return newContact;
|
|
1703
1738
|
});
|
|
@@ -1713,17 +1748,18 @@ import * as FetchHttpClient2 from "@effect/platform/FetchHttpClient";
|
|
|
1713
1748
|
import * as HttpClient from "@effect/platform/HttpClient";
|
|
1714
1749
|
import * as Array9 from "effect/Array";
|
|
1715
1750
|
import * as Effect13 from "effect/Effect";
|
|
1716
|
-
import * as
|
|
1751
|
+
import * as Function5 from "effect/Function";
|
|
1717
1752
|
import * as Schema12 from "effect/Schema";
|
|
1718
|
-
import { Filter as Filter4, Obj as
|
|
1719
|
-
import {
|
|
1753
|
+
import { Filter as Filter4, Obj as Obj10, Query as Query4, Ref as Ref5 } from "@dxos/echo";
|
|
1754
|
+
import { Database as Database10 } from "@dxos/echo";
|
|
1755
|
+
import { CredentialsService as CredentialsService3, defineFunction as defineFunction10, withAuthorization } from "@dxos/functions";
|
|
1720
1756
|
import { log as log7 } from "@dxos/log";
|
|
1721
|
-
import {
|
|
1757
|
+
import { Person as Person3, Project as Project2, Task as Task2 } from "@dxos/types";
|
|
1722
1758
|
|
|
1723
1759
|
// src/sync/sync.ts
|
|
1724
1760
|
import * as Effect12 from "effect/Effect";
|
|
1725
|
-
import { Filter as Filter3, Obj as
|
|
1726
|
-
import {
|
|
1761
|
+
import { Filter as Filter3, Obj as Obj9, Query as Query3, Ref as Ref4 } from "@dxos/echo";
|
|
1762
|
+
import { Database as Database9 } from "@dxos/echo";
|
|
1727
1763
|
import { failedInvariant } from "@dxos/invariant";
|
|
1728
1764
|
import { log as log6 } from "@dxos/log";
|
|
1729
1765
|
var __dxlog_file6 = "/__w/dxos/dxos/packages/core/assistant-toolkit/src/sync/sync.ts";
|
|
@@ -1734,7 +1770,7 @@ var syncObjects = Effect12.fn("syncObjects")(function* (objs, { foreignKeyId })
|
|
|
1734
1770
|
if (!Ref4.isRef(obj[key])) continue;
|
|
1735
1771
|
const ref = obj[key];
|
|
1736
1772
|
if (!ref.target) continue;
|
|
1737
|
-
if (
|
|
1773
|
+
if (Obj9.getDXN(ref.target).isLocalObjectId()) {
|
|
1738
1774
|
const [target] = yield* syncObjects([
|
|
1739
1775
|
ref.target
|
|
1740
1776
|
], {
|
|
@@ -1743,26 +1779,26 @@ var syncObjects = Effect12.fn("syncObjects")(function* (objs, { foreignKeyId })
|
|
|
1743
1779
|
obj[key] = Ref4.make(target);
|
|
1744
1780
|
}
|
|
1745
1781
|
}
|
|
1746
|
-
const schema =
|
|
1747
|
-
const foreignId =
|
|
1748
|
-
const
|
|
1782
|
+
const schema = Obj9.getSchema(obj) ?? failedInvariant("No schema.");
|
|
1783
|
+
const foreignId = Obj9.getKeys(obj, foreignKeyId)[0]?.id ?? failedInvariant("No foreign key.");
|
|
1784
|
+
const [existing] = yield* Database9.Service.runQuery(Query3.select(Filter3.foreignKeys(schema, [
|
|
1749
1785
|
{
|
|
1750
1786
|
source: foreignKeyId,
|
|
1751
1787
|
id: foreignId
|
|
1752
1788
|
}
|
|
1753
1789
|
])));
|
|
1754
1790
|
log6("sync object", {
|
|
1755
|
-
type:
|
|
1791
|
+
type: Obj9.getTypename(obj),
|
|
1756
1792
|
foreignId,
|
|
1757
|
-
existing: existing ?
|
|
1793
|
+
existing: existing ? Obj9.getDXN(existing) : void 0
|
|
1758
1794
|
}, {
|
|
1759
1795
|
F: __dxlog_file6,
|
|
1760
|
-
L:
|
|
1796
|
+
L: 48,
|
|
1761
1797
|
S: this,
|
|
1762
1798
|
C: (f, a) => f(...a)
|
|
1763
1799
|
});
|
|
1764
1800
|
if (!existing) {
|
|
1765
|
-
yield*
|
|
1801
|
+
yield* Database9.Service.add(obj);
|
|
1766
1802
|
return obj;
|
|
1767
1803
|
} else {
|
|
1768
1804
|
copyObjectData(existing, obj);
|
|
@@ -1773,23 +1809,25 @@ var syncObjects = Effect12.fn("syncObjects")(function* (objs, { foreignKeyId })
|
|
|
1773
1809
|
});
|
|
1774
1810
|
});
|
|
1775
1811
|
var copyObjectData = (existing, newObj) => {
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
for (const key of Object.keys(existing)) {
|
|
1782
|
-
if (typeof key !== "string" || key === "id") continue;
|
|
1783
|
-
if (!(key in newObj)) {
|
|
1784
|
-
delete existing[key];
|
|
1812
|
+
Obj9.change(existing, (obj) => {
|
|
1813
|
+
for (const key of Object.keys(newObj)) {
|
|
1814
|
+
if (typeof key !== "string" || key === "id") continue;
|
|
1815
|
+
if (typeof newObj[key] !== "string" && typeof newObj[key] !== "number" && typeof newObj[key] !== "boolean" && !Ref4.isRef(newObj[key])) continue;
|
|
1816
|
+
obj[key] = newObj[key];
|
|
1785
1817
|
}
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
}
|
|
1792
|
-
|
|
1818
|
+
for (const key of Object.keys(obj)) {
|
|
1819
|
+
if (typeof key !== "string" || key === "id") continue;
|
|
1820
|
+
if (!(key in newObj)) {
|
|
1821
|
+
delete obj[key];
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
for (const foreignKey of Obj9.getMeta(newObj).keys) {
|
|
1825
|
+
Obj9.deleteKeys(obj, foreignKey.source);
|
|
1826
|
+
Obj9.getMeta(obj).keys.push({
|
|
1827
|
+
...foreignKey
|
|
1828
|
+
});
|
|
1829
|
+
}
|
|
1830
|
+
});
|
|
1793
1831
|
};
|
|
1794
1832
|
|
|
1795
1833
|
// src/util/graphql.ts
|
|
@@ -1819,7 +1857,7 @@ query Issues($teamId: String!, $after: DateTimeOrDuration!) {
|
|
|
1819
1857
|
updatedAt
|
|
1820
1858
|
description
|
|
1821
1859
|
assignee { id, name }
|
|
1822
|
-
state {
|
|
1860
|
+
state {
|
|
1823
1861
|
name
|
|
1824
1862
|
}
|
|
1825
1863
|
project {
|
|
@@ -1850,15 +1888,16 @@ var sync_issues_default = defineFunction10({
|
|
|
1850
1888
|
})
|
|
1851
1889
|
}),
|
|
1852
1890
|
handler: Effect13.fnUntraced(function* ({ data }) {
|
|
1853
|
-
const
|
|
1891
|
+
const credential = yield* CredentialsService3.getCredential({
|
|
1854
1892
|
service: "linear.app"
|
|
1855
|
-
})
|
|
1856
|
-
const
|
|
1893
|
+
});
|
|
1894
|
+
const client = yield* HttpClient.HttpClient.pipe(Effect13.map(withAuthorization(credential.apiKey)));
|
|
1895
|
+
const after = yield* getLatestUpdateTimestamp(data.team, Task2.Task);
|
|
1857
1896
|
log7.info("will fetch", {
|
|
1858
1897
|
after
|
|
1859
1898
|
}, {
|
|
1860
1899
|
F: __dxlog_file7,
|
|
1861
|
-
L:
|
|
1900
|
+
L: 93,
|
|
1862
1901
|
S: this,
|
|
1863
1902
|
C: (f, a) => f(...a)
|
|
1864
1903
|
});
|
|
@@ -1876,7 +1915,7 @@ var sync_issues_default = defineFunction10({
|
|
|
1876
1915
|
count: tasks.length
|
|
1877
1916
|
}, {
|
|
1878
1917
|
F: __dxlog_file7,
|
|
1879
|
-
L:
|
|
1918
|
+
L: 106,
|
|
1880
1919
|
S: this,
|
|
1881
1920
|
C: (f, a) => f(...a)
|
|
1882
1921
|
});
|
|
@@ -1889,16 +1928,16 @@ var sync_issues_default = defineFunction10({
|
|
|
1889
1928
|
}, Effect13.provide(FetchHttpClient2.layer))
|
|
1890
1929
|
});
|
|
1891
1930
|
var getLatestUpdateTimestamp = Effect13.fnUntraced(function* (teamId, dataType) {
|
|
1892
|
-
const
|
|
1931
|
+
const existingTasks = yield* Database10.Service.runQuery(Query4.type(dataType).select(Filter4.foreignKeys(dataType, [
|
|
1893
1932
|
{
|
|
1894
1933
|
source: LINEAR_TEAM_ID_KEY,
|
|
1895
1934
|
id: teamId
|
|
1896
1935
|
}
|
|
1897
1936
|
])));
|
|
1898
|
-
return
|
|
1937
|
+
return Function5.pipe(existingTasks, Array9.map((task) => Obj10.getKeys(task, LINEAR_UPDATED_AT_KEY).at(0)?.id), Array9.filter((x) => x !== void 0), Array9.reduce("2025-01-01T00:00:00.000Z", (acc, x) => x > acc ? x : acc));
|
|
1899
1938
|
});
|
|
1900
|
-
var mapLinearPerson = (person, { teamId }) =>
|
|
1901
|
-
[
|
|
1939
|
+
var mapLinearPerson = (person, { teamId }) => Obj10.make(Person3.Person, {
|
|
1940
|
+
[Obj10.Meta]: {
|
|
1902
1941
|
keys: [
|
|
1903
1942
|
{
|
|
1904
1943
|
id: person.id,
|
|
@@ -1912,8 +1951,8 @@ var mapLinearPerson = (person, { teamId }) => Obj8.make(DataType6.Person, {
|
|
|
1912
1951
|
},
|
|
1913
1952
|
nickname: person.name
|
|
1914
1953
|
});
|
|
1915
|
-
var mapLinearIssue = (issue, { teamId }) =>
|
|
1916
|
-
[
|
|
1954
|
+
var mapLinearIssue = (issue, { teamId }) => Obj10.make(Task2.Task, {
|
|
1955
|
+
[Obj10.Meta]: {
|
|
1917
1956
|
keys: [
|
|
1918
1957
|
{
|
|
1919
1958
|
id: issue.id,
|
|
@@ -1936,8 +1975,8 @@ var mapLinearIssue = (issue, { teamId }) => Obj8.make(DataType6.Task, {
|
|
|
1936
1975
|
})),
|
|
1937
1976
|
// TODO(dmaretskyi): Sync those (+ linear team as org?).
|
|
1938
1977
|
// state: issue.state.name,
|
|
1939
|
-
project: !issue.project ? void 0 : Ref5.make(
|
|
1940
|
-
[
|
|
1978
|
+
project: !issue.project ? void 0 : Ref5.make(Project2.make({
|
|
1979
|
+
[Obj10.Meta]: {
|
|
1941
1980
|
keys: [
|
|
1942
1981
|
{
|
|
1943
1982
|
id: issue.project.id,
|
|
@@ -1962,15 +2001,16 @@ var Linear;
|
|
|
1962
2001
|
// src/functions/tasks/read.ts
|
|
1963
2002
|
import * as Effect14 from "effect/Effect";
|
|
1964
2003
|
import * as Schema13 from "effect/Schema";
|
|
1965
|
-
import { ArtifactId as
|
|
1966
|
-
import {
|
|
2004
|
+
import { ArtifactId as ArtifactId4 } from "@dxos/assistant";
|
|
2005
|
+
import { Database as Database11 } from "@dxos/echo";
|
|
2006
|
+
import { defineFunction as defineFunction11 } from "@dxos/functions";
|
|
1967
2007
|
import { Markdown as Markdown4 } from "@dxos/plugin-markdown/types";
|
|
1968
2008
|
var read_default2 = defineFunction11({
|
|
1969
2009
|
key: "dxos.org/function/markdown/read-tasks",
|
|
1970
2010
|
name: "Read",
|
|
1971
2011
|
description: "Read markdown tasks.",
|
|
1972
2012
|
inputSchema: Schema13.Struct({
|
|
1973
|
-
id:
|
|
2013
|
+
id: ArtifactId4.annotations({
|
|
1974
2014
|
description: "The ID of the document to read."
|
|
1975
2015
|
})
|
|
1976
2016
|
}),
|
|
@@ -1978,8 +2018,8 @@ var read_default2 = defineFunction11({
|
|
|
1978
2018
|
content: Schema13.String
|
|
1979
2019
|
}),
|
|
1980
2020
|
handler: Effect14.fn(function* ({ data: { id } }) {
|
|
1981
|
-
const doc = yield*
|
|
1982
|
-
const { content } = yield*
|
|
2021
|
+
const doc = yield* Database11.Service.resolve(ArtifactId4.toDXN(id), Markdown4.Document);
|
|
2022
|
+
const { content } = yield* Database11.Service.load(doc.content);
|
|
1983
2023
|
const lines = content.split("\n");
|
|
1984
2024
|
const len = String(lines.length).length;
|
|
1985
2025
|
const numbered = lines.map((line, i) => `${String(i + 1).padStart(len, " ")}. ${line}`).join("\n");
|
|
@@ -1992,8 +2032,9 @@ var read_default2 = defineFunction11({
|
|
|
1992
2032
|
// src/functions/tasks/update.ts
|
|
1993
2033
|
import * as Effect15 from "effect/Effect";
|
|
1994
2034
|
import * as Schema14 from "effect/Schema";
|
|
1995
|
-
import { ArtifactId as
|
|
1996
|
-
import {
|
|
2035
|
+
import { ArtifactId as ArtifactId5 } from "@dxos/assistant";
|
|
2036
|
+
import { Database as Database12 } from "@dxos/echo";
|
|
2037
|
+
import { defineFunction as defineFunction12 } from "@dxos/functions";
|
|
1997
2038
|
import { Markdown as Markdown5 } from "@dxos/plugin-markdown/types";
|
|
1998
2039
|
|
|
1999
2040
|
// src/functions/tasks/task-list.ts
|
|
@@ -2130,7 +2171,7 @@ var update_default2 = defineFunction12({
|
|
|
2130
2171
|
name: "Update markdown",
|
|
2131
2172
|
description: "Creates and updates tasks in markdown documents.",
|
|
2132
2173
|
inputSchema: Schema14.Struct({
|
|
2133
|
-
id:
|
|
2174
|
+
id: ArtifactId5.annotations({
|
|
2134
2175
|
description: "The ID of the document to update."
|
|
2135
2176
|
}),
|
|
2136
2177
|
operations: Schema14.optional(Schema14.Array(Schema14.Any.annotations({
|
|
@@ -2144,8 +2185,8 @@ var update_default2 = defineFunction12({
|
|
|
2144
2185
|
})
|
|
2145
2186
|
}),
|
|
2146
2187
|
handler: Effect15.fn(function* ({ data: { id, operations = [] } }) {
|
|
2147
|
-
const doc = yield*
|
|
2148
|
-
const { content } = yield*
|
|
2188
|
+
const doc = yield* Database12.Service.resolve(ArtifactId5.toDXN(id), Markdown5.Document);
|
|
2189
|
+
const { content } = yield* Database12.Service.load(doc.content);
|
|
2149
2190
|
const taskManager = new MarkdownTasks(content);
|
|
2150
2191
|
if (operations.length > 0) {
|
|
2151
2192
|
taskManager.applyOperations(operations);
|
|
@@ -2174,28 +2215,27 @@ var instructions = trim5`
|
|
|
2174
2215
|
When replying to the user, be terse with your comments about design doc handling.
|
|
2175
2216
|
Do not announce when you read or write the design spec document.
|
|
2176
2217
|
`;
|
|
2177
|
-
var blueprint =
|
|
2218
|
+
var blueprint = Blueprint.make({
|
|
2178
2219
|
key: "dxos.org/blueprint/design",
|
|
2179
2220
|
name: "Design Spec",
|
|
2180
2221
|
description: "Preserve the conversation in the design spec.",
|
|
2181
2222
|
instructions: {
|
|
2182
|
-
source: Ref6.make(
|
|
2223
|
+
source: Ref6.make(Text2.make(instructions))
|
|
2183
2224
|
},
|
|
2184
2225
|
tools: [
|
|
2185
2226
|
Document.read,
|
|
2186
2227
|
Document.update
|
|
2187
2228
|
].map((fn9) => ToolId.make(fn9.key))
|
|
2188
2229
|
});
|
|
2189
|
-
var design_blueprint_default = blueprint;
|
|
2190
2230
|
|
|
2191
2231
|
// src/blueprints/design/index.ts
|
|
2192
|
-
var design_default =
|
|
2232
|
+
var design_default = blueprint;
|
|
2193
2233
|
|
|
2194
2234
|
// src/blueprints/discord/discord-blueprint.ts
|
|
2195
2235
|
import { ToolId as ToolId2 } from "@dxos/ai";
|
|
2196
2236
|
import { Blueprint as Blueprint2 } from "@dxos/blueprints";
|
|
2197
|
-
import {
|
|
2198
|
-
import {
|
|
2237
|
+
import { Ref as Ref7 } from "@dxos/echo";
|
|
2238
|
+
import { Text as Text3 } from "@dxos/schema";
|
|
2199
2239
|
import { trim as trim6 } from "@dxos/util";
|
|
2200
2240
|
var instructions2 = trim6`
|
|
2201
2241
|
You are able to fetch messages from Discord servers.
|
|
@@ -2204,27 +2244,26 @@ var instructions2 = trim6`
|
|
|
2204
2244
|
|
|
2205
2245
|
DXOS serverId: 837138313172353095
|
|
2206
2246
|
`;
|
|
2207
|
-
var blueprint2 =
|
|
2247
|
+
var blueprint2 = Blueprint2.make({
|
|
2208
2248
|
key: "dxos.org/blueprint/discord",
|
|
2209
2249
|
name: "Discord",
|
|
2210
2250
|
description: "Discord integration.",
|
|
2211
2251
|
instructions: {
|
|
2212
|
-
source: Ref7.make(
|
|
2252
|
+
source: Ref7.make(Text3.make(instructions2))
|
|
2213
2253
|
},
|
|
2214
2254
|
tools: [
|
|
2215
2255
|
ToolId2.make(Discord.fetch.key)
|
|
2216
2256
|
]
|
|
2217
2257
|
});
|
|
2218
|
-
var discord_blueprint_default = blueprint2;
|
|
2219
2258
|
|
|
2220
2259
|
// src/blueprints/discord/index.ts
|
|
2221
|
-
var discord_default =
|
|
2260
|
+
var discord_default = blueprint2;
|
|
2222
2261
|
|
|
2223
2262
|
// src/blueprints/linear/linear-blueprint.ts
|
|
2224
2263
|
import { ToolId as ToolId3 } from "@dxos/ai";
|
|
2225
2264
|
import { Blueprint as Blueprint3 } from "@dxos/blueprints";
|
|
2226
|
-
import {
|
|
2227
|
-
import {
|
|
2265
|
+
import { Ref as Ref8 } from "@dxos/echo";
|
|
2266
|
+
import { Text as Text4 } from "@dxos/schema";
|
|
2228
2267
|
import { trim as trim7 } from "@dxos/util";
|
|
2229
2268
|
var instructions3 = trim7`
|
|
2230
2269
|
You are able to sync Linear workspaces.
|
|
@@ -2234,27 +2273,26 @@ var instructions3 = trim7`
|
|
|
2234
2273
|
|
|
2235
2274
|
DXOS teamId: 1127c63a-6f77-4725-9229-50f6cd47321c
|
|
2236
2275
|
`;
|
|
2237
|
-
var blueprint3 =
|
|
2276
|
+
var blueprint3 = Blueprint3.make({
|
|
2238
2277
|
key: "dxos.org/blueprint/linear",
|
|
2239
2278
|
name: "Linear",
|
|
2240
2279
|
description: "Syncs Linear workspaces.",
|
|
2241
2280
|
instructions: {
|
|
2242
|
-
source: Ref8.make(
|
|
2281
|
+
source: Ref8.make(Text4.make(instructions3))
|
|
2243
2282
|
},
|
|
2244
2283
|
tools: [
|
|
2245
2284
|
Linear.sync
|
|
2246
2285
|
].map((tool) => ToolId3.make(tool.key))
|
|
2247
2286
|
});
|
|
2248
|
-
var linear_blueprint_default = blueprint3;
|
|
2249
2287
|
|
|
2250
2288
|
// src/blueprints/linear/index.ts
|
|
2251
|
-
var linear_default =
|
|
2289
|
+
var linear_default = blueprint3;
|
|
2252
2290
|
|
|
2253
2291
|
// src/blueprints/planning/planning-blueprint.ts
|
|
2254
2292
|
import { ToolId as ToolId4 } from "@dxos/ai";
|
|
2255
2293
|
import { Blueprint as Blueprint4 } from "@dxos/blueprints";
|
|
2256
|
-
import {
|
|
2257
|
-
import {
|
|
2294
|
+
import { Ref as Ref9 } from "@dxos/echo";
|
|
2295
|
+
import { Text as Text5 } from "@dxos/schema";
|
|
2258
2296
|
import { trim as trim8 } from "@dxos/util";
|
|
2259
2297
|
var instructions4 = trim8`
|
|
2260
2298
|
You are a task management agent that maintains hierarchical task lists where each line is a task.
|
|
@@ -2327,81 +2365,86 @@ var instructions4 = trim8`
|
|
|
2327
2365
|
- When creating subtasks, consider the parent task's completion status
|
|
2328
2366
|
- Be precise with task descriptions and hierarchy levels
|
|
2329
2367
|
`;
|
|
2330
|
-
var blueprint4 =
|
|
2368
|
+
var blueprint4 = Blueprint4.make({
|
|
2331
2369
|
key: "dxos.org/blueprint/planning",
|
|
2332
2370
|
name: "Planning",
|
|
2333
2371
|
description: "Plans and tracks complex tasks with artifact management.",
|
|
2334
2372
|
instructions: {
|
|
2335
|
-
source: Ref9.make(
|
|
2373
|
+
source: Ref9.make(Text5.make(instructions4))
|
|
2336
2374
|
},
|
|
2337
2375
|
tools: [
|
|
2338
2376
|
Tasks.read,
|
|
2339
2377
|
Tasks.update
|
|
2340
2378
|
].map((fn9) => ToolId4.make(fn9.key))
|
|
2341
2379
|
});
|
|
2342
|
-
var planning_blueprint_default = blueprint4;
|
|
2343
2380
|
|
|
2344
2381
|
// src/blueprints/planning/index.ts
|
|
2345
|
-
var planning_default =
|
|
2382
|
+
var planning_default = blueprint4;
|
|
2346
2383
|
|
|
2347
2384
|
// src/blueprints/research/research-blueprint.ts
|
|
2348
2385
|
import { ToolId as ToolId5 } from "@dxos/ai";
|
|
2349
2386
|
import { Blueprint as Blueprint5 } from "@dxos/blueprints";
|
|
2350
|
-
import {
|
|
2351
|
-
import {
|
|
2387
|
+
import { Ref as Ref10 } from "@dxos/echo";
|
|
2388
|
+
import { Text as Text6 } from "@dxos/schema";
|
|
2352
2389
|
import { trim as trim9 } from "@dxos/util";
|
|
2353
2390
|
var instructions5 = trim9`
|
|
2354
2391
|
{{! Research }}
|
|
2355
2392
|
|
|
2356
2393
|
You are an analyst that does research tasks using tools that scrape the web and create structured data.
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
<
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2394
|
+
Structured data extraction is an experimental feature -- only enable it if the user explicitly requests it in the prompt.
|
|
2395
|
+
Prefer updating existing notes instead of creating new ones.
|
|
2396
|
+
|
|
2397
|
+
<strcutured_mode>
|
|
2398
|
+
When you are done, reply with the created objects.
|
|
2399
|
+
Do not print the data, instead reply with inline references to the created objects.
|
|
2400
|
+
Those will be later substituted with the pills representing the created objects.
|
|
2401
|
+
Print the rest of the created objects as block references after the main note.
|
|
2402
|
+
|
|
2403
|
+
<example>
|
|
2404
|
+
Based on my research, Google was founded by @dxn:queue:data:B6INSIBY3CBEF4M5VZRYBCMAHQMPYK5AJ:01K24XMVHSZHS97SG1VTVQDM5Z:01K24XPK464FSCKVQJAB2H662M and @dxn:queue:data:B6INSIBY3CBEF4M5VZRYBCMAHQMPYK5AJ:01K24XMVHSZHS97SG1VTVQDM5Z:01K24XPK46K31DDW62PBW9H2ZQ
|
|
2405
|
+
|
|
2406
|
+
<object><dxn>dxn:queue:data:B6INSIBY3CBEF4M5VZRYBCMAHQMPYK5AJ:01K24XMVHSZHS97SG1VTVQDM5Z:01K24XPK464FSCKVQJAB2H662M</dxn></object>
|
|
2407
|
+
<object><dxn>dxn:queue:data:B6INSIBY3CBEF4M5VZRYBCMAHQMPYK5AJ:01K24XMVHSZHS97SG1VTVQDM5Z:01K24XPK46K31DDW62PBW9H2ZQ</dxn></object>
|
|
2408
|
+
<object><dxn>dxn:queue:data:B6INSIBY3CBEF4M5VZRYBCMAHQMPYK5AJ:01K24XMVHSZHS97SG1VTVQDM5Z:01K24XPK46K31DDW62PBW92333</dxn></object>
|
|
2409
|
+
</example>
|
|
2410
|
+
</structured_mode>
|
|
2411
|
+
|
|
2412
|
+
<unstructured_mode>
|
|
2413
|
+
Reply normally with the text mode of the result of your research.
|
|
2414
|
+
</unstructured_mode>
|
|
2370
2415
|
`;
|
|
2371
|
-
var blueprint5 =
|
|
2416
|
+
var blueprint5 = Blueprint5.make({
|
|
2372
2417
|
key: "dxos.org/blueprint/research",
|
|
2373
2418
|
name: "Research",
|
|
2374
2419
|
description: "Researches the web and creates structured data.",
|
|
2375
2420
|
instructions: {
|
|
2376
|
-
source: Ref10.make(
|
|
2421
|
+
source: Ref10.make(Text6.make(instructions5))
|
|
2377
2422
|
},
|
|
2378
2423
|
tools: [
|
|
2379
2424
|
Research.create,
|
|
2380
2425
|
Research.research
|
|
2381
2426
|
].map((fn9) => ToolId5.make(fn9.key))
|
|
2382
2427
|
});
|
|
2383
|
-
var research_blueprint_default = blueprint5;
|
|
2384
2428
|
|
|
2385
2429
|
// src/blueprints/research/index.ts
|
|
2386
|
-
var research_default2 =
|
|
2430
|
+
var research_default2 = blueprint5;
|
|
2387
2431
|
|
|
2388
2432
|
// src/blueprints/websearch/websearch-blueprint.ts
|
|
2389
2433
|
import { ToolId as ToolId6 } from "@dxos/ai";
|
|
2390
2434
|
import { Blueprint as Blueprint6 } from "@dxos/blueprints";
|
|
2391
|
-
import {
|
|
2392
|
-
import {
|
|
2393
|
-
var blueprint6 =
|
|
2435
|
+
import { Ref as Ref11 } from "@dxos/echo";
|
|
2436
|
+
import { Text as Text7 } from "@dxos/schema";
|
|
2437
|
+
var blueprint6 = Blueprint6.make({
|
|
2394
2438
|
key: "dxos.org/blueprint/web-search",
|
|
2395
2439
|
name: "Web Search",
|
|
2396
2440
|
description: "Search the web.",
|
|
2397
2441
|
instructions: {
|
|
2398
|
-
source: Ref11.make(
|
|
2442
|
+
source: Ref11.make(Text7.make())
|
|
2399
2443
|
},
|
|
2400
2444
|
tools: [
|
|
2401
2445
|
ToolId6.make("AnthropicWebSearch")
|
|
2402
2446
|
]
|
|
2403
2447
|
});
|
|
2404
|
-
var websearch_blueprint_default = blueprint6;
|
|
2405
2448
|
|
|
2406
2449
|
// src/blueprints/websearch/websearch-toolkit.ts
|
|
2407
2450
|
import * as Toolkit4 from "@effect/ai/Toolkit";
|
|
@@ -2409,46 +2452,402 @@ import * as AnthropicTool2 from "@effect/ai-anthropic/AnthropicTool";
|
|
|
2409
2452
|
var WebSearchToolkit = Toolkit4.make(AnthropicTool2.WebSearch_20250305({}));
|
|
2410
2453
|
|
|
2411
2454
|
// src/blueprints/websearch/index.ts
|
|
2412
|
-
var websearch_default =
|
|
2413
|
-
|
|
2414
|
-
// src/
|
|
2455
|
+
var websearch_default = blueprint6;
|
|
2456
|
+
|
|
2457
|
+
// src/toolkits/AssistantToolkit.ts
|
|
2458
|
+
var AssistantToolkit_exports = {};
|
|
2459
|
+
__export(AssistantToolkit_exports, {
|
|
2460
|
+
AssistantToolkit: () => AssistantToolkit,
|
|
2461
|
+
layer: () => layer3,
|
|
2462
|
+
tools: () => tools
|
|
2463
|
+
});
|
|
2464
|
+
import * as Tool2 from "@effect/ai/Tool";
|
|
2465
|
+
import * as Toolkit5 from "@effect/ai/Toolkit";
|
|
2466
|
+
import * as Effect16 from "effect/Effect";
|
|
2467
|
+
import * as Record from "effect/Record";
|
|
2415
2468
|
import * as Schema15 from "effect/Schema";
|
|
2416
|
-
import
|
|
2417
|
-
import {
|
|
2418
|
-
import {
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
var isImage = (data) => false;
|
|
2427
|
-
var capabilities = [
|
|
2428
|
-
contributes(Capabilities.ReactSurface, createSurface({
|
|
2429
|
-
id: "plugin-image",
|
|
2430
|
-
role: "card--extrinsic",
|
|
2431
|
-
filter: (data) => isImage(data.value),
|
|
2432
|
-
component: ({ data }) => /* @__PURE__ */ React.createElement("img", {
|
|
2433
|
-
className: "grow object-cover",
|
|
2434
|
-
src: `data:image/jpeg;base64,${data.value.source.data}`,
|
|
2435
|
-
alt: data.value.prompt ?? `Generated image [id=${data.value.id}]`
|
|
2469
|
+
import { AiContextService, ArtifactId as ArtifactId6 } from "@dxos/assistant";
|
|
2470
|
+
import { Database as Database13 } from "@dxos/echo";
|
|
2471
|
+
import { trim as trim10 } from "@dxos/util";
|
|
2472
|
+
var AssistantToolkit = Toolkit5.make(Tool2.make("context-add", {
|
|
2473
|
+
description: trim10`
|
|
2474
|
+
Adds the object to the chat context.
|
|
2475
|
+
`,
|
|
2476
|
+
parameters: {
|
|
2477
|
+
id: ArtifactId6.annotations({
|
|
2478
|
+
description: "The ID of the document to add."
|
|
2436
2479
|
})
|
|
2437
|
-
}
|
|
2480
|
+
},
|
|
2481
|
+
success: Schema15.Void,
|
|
2482
|
+
failure: Schema15.Never,
|
|
2483
|
+
dependencies: [
|
|
2484
|
+
AiContextService,
|
|
2485
|
+
Database13.Service
|
|
2486
|
+
]
|
|
2487
|
+
}), Tool2.make("context-remove", {
|
|
2488
|
+
description: trim10`
|
|
2489
|
+
Removes the object from the chat context.
|
|
2490
|
+
`,
|
|
2491
|
+
parameters: {
|
|
2492
|
+
id: ArtifactId6.annotations({
|
|
2493
|
+
description: "The ID of the document to remove."
|
|
2494
|
+
})
|
|
2495
|
+
},
|
|
2496
|
+
success: Schema15.Void,
|
|
2497
|
+
failure: Schema15.Never,
|
|
2498
|
+
dependencies: [
|
|
2499
|
+
AiContextService,
|
|
2500
|
+
Database13.Service
|
|
2501
|
+
]
|
|
2502
|
+
}));
|
|
2503
|
+
var tools = Record.keys(AssistantToolkit.tools);
|
|
2504
|
+
var layer3 = () => AssistantToolkit.toLayer({
|
|
2505
|
+
["context-add"]: Effect16.fnUntraced(function* ({ id }) {
|
|
2506
|
+
const { binder } = yield* AiContextService;
|
|
2507
|
+
const { db } = yield* Database13.Service;
|
|
2508
|
+
const ref = db.makeRef(ArtifactId6.toDXN(id, db.spaceId));
|
|
2509
|
+
yield* Effect16.promise(() => binder.bind({
|
|
2510
|
+
blueprints: [],
|
|
2511
|
+
objects: [
|
|
2512
|
+
ref
|
|
2513
|
+
]
|
|
2514
|
+
}));
|
|
2515
|
+
}),
|
|
2516
|
+
["context-remove"]: Effect16.fnUntraced(function* ({ id }) {
|
|
2517
|
+
const { binder } = yield* AiContextService;
|
|
2518
|
+
const { db } = yield* Database13.Service;
|
|
2519
|
+
const ref = db.makeRef(ArtifactId6.toDXN(id, db.spaceId));
|
|
2520
|
+
yield* Effect16.promise(() => binder.unbind({
|
|
2521
|
+
blueprints: [],
|
|
2522
|
+
objects: [
|
|
2523
|
+
ref
|
|
2524
|
+
]
|
|
2525
|
+
}));
|
|
2526
|
+
})
|
|
2527
|
+
});
|
|
2528
|
+
|
|
2529
|
+
// src/toolkits/SystemToolkit.ts
|
|
2530
|
+
var SystemToolkit_exports = {};
|
|
2531
|
+
__export(SystemToolkit_exports, {
|
|
2532
|
+
SystemToolkit: () => SystemToolkit,
|
|
2533
|
+
layer: () => layer4,
|
|
2534
|
+
tools: () => tools2
|
|
2535
|
+
});
|
|
2536
|
+
import * as Tool3 from "@effect/ai/Tool";
|
|
2537
|
+
import * as Toolkit6 from "@effect/ai/Toolkit";
|
|
2538
|
+
import * as Effect17 from "effect/Effect";
|
|
2539
|
+
import * as Record2 from "effect/Record";
|
|
2540
|
+
import * as Schema16 from "effect/Schema";
|
|
2541
|
+
import { ArtifactId as ArtifactId7 } from "@dxos/assistant";
|
|
2542
|
+
import { DXN as DXN2, Database as Database14, Entity as Entity3, Filter as Filter5, Obj as Obj11, Relation as Relation2, Tag as Tag2, Type as Type5 } from "@dxos/echo";
|
|
2543
|
+
import { invariant } from "@dxos/invariant";
|
|
2544
|
+
import { trim as trim11 } from "@dxos/util";
|
|
2545
|
+
var __dxlog_file8 = "/__w/dxos/dxos/packages/core/assistant-toolkit/src/toolkits/SystemToolkit.ts";
|
|
2546
|
+
var SystemToolkit = Toolkit6.make(
|
|
2438
2547
|
//
|
|
2439
|
-
//
|
|
2548
|
+
// Schema
|
|
2440
2549
|
//
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2550
|
+
Tool3.make("schema-list", {
|
|
2551
|
+
description: trim11`
|
|
2552
|
+
Lists schemas definitions.
|
|
2553
|
+
`,
|
|
2554
|
+
parameters: {
|
|
2555
|
+
// TODO(wittjosiah): Remove this once parameter-less tools are fixed.
|
|
2556
|
+
limit: Schema16.Number
|
|
2557
|
+
},
|
|
2558
|
+
// TODO(dmaretskyi): Effect returns ({ result, encodedResult })
|
|
2559
|
+
success: Schema16.Any,
|
|
2560
|
+
failure: Schema16.Never,
|
|
2561
|
+
dependencies: [
|
|
2562
|
+
Database14.Service
|
|
2563
|
+
]
|
|
2564
|
+
}),
|
|
2565
|
+
Tool3.make("schema-add", {
|
|
2566
|
+
description: trim11`
|
|
2567
|
+
Adds a schema to the space.
|
|
2568
|
+
The name will be used when displayed to the user.
|
|
2569
|
+
The typename must be in the format of "example.com/type/Type".
|
|
2570
|
+
`,
|
|
2571
|
+
parameters: {
|
|
2572
|
+
name: Schema16.String,
|
|
2573
|
+
typename: Schema16.String,
|
|
2574
|
+
jsonSchema: Schema16.Any
|
|
2575
|
+
},
|
|
2576
|
+
success: Schema16.Any,
|
|
2577
|
+
failure: Schema16.Never,
|
|
2578
|
+
dependencies: [
|
|
2579
|
+
Database14.Service
|
|
2580
|
+
]
|
|
2581
|
+
}),
|
|
2582
|
+
//
|
|
2583
|
+
// Query
|
|
2584
|
+
//
|
|
2585
|
+
Tool3.make("query", {
|
|
2586
|
+
description: trim11`
|
|
2587
|
+
Queries objects in the space.
|
|
2588
|
+
Get the typename from the schema-list tool.
|
|
2589
|
+
`,
|
|
2590
|
+
parameters: {
|
|
2591
|
+
typename: Schema16.String
|
|
2592
|
+
},
|
|
2593
|
+
success: Schema16.Any,
|
|
2594
|
+
failure: Schema16.Never,
|
|
2595
|
+
dependencies: [
|
|
2596
|
+
Database14.Service
|
|
2597
|
+
]
|
|
2598
|
+
}),
|
|
2599
|
+
//
|
|
2600
|
+
// Objects
|
|
2601
|
+
//
|
|
2602
|
+
Tool3.make("object-create", {
|
|
2603
|
+
description: trim11`
|
|
2604
|
+
Creates a new object and adds it to the current space.
|
|
2605
|
+
Get the schema from the schema-list tool and ensure that the data matches the corresponding schema.
|
|
2606
|
+
`,
|
|
2607
|
+
parameters: {
|
|
2608
|
+
typename: Schema16.String,
|
|
2609
|
+
data: Schema16.Any
|
|
2610
|
+
},
|
|
2611
|
+
success: Schema16.Any,
|
|
2612
|
+
failure: Schema16.Never,
|
|
2613
|
+
dependencies: [
|
|
2614
|
+
Database14.Service
|
|
2615
|
+
]
|
|
2616
|
+
}),
|
|
2617
|
+
Tool3.make("object-delete", {
|
|
2618
|
+
description: trim11`
|
|
2619
|
+
Deletes the object.
|
|
2620
|
+
`,
|
|
2621
|
+
parameters: {
|
|
2622
|
+
id: ArtifactId7.annotations({
|
|
2623
|
+
description: "The ID of the object."
|
|
2624
|
+
})
|
|
2625
|
+
},
|
|
2626
|
+
success: Schema16.Any,
|
|
2627
|
+
failure: Schema16.Never,
|
|
2628
|
+
dependencies: [
|
|
2629
|
+
Database14.Service
|
|
2630
|
+
]
|
|
2631
|
+
}),
|
|
2632
|
+
Tool3.make("object-update", {
|
|
2633
|
+
description: trim11`
|
|
2634
|
+
Updates the object properties.
|
|
2635
|
+
`,
|
|
2636
|
+
parameters: {
|
|
2637
|
+
id: ArtifactId7.annotations({
|
|
2638
|
+
description: "The ID of the object."
|
|
2639
|
+
}),
|
|
2640
|
+
properties: Schema16.Record({
|
|
2641
|
+
key: Schema16.String,
|
|
2642
|
+
value: Schema16.Any
|
|
2643
|
+
})
|
|
2644
|
+
},
|
|
2645
|
+
success: Schema16.Any,
|
|
2646
|
+
failure: Schema16.Never,
|
|
2647
|
+
dependencies: [
|
|
2648
|
+
Database14.Service
|
|
2649
|
+
]
|
|
2650
|
+
}),
|
|
2651
|
+
//
|
|
2652
|
+
// Relations
|
|
2653
|
+
//
|
|
2654
|
+
Tool3.make("relation-create", {
|
|
2655
|
+
description: trim11`
|
|
2656
|
+
Creates a new relation and adds it to the current space.
|
|
2657
|
+
Get the schema from the schema-list tool and ensure that the data matches the corresponding schema.
|
|
2658
|
+
`,
|
|
2659
|
+
parameters: {
|
|
2660
|
+
typename: Schema16.String,
|
|
2661
|
+
source: ArtifactId7.annotations({
|
|
2662
|
+
description: "The ID of the source object."
|
|
2663
|
+
}),
|
|
2664
|
+
target: ArtifactId7.annotations({
|
|
2665
|
+
description: "The ID of the target object."
|
|
2666
|
+
}),
|
|
2667
|
+
data: Schema16.Any.annotations({
|
|
2668
|
+
description: "The data to be stored in the relation."
|
|
2669
|
+
})
|
|
2670
|
+
},
|
|
2671
|
+
success: Schema16.Any,
|
|
2672
|
+
failure: Schema16.Never,
|
|
2673
|
+
dependencies: [
|
|
2674
|
+
Database14.Service
|
|
2675
|
+
]
|
|
2676
|
+
}),
|
|
2677
|
+
Tool3.make("relation-delete", {
|
|
2678
|
+
description: trim11`
|
|
2679
|
+
Deletes the relation.
|
|
2680
|
+
`,
|
|
2681
|
+
parameters: {
|
|
2682
|
+
id: ArtifactId7.annotations({
|
|
2683
|
+
description: "The ID of the relation."
|
|
2684
|
+
})
|
|
2685
|
+
},
|
|
2686
|
+
success: Schema16.Any,
|
|
2687
|
+
failure: Schema16.Never,
|
|
2688
|
+
dependencies: [
|
|
2689
|
+
Database14.Service
|
|
2690
|
+
]
|
|
2691
|
+
}),
|
|
2692
|
+
//
|
|
2693
|
+
// Tags
|
|
2694
|
+
//
|
|
2695
|
+
Tool3.make("tag-add", {
|
|
2696
|
+
description: trim11`
|
|
2697
|
+
Adds a tag to an object.
|
|
2698
|
+
Tags are objects of type ${Tag2.Tag.typename}.
|
|
2699
|
+
`,
|
|
2700
|
+
parameters: {
|
|
2701
|
+
tagId: ArtifactId7.annotations({
|
|
2702
|
+
description: "The ID of the tag."
|
|
2703
|
+
}),
|
|
2704
|
+
objectId: ArtifactId7.annotations({
|
|
2705
|
+
description: "The ID of the object."
|
|
2706
|
+
})
|
|
2707
|
+
},
|
|
2708
|
+
success: Schema16.Any,
|
|
2709
|
+
failure: Schema16.Never,
|
|
2710
|
+
dependencies: [
|
|
2711
|
+
Database14.Service
|
|
2712
|
+
]
|
|
2713
|
+
}),
|
|
2714
|
+
Tool3.make("tag-remove", {
|
|
2715
|
+
description: trim11`
|
|
2716
|
+
Removes a tag from an object.
|
|
2717
|
+
Tags are objects of type ${Tag2.Tag.typename}.
|
|
2718
|
+
`,
|
|
2719
|
+
parameters: {
|
|
2720
|
+
tagId: ArtifactId7.annotations({
|
|
2721
|
+
description: "The ID of the tag."
|
|
2722
|
+
}),
|
|
2723
|
+
objectId: ArtifactId7.annotations({
|
|
2724
|
+
description: "The ID of the object."
|
|
2725
|
+
})
|
|
2726
|
+
},
|
|
2727
|
+
success: Schema16.Any,
|
|
2728
|
+
failure: Schema16.Never,
|
|
2729
|
+
dependencies: [
|
|
2730
|
+
Database14.Service
|
|
2731
|
+
]
|
|
2732
|
+
})
|
|
2733
|
+
);
|
|
2734
|
+
var tools2 = Record2.keys(SystemToolkit.tools);
|
|
2735
|
+
var layer4 = () => SystemToolkit.toLayer({
|
|
2736
|
+
["schema-list"]: Effect17.fnUntraced(function* () {
|
|
2737
|
+
const { db } = yield* Database14.Service;
|
|
2738
|
+
const schema = yield* Effect17.promise(() => db.schemaRegistry.query({
|
|
2739
|
+
location: [
|
|
2740
|
+
"database",
|
|
2741
|
+
"runtime"
|
|
2742
|
+
]
|
|
2743
|
+
}).run());
|
|
2744
|
+
return schema.map((schema2) => {
|
|
2745
|
+
const meta = Type5.getMeta(schema2);
|
|
2746
|
+
return {
|
|
2747
|
+
typename: Type5.getTypename(schema2),
|
|
2748
|
+
jsonSchema: Type5.toJsonSchema(schema2),
|
|
2749
|
+
kind: meta?.sourceSchema ? "relation" : "record"
|
|
2750
|
+
};
|
|
2751
|
+
});
|
|
2752
|
+
}),
|
|
2753
|
+
["schema-add"]: Effect17.fnUntraced(function* ({ name, typename, jsonSchema }) {
|
|
2754
|
+
const { db } = yield* Database14.Service;
|
|
2755
|
+
yield* Effect17.promise(() => db.schemaRegistry.register([
|
|
2756
|
+
{
|
|
2757
|
+
typename,
|
|
2758
|
+
version: "0.1.0",
|
|
2759
|
+
jsonSchema,
|
|
2760
|
+
name
|
|
2761
|
+
}
|
|
2762
|
+
]));
|
|
2763
|
+
}),
|
|
2764
|
+
["query"]: Effect17.fnUntraced(function* ({ typename }) {
|
|
2765
|
+
const objects = yield* Database14.Service.runQuery(Filter5.typename(typename));
|
|
2766
|
+
return objects;
|
|
2767
|
+
}),
|
|
2768
|
+
["object-create"]: Effect17.fnUntraced(function* ({ typename, data }) {
|
|
2769
|
+
const { db } = yield* Database14.Service;
|
|
2770
|
+
const schema = yield* Effect17.promise(() => db.schemaRegistry.query({
|
|
2771
|
+
typename,
|
|
2772
|
+
location: [
|
|
2773
|
+
"database",
|
|
2774
|
+
"runtime"
|
|
2775
|
+
]
|
|
2776
|
+
}).first());
|
|
2777
|
+
invariant(Type5.isObjectSchema(schema), "Schema is not an object schema", {
|
|
2778
|
+
F: __dxlog_file8,
|
|
2779
|
+
L: 238,
|
|
2780
|
+
S: this,
|
|
2781
|
+
A: [
|
|
2782
|
+
"Type.isObjectSchema(schema)",
|
|
2783
|
+
"'Schema is not an object schema'"
|
|
2784
|
+
]
|
|
2785
|
+
});
|
|
2786
|
+
const object = db.add(Obj11.make(schema, data));
|
|
2787
|
+
return object;
|
|
2788
|
+
}),
|
|
2789
|
+
["object-delete"]: Effect17.fnUntraced(function* ({ id }) {
|
|
2790
|
+
const { db } = yield* Database14.Service;
|
|
2791
|
+
const object = yield* Database14.Service.resolve(DXN2.parse(id));
|
|
2792
|
+
db.remove(object);
|
|
2793
|
+
return object;
|
|
2794
|
+
}),
|
|
2795
|
+
["object-update"]: Effect17.fnUntraced(function* ({ id, properties }) {
|
|
2796
|
+
const object = yield* Database14.Service.resolve(DXN2.parse(id));
|
|
2797
|
+
Entity3.change(object, (obj) => {
|
|
2798
|
+
for (const [key, value2] of Object.entries(properties)) {
|
|
2799
|
+
obj[key] = value2;
|
|
2800
|
+
}
|
|
2801
|
+
});
|
|
2802
|
+
return object;
|
|
2803
|
+
}),
|
|
2804
|
+
["relation-create"]: Effect17.fnUntraced(function* ({ typename, source, target, data }) {
|
|
2805
|
+
const { db } = yield* Database14.Service;
|
|
2806
|
+
const schema = yield* Effect17.promise(() => db.schemaRegistry.query({
|
|
2807
|
+
typename,
|
|
2808
|
+
location: [
|
|
2809
|
+
"database",
|
|
2810
|
+
"runtime"
|
|
2811
|
+
]
|
|
2812
|
+
}).first());
|
|
2813
|
+
invariant(Type5.isRelationSchema(schema), "Schema is not a relation schema", {
|
|
2814
|
+
F: __dxlog_file8,
|
|
2815
|
+
L: 267,
|
|
2816
|
+
S: this,
|
|
2817
|
+
A: [
|
|
2818
|
+
"Type.isRelationSchema(schema)",
|
|
2819
|
+
"'Schema is not a relation schema'"
|
|
2820
|
+
]
|
|
2821
|
+
});
|
|
2822
|
+
const sourceObj = yield* Database14.Service.resolve(DXN2.parse(source));
|
|
2823
|
+
const targetObj = yield* Database14.Service.resolve(DXN2.parse(target));
|
|
2824
|
+
const relation = db.add(Relation2.make(schema, {
|
|
2825
|
+
[Relation2.Source]: sourceObj,
|
|
2826
|
+
[Relation2.Target]: targetObj,
|
|
2827
|
+
...data
|
|
2828
|
+
}));
|
|
2829
|
+
return relation;
|
|
2830
|
+
}),
|
|
2831
|
+
["relation-delete"]: Effect17.fnUntraced(function* ({ id }) {
|
|
2832
|
+
const { db } = yield* Database14.Service;
|
|
2833
|
+
const relation = yield* Database14.Service.resolve(DXN2.parse(id));
|
|
2834
|
+
db.remove(relation);
|
|
2835
|
+
return relation;
|
|
2836
|
+
}),
|
|
2837
|
+
["tag-add"]: Effect17.fnUntraced(function* ({ tagId, objectId }) {
|
|
2838
|
+
const object = yield* Database14.Service.resolve(DXN2.parse(objectId));
|
|
2839
|
+
Entity3.change(object, (obj) => Entity3.addTag(obj, DXN2.parse(tagId).toString()));
|
|
2840
|
+
return object;
|
|
2841
|
+
}),
|
|
2842
|
+
["tag-remove"]: Effect17.fnUntraced(function* ({ tagId, objectId }) {
|
|
2843
|
+
const object = yield* Database14.Service.resolve(DXN2.parse(objectId));
|
|
2844
|
+
Entity3.change(object, (obj) => Entity3.removeTag(obj, DXN2.parse(tagId).toString()));
|
|
2845
|
+
return object;
|
|
2846
|
+
})
|
|
2847
|
+
});
|
|
2450
2848
|
export {
|
|
2451
2849
|
Agent,
|
|
2850
|
+
AssistantToolkit_exports as AssistantToolkit,
|
|
2452
2851
|
design_default as DesignBlueprint,
|
|
2453
2852
|
Discord,
|
|
2454
2853
|
discord_default as DiscordBlueprint,
|
|
@@ -2458,17 +2857,16 @@ export {
|
|
|
2458
2857
|
linear_default as LinearBlueprint,
|
|
2459
2858
|
LocalSearchHandler,
|
|
2460
2859
|
LocalSearchToolkit,
|
|
2461
|
-
MapSchema,
|
|
2462
2860
|
planning_default as PlanningBlueprint,
|
|
2463
2861
|
Research,
|
|
2464
2862
|
research_default2 as ResearchBlueprint,
|
|
2465
2863
|
ResearchDataTypes,
|
|
2466
2864
|
ResearchGraph,
|
|
2467
2865
|
Subgraph,
|
|
2866
|
+
SystemToolkit_exports as SystemToolkit,
|
|
2468
2867
|
Tasks,
|
|
2469
2868
|
websearch_default as WebSearchBlueprint,
|
|
2470
2869
|
WebSearchToolkit,
|
|
2471
|
-
capabilities,
|
|
2472
2870
|
contextQueueLayerFromResearchGraph,
|
|
2473
2871
|
createExtractionSchema,
|
|
2474
2872
|
createResearchGraph,
|