@dbx-tools/appkit-memory 0.0.0-stage → 0.9.131
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/LICENSE +202 -0
- package/README.md +78 -2
- package/index.ts +17 -0
- package/lib/index.d.ts +13 -0
- package/lib/index.js +14 -0
- package/lib/smoke/mastra-tool.d.ts +1 -0
- package/lib/smoke/mastra-tool.js +46 -0
- package/lib/src/_contracts.d.ts +71 -0
- package/lib/src/_contracts.js +63 -0
- package/lib/src/_mastra.d.ts +11 -0
- package/lib/src/_mastra.js +66 -0
- package/lib/src/config.d.ts +70 -0
- package/lib/src/config.js +87 -0
- package/lib/src/databricks/_runtime.d.ts +18 -0
- package/lib/src/databricks/_runtime.js +79 -0
- package/lib/src/databricks/client.d.ts +48 -0
- package/lib/src/databricks/client.js +174 -0
- package/lib/src/databricks/index.d.ts +3 -0
- package/lib/src/databricks/index.js +6 -0
- package/lib/src/graphiti/_backend.d.ts +9 -0
- package/lib/src/graphiti/_backend.js +214 -0
- package/lib/src/graphiti/index.d.ts +3 -0
- package/lib/src/graphiti/index.js +6 -0
- package/lib/src/graphiti/options.d.ts +7 -0
- package/lib/src/graphiti/options.js +7 -0
- package/lib/src/graphiti/runtime.d.ts +49 -0
- package/lib/src/graphiti/runtime.js +170 -0
- package/lib/src/plugin.d.ts +38 -0
- package/lib/src/plugin.js +196 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/package.json +104 -4
- package/src/_contracts.ts +107 -0
- package/src/_mastra.ts +80 -0
- package/src/config.ts +134 -0
- package/src/databricks/_runtime.ts +103 -0
- package/src/databricks/client.ts +251 -0
- package/src/databricks/index.ts +7 -0
- package/src/graphiti/_backend.ts +282 -0
- package/src/graphiti/index.ts +7 -0
- package/src/graphiti/options.ts +17 -0
- package/src/graphiti/runtime.ts +261 -0
- package/src/plugin.ts +254 -0
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy Graphiti implementation of the backend-neutral memory contract.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
7
|
+
import { createServer } from "node:net";
|
|
8
|
+
import { ConfigurationError } from "@databricks/appkit";
|
|
9
|
+
import { openApiTools } from "@dbx-tools/appkit/openapi-tool";
|
|
10
|
+
import { profile as authProfile } from "@dbx-tools/auth";
|
|
11
|
+
import { configUtils } from "@dbx-tools/core";
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
import { graphitiOptionOverrides, graphitiOptionsFromEnvironment, resolveGraphitiOptions, } from "./options.js";
|
|
14
|
+
import { createGraphitiChildProcess, graphitiHealthCheck, graphitiHttpUrl, graphitiRequestHeaders, } from "./runtime.js";
|
|
15
|
+
const GraphitiFactSchema = z
|
|
16
|
+
.object({
|
|
17
|
+
name: z.string().optional().describe("Graphiti fact name."),
|
|
18
|
+
fact: z.string().describe("Retrieved graph fact."),
|
|
19
|
+
})
|
|
20
|
+
.loose()
|
|
21
|
+
.describe("Graphiti fact search result.");
|
|
22
|
+
const GraphitiFactSearchSchema = z
|
|
23
|
+
.object({
|
|
24
|
+
facts: z.array(GraphitiFactSchema).optional().describe("Matching graph facts."),
|
|
25
|
+
error: z.string().optional().describe("Graphiti operation error."),
|
|
26
|
+
})
|
|
27
|
+
.loose()
|
|
28
|
+
.describe("Graphiti fact search response.");
|
|
29
|
+
const GraphitiWriteSchema = z
|
|
30
|
+
.object({
|
|
31
|
+
message: z.string().optional().describe("Graphiti write confirmation."),
|
|
32
|
+
error: z.string().optional().describe("Graphiti operation error."),
|
|
33
|
+
})
|
|
34
|
+
.loose()
|
|
35
|
+
.describe("Graphiti write response.");
|
|
36
|
+
class GraphitiBackend {
|
|
37
|
+
options;
|
|
38
|
+
child;
|
|
39
|
+
writeTool;
|
|
40
|
+
recallTool;
|
|
41
|
+
constructor(options, child, writeTool, recallTool) {
|
|
42
|
+
this.options = options;
|
|
43
|
+
this.child = child;
|
|
44
|
+
this.writeTool = writeTool;
|
|
45
|
+
this.recallTool = recallTool;
|
|
46
|
+
}
|
|
47
|
+
get running() {
|
|
48
|
+
return ((this.child.exitCode === null || this.child.exitCode === undefined) &&
|
|
49
|
+
(this.child.signalCode === null || this.child.signalCode === undefined));
|
|
50
|
+
}
|
|
51
|
+
async remember(actorId, input, signal) {
|
|
52
|
+
await this.write(actorId, {
|
|
53
|
+
name: input.path,
|
|
54
|
+
episode_body: input.content,
|
|
55
|
+
source: "text",
|
|
56
|
+
source_description: input.description ? `${input.path}: ${input.description}` : input.path,
|
|
57
|
+
}, signal);
|
|
58
|
+
return {
|
|
59
|
+
backend: "graphiti",
|
|
60
|
+
memory: {
|
|
61
|
+
path: input.path,
|
|
62
|
+
content: input.content,
|
|
63
|
+
...(input.description ? { description: input.description } : {}),
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
async recall(actorId, input, signal) {
|
|
68
|
+
const response = GraphitiFactSearchSchema.parse(await this.request(this.recallTool, {
|
|
69
|
+
query: input.query,
|
|
70
|
+
max_facts: input.limit,
|
|
71
|
+
group_ids: [userScope(actorId)],
|
|
72
|
+
}, signal));
|
|
73
|
+
if (response.error)
|
|
74
|
+
throw new Error(response.error);
|
|
75
|
+
return {
|
|
76
|
+
backend: "graphiti",
|
|
77
|
+
memories: (response.facts ?? []).map((fact) => ({
|
|
78
|
+
content: fact.fact,
|
|
79
|
+
...(fact.name ? { description: fact.name } : {}),
|
|
80
|
+
})),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
async saveTurn(turn, signal) {
|
|
84
|
+
await this.write(turn.actorId, {
|
|
85
|
+
name: `Mastra turn ${turn.agentId}/${turn.threadId}`,
|
|
86
|
+
episode_body: `User: ${turn.user}\n\nAssistant: ${turn.assistant}`,
|
|
87
|
+
source: "message",
|
|
88
|
+
source_description: `Completed ${turn.agentId} conversation turn`,
|
|
89
|
+
}, signal);
|
|
90
|
+
}
|
|
91
|
+
shutdown() {
|
|
92
|
+
return this.child.shutdown();
|
|
93
|
+
}
|
|
94
|
+
async write(actorId, args, signal) {
|
|
95
|
+
const response = GraphitiWriteSchema.parse(await this.request(this.writeTool, { ...args, group_id: userScope(actorId) }, signal));
|
|
96
|
+
if (response.error)
|
|
97
|
+
throw new Error(response.error);
|
|
98
|
+
}
|
|
99
|
+
async request(tool, args, signal) {
|
|
100
|
+
if (!this.running)
|
|
101
|
+
throw new Error("Graphiti sidecar is not running");
|
|
102
|
+
const response = await fetch(tool.url, {
|
|
103
|
+
method: tool.method,
|
|
104
|
+
headers: {
|
|
105
|
+
...graphitiRequestHeaders(this.options),
|
|
106
|
+
"content-type": "application/json",
|
|
107
|
+
},
|
|
108
|
+
body: JSON.stringify(args),
|
|
109
|
+
signal,
|
|
110
|
+
});
|
|
111
|
+
if (!response.ok) {
|
|
112
|
+
throw new Error(`Graphiti operation ${tool.id} failed with HTTP ${response.status}: ${await response.text()}`);
|
|
113
|
+
}
|
|
114
|
+
return response.json();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/** Start a fully ready Graphiti backend for the first fallback operation. */
|
|
118
|
+
export async function startGraphitiBackend(options, signal) {
|
|
119
|
+
const configured = resolveGraphitiConfig(options);
|
|
120
|
+
if (configured.listen.scheme !== "tcp") {
|
|
121
|
+
throw new Error("AppKit memory requires a TCP Graphiti listener");
|
|
122
|
+
}
|
|
123
|
+
const [graphitiPort] = await distinctPorts(configUtils.port(undefined, "DATABRICKS_APP_PORT", 8000, configUtils.ENV_ONLY), configured.listen.port);
|
|
124
|
+
const resolved = resolveGraphitiOptions({
|
|
125
|
+
...configured,
|
|
126
|
+
bearer: randomBytes(32).toString("base64url"),
|
|
127
|
+
listen: { ...configured.listen, port: graphitiPort },
|
|
128
|
+
});
|
|
129
|
+
let tools;
|
|
130
|
+
const { child } = await createGraphitiChildProcess({
|
|
131
|
+
...resolved,
|
|
132
|
+
...(signal ? { signal } : {}),
|
|
133
|
+
healthCheck: async ({ signal }) => {
|
|
134
|
+
try {
|
|
135
|
+
if (!(await graphitiHealthCheck(resolved, signal)))
|
|
136
|
+
return false;
|
|
137
|
+
const loaded = await openApiTools(graphitiHttpUrl(resolved, "/openapi.json"), {
|
|
138
|
+
signal,
|
|
139
|
+
headers: graphitiRequestHeaders(resolved),
|
|
140
|
+
});
|
|
141
|
+
tools = [
|
|
142
|
+
requiredOperation(loaded, "add_memory_sync"),
|
|
143
|
+
requiredOperation(loaded, "search_memory_facts"),
|
|
144
|
+
];
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
if (signal.aborted)
|
|
149
|
+
throw error;
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
if (!tools) {
|
|
155
|
+
await child.shutdown();
|
|
156
|
+
throw new Error("Graphiti OpenAPI tools were not captured during readiness");
|
|
157
|
+
}
|
|
158
|
+
return new GraphitiBackend(resolved, child, tools[0], tools[1]);
|
|
159
|
+
}
|
|
160
|
+
function resolveGraphitiConfig(options) {
|
|
161
|
+
const environment = graphitiOptionsFromEnvironment(process.env);
|
|
162
|
+
if (environment.profile && !authProfile.resolveProfile({ profile: environment.profile })) {
|
|
163
|
+
environment.profile = undefined;
|
|
164
|
+
}
|
|
165
|
+
const overrides = graphitiOptionOverrides(options);
|
|
166
|
+
return resolveGraphitiOptions({
|
|
167
|
+
...environment,
|
|
168
|
+
...overrides,
|
|
169
|
+
listen: overrides.listen ??
|
|
170
|
+
environment.listen ?? {
|
|
171
|
+
scheme: "tcp",
|
|
172
|
+
host: "127.0.0.1",
|
|
173
|
+
port: 0,
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
function requiredOperation(tools, name) {
|
|
178
|
+
const tool = tools.find(({ id }) => id === name);
|
|
179
|
+
if (!tool)
|
|
180
|
+
throw new Error(`Graphiti OpenAPI is missing operation: ${name}`);
|
|
181
|
+
return tool;
|
|
182
|
+
}
|
|
183
|
+
function userScope(userId) {
|
|
184
|
+
return `user_${createHash("sha256").update(userId).digest("base64url")}`;
|
|
185
|
+
}
|
|
186
|
+
async function availablePort() {
|
|
187
|
+
return new Promise((resolve, reject) => {
|
|
188
|
+
const server = createServer();
|
|
189
|
+
server.once("error", reject);
|
|
190
|
+
server.listen(0, "127.0.0.1", () => {
|
|
191
|
+
const address = server.address();
|
|
192
|
+
if (!address || typeof address === "string") {
|
|
193
|
+
server.close();
|
|
194
|
+
reject(new Error("Could not allocate a Graphiti loopback port"));
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
server.close((error) => (error ? reject(error) : resolve(address.port)));
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
async function distinctPorts(appPort, graphitiPort) {
|
|
202
|
+
const ports = [appPort];
|
|
203
|
+
for (const configuredPort of [graphitiPort]) {
|
|
204
|
+
if (configuredPort && ports.includes(configuredPort)) {
|
|
205
|
+
throw new ConfigurationError("Graphiti sidecar ports must differ from DATABRICKS_APP_PORT");
|
|
206
|
+
}
|
|
207
|
+
let port = configuredPort || (await availablePort());
|
|
208
|
+
while (ports.includes(port))
|
|
209
|
+
port = await availablePort();
|
|
210
|
+
ports.push(port);
|
|
211
|
+
}
|
|
212
|
+
return ports.slice(1);
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2JhY2tlbmQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZ3JhcGhpdGkvX2JhY2tlbmQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRztBQUVILE9BQU8sRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3RELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDeEMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDeEQsT0FBTyxFQUFFLFlBQVksRUFBb0IsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNoRixPQUFPLEVBQUUsT0FBTyxJQUFJLFdBQVcsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUU5QyxPQUFPLEVBQUUsQ0FBQyxFQUFFLE1BQU0sS0FBSyxDQUFDO0FBVXhCLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsOEJBQThCLEVBQzlCLHNCQUFzQixHQUd2QixNQUFNLGNBQWMsQ0FBQztBQUN0QixPQUFPLEVBQ0wsMEJBQTBCLEVBQzFCLG1CQUFtQixFQUNuQixlQUFlLEVBQ2Ysc0JBQXNCLEdBQ3ZCLE1BQU0sY0FBYyxDQUFDO0FBRXRCLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQztLQUN6QixNQUFNLENBQUM7SUFDTixJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQztJQUMzRCxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyx1QkFBdUIsQ0FBQztDQUNuRCxDQUFDO0tBQ0QsS0FBSyxFQUFFO0tBQ1AsUUFBUSxDQUFDLDhCQUE4QixDQUFDLENBQUM7QUFFNUMsTUFBTSx3QkFBd0IsR0FBRyxDQUFDO0tBQy9CLE1BQU0sQ0FBQztJQUNOLEtBQUssRUFB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LENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMzRSxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELEtBQUssVUFBVSxhQUFhLENBQUMsT0FBZSxFQUFFLFlBQW9CO0lBQ2hFLE1BQU0sS0FBSyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDeEIsS0FBSyxNQUFNLGNBQWMsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7UUFDNUMsSUFBSSxjQUFjLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDO1lBQ3JELE1BQU0sSUFBSSxrQkFBa0IsQ0FBQyw2REFBNkQsQ0FBQyxDQUFDO1FBQzlGLENBQUM7UUFDRCxJQUFJLElBQUksR0FBRyxjQUFjLElBQUksQ0FBQyxNQUFNLGFBQWEsRUFBRSxDQUFDLENBQUM7UUFDckQsT0FBTyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQztZQUFFLElBQUksR0FBRyxNQUFNLGFBQWEsRUFBRSxDQUFDO1FBQzFELEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbkIsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQWEsQ0FBQztBQUNwQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBMYXp5IEdyYXBoaXRpIGltcGxlbWVudGF0aW9uIG9mIHRoZSBiYWNrZW5kLW5ldXRyYWwgbWVtb3J5IGNvbnRyYWN0LlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBjcmVhdGVIYXNoLCByYW5kb21CeXRlcyB9IGZyb20gXCJub2RlOmNyeXB0b1wiO1xuaW1wb3J0IHsgY3JlYXRlU2VydmVyIH0gZnJvbSBcIm5vZGU6bmV0XCI7XG5pbXBvcnQgeyBDb25maWd1cmF0aW9uRXJyb3IgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBvcGVuQXBpVG9vbHMsIHR5cGUgT3BlbkFwaVRvb2wgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXQvb3BlbmFwaS10b29sXCI7XG5pbXBvcnQgeyBwcm9maWxlIGFzIGF1dGhQcm9maWxlIH0gZnJvbSBcIkBkYngtdG9vbHMvYXV0aFwiO1xuaW1wb3J0IHsgY29uZmlnVXRpbHMgfSBmcm9tIFwiQGRieC10b29scy9jb3JlXCI7XG5pbXBvcnQgdHlwZSB7IENoaWxkUHJvY2Vzc1Jlc3VsdCB9IGZyb20gXCJAZGJ4LXRvb2xzL2NvcmUvZXhlY1wiO1xuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIjtcblxuaW1wb3J0IHtcbiAgdHlwZSBHcmFwaGl0aU1lbW9yeUJhY2tlbmQsXG4gIHR5cGUgTWVtb3J5VHVybixcbiAgdHlwZSBSZWNhbGxNZW1vcnlJbnB1dCxcbiAgdHlwZSBSZWNhbGxNZW1vcnlSZXN1bHQsXG4gIHR5cGUgUmVtZW1iZXJNZW1vcnlJbnB1dCxcbiAgdHlwZSBSZW1lbWJlck1lbW9yeVJlc3VsdCxcbn0gZnJvbSBcIi4uL19jb250cmFjdHMudHNcIjtcbmltcG9ydCB7XG4gIGdyYXBoaXRpT3B0aW9uT3ZlcnJpZGVzLFxuICBncmFwaGl0aU9wdGlvbnNGcm9tRW52aXJvbm1lbnQsXG4gIHJlc29sdmVHcmFwaGl0aU9wdGlvbnMsXG4gIHR5cGUgR3JhcGhpdGlPcHRpb25zLFxuICB0eXBlIFJlc29sdmVkR3JhcGhpdGlPcHRpb25zLFxufSBmcm9tIFwiLi9vcHRpb25zLnRzXCI7XG5pbXBvcnQge1xuICBjcmVhdGVHcmFwaGl0aUNoaWxkUHJvY2VzcyxcbiAgZ3JhcGhpdGlIZWFsdGhDaGVjayxcbiAgZ3JhcGhpdGlIdHRwVXJsLFxuICBncmFwaGl0aVJlcXVlc3RIZWFkZXJzLFxufSBmcm9tIFwiLi9ydW50aW1lLnRzXCI7XG5cbmNvbnN0IEdyYXBoaXRpRmFjdFNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgbmFtZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLmRlc2NyaWJlKFwiR3JhcGhpdGkgZmFjdCBuYW1lLlwiKSxcbiAgICBmYWN0OiB6LnN0cmluZygpLmRlc2NyaWJlKFwiUmV0cmlldmVkIGdyYXBoIGZhY3QuXCIpLFxuICB9KVxuICAubG9vc2UoKVxuICAuZGVzY3JpYmUoXCJHcmFwaGl0aSBmYWN0IHNlYXJjaCByZXN1bHQuXCIpO1xuXG5jb25zdCBHcmFwaGl0aUZhY3RTZWFyY2hTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIGZhY3RzOiB6LmFycmF5KEdyYXBoaXRpRmFjdFNjaGVtYSkub3B0aW9uYWwoKS5kZXNjcmliZShcIk1hdGNoaW5nIGdyYXBoIGZhY3RzLlwiKSxcbiAgICBlcnJvcjogei5zdHJpbmcoKS5vcHRpb25hbCgpLmRlc2NyaWJlKFwiR3JhcGhpdGkgb3BlcmF0aW9uIGVycm9yLlwiKSxcbiAgfSlcbiAgLmxvb3NlKClcbiAgLmRlc2NyaWJlKFwiR3JhcGhpdGkgZmFjdCBzZWFyY2ggcmVzcG9uc2UuXCIpO1xuXG5jb25zdCBHcmFwaGl0aVdyaXRlU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICBtZXNzYWdlOiB6LnN0cmluZygpLm9wdGlvbmFsKCkuZGVzY3JpYmUoXCJHcmFwaGl0aSB3cml0ZSBjb25maXJtYXRpb24uXCIpLFxuICAgIGVycm9yOiB6LnN0cmluZygpLm9wdGlvbmFsKCkuZGVzY3JpYmUoXCJHcmFwaGl0aSBvcGVyYXRpb24gZXJyb3IuXCIpLFxuICB9KVxuICAubG9vc2UoKVxuICAuZGVzY3JpYmUoXCJHcmFwaGl0aSB3cml0ZSByZXNwb25zZS5cIik7XG5cbmNsYXNzIEdyYXBoaXRpQmFja2VuZCBpbXBsZW1lbnRzIEdyYXBoaXRpTWVtb3J5QmFja2VuZCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgb3B0aW9uczogUmVzb2x2ZWRHcmFwaGl0aU9wdGlvbnMsXG4gICAgcHJpdmF0ZSByZWFkb25seSBjaGlsZDogQ2hpbGRQcm9jZXNzUmVzdWx0LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgd3JpdGVUb29sOiBPcGVuQXBpVG9vbCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJlY2FsbFRvb2w6IE9wZW5BcGlUb29sLFxuICApIHt9XG5cbiAgZ2V0IHJ1bm5pbmcoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgICh0aGlzLmNoaWxkLmV4aXRDb2RlID09PSBudWxsIHx8IHRoaXMuY2hpbGQuZXhpdENvZGUgPT09IHVuZGVmaW5lZCkgJiZcbiAgICAgICh0aGlzLmNoaWxkLnNpZ25hbENvZGUgPT09IG51bGwgfHwgdGhpcy5jaGlsZC5zaWduYWxDb2RlID09PSB1bmRlZmluZWQpXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIHJlbWVtYmVyKFxuICAgIGFjdG9ySWQ6IHN0cmluZyxcbiAgICBpbnB1dDogUmVtZW1iZXJNZW1vcnlJbnB1dCxcbiAgICBzaWduYWw/OiBBYm9ydFNpZ25hbCxcbiAgKTogUHJvbWlzZTxSZW1lbWJlck1lbW9yeVJlc3VsdD4ge1xuICAgIGF3YWl0IHRoaXMud3JpdGUoXG4gICAgICBhY3RvcklkLFxuICAgICAge1xuICAgICAgICBuYW1lOiBpbnB1dC5wYXRoLFxuICAgICAgICBlcGlzb2RlX2JvZHk6IGlucHV0LmNvbnRlbnQsXG4gICAgICAgIHNvdXJjZTogXCJ0ZXh0XCIsXG4gICAgICAgIHNvdXJjZV9kZXNjcmlwdGlvbjogaW5wdXQuZGVzY3JpcHRpb24gPyBgJHtpbnB1dC5wYXRofTogJHtpbnB1dC5kZXNjcmlwdGlvbn1gIDogaW5wdXQucGF0aCxcbiAgICAgIH0sXG4gICAgICBzaWduYWwsXG4gICAgKTtcbiAgICByZXR1cm4ge1xuICAgICAgYmFja2VuZDogXCJncmFwaGl0aVwiLFxuICAgICAgbWVtb3J5OiB7XG4gICAgICAgIHBhdGg6IGlucHV0LnBhdGgsXG4gICAgICAgIGNvbnRlbnQ6IGlucHV0LmNvbnRlbnQsXG4gICAgICAgIC4uLihpbnB1dC5kZXNjcmlwdGlvbiA/IHsgZGVzY3JpcHRpb246IGlucHV0LmRlc2NyaXB0aW9uIH0gOiB7fSksXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBhc3luYyByZWNhbGwoXG4gICAgYWN0b3JJZDogc3RyaW5nLFxuICAgIGlucHV0OiBSZWNhbGxNZW1vcnlJbnB1dCxcbiAgICBzaWduYWw/OiBBYm9ydFNpZ25hbCxcbiAgKTogUHJvbWlzZTxSZWNhbGxNZW1vcnlSZXN1bHQ+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IEdyYXBoaXRpRmFjdFNlYXJjaFNjaGVtYS5wYXJzZShcbiAgICAgIGF3YWl0IHRoaXMucmVxdWVzdChcbiAgICAgICAgdGhpcy5yZWNhbGxUb29sLFxuICAgICAgICB7XG4gICAgICAgICAgcXVlcnk6IGlucHV0LnF1ZXJ5LFxuICAgICAgICAgIG1heF9mYWN0czogaW5wdXQubGltaXQsXG4gICAgICAgICAgZ3JvdXBfaWRzOiBbdXNlclNjb3BlKGFjdG9ySWQpXSxcbiAgICAgICAgfSxcbiAgICAgICAgc2lnbmFsLFxuICAgICAgKSxcbiAgICApO1xuICAgIGlmIChyZXNwb25zZS5lcnJvcikgdGhyb3cgbmV3IEVycm9yKHJlc3BvbnNlLmVycm9yKTtcbiAgICByZXR1cm4ge1xuICAgICAgYmFja2VuZDogXCJncmFwaGl0aVwiLFxuICAgICAgbWVtb3JpZXM6IChyZXNwb25zZS5mYWN0cyA/PyBbXSkubWFwKChmYWN0KSA9PiAoe1xuICAgICAgICBjb250ZW50OiBmYWN0LmZhY3QsXG4gICAgICAgIC4uLihmYWN0Lm5hbWUgPyB7IGRlc2NyaXB0aW9uOiBmYWN0Lm5hbWUgfSA6IHt9KSxcbiAgICAgIH0pKSxcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgc2F2ZVR1cm4odHVybjogTWVtb3J5VHVybiwgc2lnbmFsPzogQWJvcnRTaWduYWwpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLndyaXRlKFxuICAgICAgdHVybi5hY3RvcklkLFxuICAgICAge1xuICAgICAgICBuYW1lOiBgTWFzdHJhIHR1cm4gJHt0dXJuLmFnZW50SWR9LyR7dHVybi50aHJlYWRJZH1gLFxuICAgICAgICBlcGlzb2RlX2JvZHk6IGBVc2VyOiAke3R1cm4udXNlcn1cXG5cXG5Bc3Npc3RhbnQ6ICR7dHVybi5hc3Npc3RhbnR9YCxcbiAgICAgICAgc291cmNlOiBcIm1lc3NhZ2VcIixcbiAgICAgICAgc291cmNlX2Rlc2NyaXB0aW9uOiBgQ29tcGxldGVkICR7dHVybi5hZ2VudElkfSBjb252ZXJzYXRpb24gdHVybmAsXG4gICAgICB9LFxuICAgICAgc2lnbmFsLFxuICAgICk7XG4gIH1cblxuICBzaHV0ZG93bigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5jaGlsZC5zaHV0ZG93bigpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB3cml0ZShcbiAgICBhY3RvcklkOiBzdHJpbmcsXG4gICAgYXJnczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gICAgc2lnbmFsPzogQWJvcnRTaWduYWwsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gR3JhcGhpdGlXcml0ZVNjaGVtYS5wYXJzZShcbiAgICAgIGF3YWl0IHRoaXMucmVxdWVzdCh0aGlzLndyaXRlVG9vbCwgeyAuLi5hcmdzLCBncm91cF9pZDogdXNlclNjb3BlKGFjdG9ySWQpIH0sIHNpZ25hbCksXG4gICAgKTtcbiAgICBpZiAocmVzcG9uc2UuZXJyb3IpIHRocm93IG5ldyBFcnJvcihyZXNwb25zZS5lcnJvcik7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlcXVlc3QoXG4gICAgdG9vbDogT3BlbkFwaVRvb2wsXG4gICAgYXJnczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gICAgc2lnbmFsPzogQWJvcnRTaWduYWwsXG4gICk6IFByb21pc2U8dW5rbm93bj4ge1xuICAgIGlmICghdGhpcy5ydW5uaW5nKSB0aHJvdyBuZXcgRXJyb3IoXCJHcmFwaGl0aSBzaWRlY2FyIGlzIG5vdCBydW5uaW5nXCIpO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godG9vbC51cmwsIHtcbiAgICAgIG1ldGhvZDogdG9vbC5tZXRob2QsXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgIC4uLmdyYXBoaXRpUmVxdWVzdEhlYWRlcnModGhpcy5vcHRpb25zKSxcbiAgICAgICAgXCJjb250ZW50LXR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIsXG4gICAgICB9LFxuICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoYXJncyksXG4gICAgICBzaWduYWwsXG4gICAgfSk7XG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgR3JhcGhpdGkgb3BlcmF0aW9uICR7dG9vbC5pZH0gZmFpbGVkIHdpdGggSFRUUCAke3Jlc3BvbnNlLnN0YXR1c306ICR7YXdhaXQgcmVzcG9uc2UudGV4dCgpfWAsXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpO1xuICB9XG59XG5cbi8qKiBTdGFydCBhIGZ1bGx5IHJlYWR5IEdyYXBoaXRpIGJhY2tlbmQgZm9yIHRoZSBmaXJzdCBmYWxsYmFjayBvcGVyYXRpb24uICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RhcnRHcmFwaGl0aUJhY2tlbmQoXG4gIG9wdGlvbnM6IEdyYXBoaXRpT3B0aW9ucyxcbiAgc2lnbmFsPzogQWJvcnRTaWduYWwsXG4pOiBQcm9taXNlPEdyYXBoaXRpTWVtb3J5QmFja2VuZD4ge1xuICBjb25zdCBjb25maWd1cmVkID0gcmVzb2x2ZUdyYXBoaXRpQ29uZmlnKG9wdGlvbnMpO1xuICBpZiAoY29uZmlndXJlZC5saXN0ZW4uc2NoZW1lICE9PSBcInRjcFwiKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiQXBwS2l0IG1lbW9yeSByZXF1aXJlcyBhIFRDUCBHcmFwaGl0aSBsaXN0ZW5lclwiKTtcbiAgfVxuICBjb25zdCBbZ3JhcGhpdGlQb3J0XSA9IGF3YWl0IGRpc3RpbmN0UG9ydHMoXG4gICAgY29uZmlnVXRpbHMucG9ydCh1bmRlZmluZWQsIFwiREFUQUJSSUNLU19BUFBfUE9SVFwiLCA4MDAwLCBjb25maWdVdGlscy5FTlZfT05MWSksXG4gICAgY29uZmlndXJlZC5saXN0ZW4ucG9ydCxcbiAgKTtcbiAgY29uc3QgcmVzb2x2ZWQgPSByZXNvbHZlR3JhcGhpdGlPcHRpb25zKHtcbiAgICAuLi5jb25maWd1cmVkLFxuICAgIGJlYXJlcjogcmFuZG9tQnl0ZXMoMzIpLnRvU3RyaW5nKFwiYmFzZTY0dXJsXCIpLFxuICAgIGxpc3RlbjogeyAuLi5jb25maWd1cmVkLmxpc3RlbiwgcG9ydDogZ3JhcGhpdGlQb3J0IH0sXG4gIH0pO1xuICBsZXQgdG9vbHM6IE9wZW5BcGlUb29sW10gfCB1bmRlZmluZWQ7XG4gIGNvbnN0IHsgY2hpbGQgfSA9IGF3YWl0IGNyZWF0ZUdyYXBoaXRpQ2hpbGRQcm9jZXNzKHtcbiAgICAuLi5yZXNvbHZlZCxcbiAgICAuLi4oc2lnbmFsID8geyBzaWduYWwgfSA6IHt9KSxcbiAgICBoZWFsdGhDaGVjazogYXN5bmMgKHsgc2lnbmFsIH0pID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmICghKGF3YWl0IGdyYXBoaXRpSGVhbHRoQ2hlY2socmVzb2x2ZWQsIHNpZ25hbCkpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGNvbnN0IGxvYWRlZCA9IGF3YWl0IG9wZW5BcGlUb29scyhncmFwaGl0aUh0dHBVcmwocmVzb2x2ZWQsIFwiL29wZW5hcGkuanNvblwiKSwge1xuICAgICAgICAgIHNpZ25hbCxcbiAgICAgICAgICBoZWFkZXJzOiBncmFwaGl0aVJlcXVlc3RIZWFkZXJzKHJlc29sdmVkKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRvb2xzID0gW1xuICAgICAgICAgIHJlcXVpcmVkT3BlcmF0aW9uKGxvYWRlZCwgXCJhZGRfbWVtb3J5X3N5bmNcIiksXG4gICAgICAgICAgcmVxdWlyZWRPcGVyYXRpb24obG9hZGVkLCBcInNlYXJjaF9tZW1vcnlfZmFjdHNcIiksXG4gICAgICAgIF07XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKHNpZ25hbC5hYm9ydGVkKSB0aHJvdyBlcnJvcjtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xuICBpZiAoIXRvb2xzKSB7XG4gICAgYXdhaXQgY2hpbGQuc2h1dGRvd24oKTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJHcmFwaGl0aSBPcGVuQVBJIHRvb2xzIHdlcmUgbm90IGNhcHR1cmVkIGR1cmluZyByZWFkaW5lc3NcIik7XG4gIH1cbiAgcmV0dXJuIG5ldyBHcmFwaGl0aUJhY2tlbmQocmVzb2x2ZWQsIGNoaWxkLCB0b29sc1swXSEsIHRvb2xzWzFdISk7XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVHcmFwaGl0aUNvbmZpZyhvcHRpb25zOiBHcmFwaGl0aU9wdGlvbnMpOiBSZXNvbHZlZEdyYXBoaXRpT3B0aW9ucyB7XG4gIGNvbnN0IGVudmlyb25tZW50ID0gZ3JhcGhpdGlPcHRpb25zRnJvbUVudmlyb25tZW50KHByb2Nlc3MuZW52KTtcbiAgaWYgKGVudmlyb25tZW50LnByb2ZpbGUgJiYgIWF1dGhQcm9maWxlLnJlc29sdmVQcm9maWxlKHsgcHJvZmlsZTogZW52aXJvbm1lbnQucHJvZmlsZSB9KSkge1xuICAgIGVudmlyb25tZW50LnByb2ZpbGUgPSB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3Qgb3ZlcnJpZGVzID0gZ3JhcGhpdGlPcHRpb25PdmVycmlkZXMob3B0aW9ucyk7XG4gIHJldHVybiByZXNvbHZlR3JhcGhpdGlPcHRpb25zKHtcbiAgICAuLi5lbnZpcm9ubWVudCxcbiAgICAuLi5vdmVycmlkZXMsXG4gICAgbGlzdGVuOiBvdmVycmlkZXMubGlzdGVuID8/XG4gICAgICBlbnZpcm9ubWVudC5saXN0ZW4gPz8ge1xuICAgICAgICBzY2hlbWU6IFwidGNwXCIsXG4gICAgICAgIGhvc3Q6IFwiMTI3LjAuMC4xXCIsXG4gICAgICAgIHBvcnQ6IDAsXG4gICAgICB9LFxuICB9KTtcbn1cblxuZnVuY3Rpb24gcmVxdWlyZWRPcGVyYXRpb24odG9vbHM6IHJlYWRvbmx5IE9wZW5BcGlUb29sW10sIG5hbWU6IHN0cmluZyk6IE9wZW5BcGlUb29sIHtcbiAgY29uc3QgdG9vbCA9IHRvb2xzLmZpbmQoKHsgaWQgfSkgPT4gaWQgPT09IG5hbWUpO1xuICBpZiAoIXRvb2wpIHRocm93IG5ldyBFcnJvcihgR3JhcGhpdGkgT3BlbkFQSSBpcyBtaXNzaW5nIG9wZXJhdGlvbjogJHtuYW1lfWApO1xuICByZXR1cm4gdG9vbDtcbn1cblxuZnVuY3Rpb24gdXNlclNjb3BlKHVzZXJJZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGB1c2VyXyR7Y3JlYXRlSGFzaChcInNoYTI1NlwiKS51cGRhdGUodXNlcklkKS5kaWdlc3QoXCJiYXNlNjR1cmxcIil9YDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gYXZhaWxhYmxlUG9ydCgpOiBQcm9taXNlPG51bWJlcj4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHNlcnZlciA9IGNyZWF0ZVNlcnZlcigpO1xuICAgIHNlcnZlci5vbmNlKFwiZXJyb3JcIiwgcmVqZWN0KTtcbiAgICBzZXJ2ZXIubGlzdGVuKDAsIFwiMTI3LjAuMC4xXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSBzZXJ2ZXIuYWRkcmVzcygpO1xuICAgICAgaWYgKCFhZGRyZXNzIHx8IHR5cGVvZiBhZGRyZXNzID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHNlcnZlci5jbG9zZSgpO1xuICAgICAgICByZWplY3QobmV3IEVycm9yKFwiQ291bGQgbm90IGFsbG9jYXRlIGEgR3JhcGhpdGkgbG9vcGJhY2sgcG9ydFwiKSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHNlcnZlci5jbG9zZSgoZXJyb3IpID0+IChlcnJvciA/IHJlamVjdChlcnJvcikgOiByZXNvbHZlKGFkZHJlc3MucG9ydCkpKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGRpc3RpbmN0UG9ydHMoYXBwUG9ydDogbnVtYmVyLCBncmFwaGl0aVBvcnQ6IG51bWJlcik6IFByb21pc2U8W251bWJlcl0+IHtcbiAgY29uc3QgcG9ydHMgPSBbYXBwUG9ydF07XG4gIGZvciAoY29uc3QgY29uZmlndXJlZFBvcnQgb2YgW2dyYXBoaXRpUG9ydF0pIHtcbiAgICBpZiAoY29uZmlndXJlZFBvcnQgJiYgcG9ydHMuaW5jbHVkZXMoY29uZmlndXJlZFBvcnQpKSB7XG4gICAgICB0aHJvdyBuZXcgQ29uZmlndXJhdGlvbkVycm9yKFwiR3JhcGhpdGkgc2lkZWNhciBwb3J0cyBtdXN0IGRpZmZlciBmcm9tIERBVEFCUklDS1NfQVBQX1BPUlRcIik7XG4gICAgfVxuICAgIGxldCBwb3J0ID0gY29uZmlndXJlZFBvcnQgfHwgKGF3YWl0IGF2YWlsYWJsZVBvcnQoKSk7XG4gICAgd2hpbGUgKHBvcnRzLmluY2x1ZGVzKHBvcnQpKSBwb3J0ID0gYXdhaXQgYXZhaWxhYmxlUG9ydCgpO1xuICAgIHBvcnRzLnB1c2gocG9ydCk7XG4gIH1cbiAgcmV0dXJuIHBvcnRzLnNsaWNlKDEpIGFzIFtudW1iZXJdO1xufVxuIl19
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// GENERATED by projen watch - DO NOT EDIT.
|
|
2
|
+
// Regenerated from the exporting modules in ./src.
|
|
3
|
+
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
|
+
export * as options from "./options.js";
|
|
5
|
+
export * as runtime from "./runtime.js";
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZ3JhcGhpdGkvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsMkNBQTJDO0FBQzNDLG1EQUFtRDtBQUNuRCx3RUFBd0U7QUFFeEUsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBHRU5FUkFURUQgYnkgcHJvamVuIHdhdGNoIC0gRE8gTk9UIEVESVQuXG4vLyBSZWdlbmVyYXRlZCBmcm9tIHRoZSBleHBvcnRpbmcgbW9kdWxlcyBpbiAuL3NyYy5cbi8vIEhhbmQgZWRpdHMgYXJlIG92ZXJ3cml0dGVuIG9uIHRoZSBuZXh0IHdhdGNoOyB0aGlzIGZpbGUgaXMgcmVhZC1vbmx5LlxuXG5leHBvcnQgKiBhcyBvcHRpb25zIGZyb20gXCIuL29wdGlvbnMudHNcIjtcbmV4cG9ydCAqIGFzIHJ1bnRpbWUgZnJvbSBcIi4vcnVudGltZS50c1wiO1xuZXhwb3J0IHR5cGUgeyBHcmFwaGl0aUhlYWx0aENoZWNrQ29udGV4dCwgR3JhcGhpdGlIZWFsdGhDaGVjaywgR3JhcGhpdGlDaGlsZFByb2Nlc3MsIEdyYXBoaXRpUnVudGltZU9wdGlvbnMsIEdyYXBoaXRpUHl0aG9uQ29tbWFuZCB9IGZyb20gXCIuL3J1bnRpbWUudHNcIjtcbiJdfQ==
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node export of the shared Graphiti option contract.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
export { GRAPHITI_DEFAULTS, GraphitiCliOptionsSchema, GraphitiOptionsSchema, ResolvedGraphitiOptionsSchema, graphitiOptionOverrides, graphitiOptionsEnvironment, graphitiOptionsFromEnvironment, resolveGraphitiOptions, } from "@dbx-tools/shared-graphiti";
|
|
7
|
+
export type { GraphitiOptions, ResolvedGraphitiOptions } from "@dbx-tools/shared-graphiti";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node export of the shared Graphiti option contract.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
export { GRAPHITI_DEFAULTS, GraphitiCliOptionsSchema, GraphitiOptionsSchema, ResolvedGraphitiOptionsSchema, graphitiOptionOverrides, graphitiOptionsEnvironment, graphitiOptionsFromEnvironment, resolveGraphitiOptions, } from "@dbx-tools/shared-graphiti";
|
|
7
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9ncmFwaGl0aS9vcHRpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7QUFFSCxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLHdCQUF3QixFQUN4QixxQkFBcUIsRUFDckIsNkJBQTZCLEVBQzdCLHVCQUF1QixFQUN2QiwwQkFBMEIsRUFDMUIsOEJBQThCLEVBQzlCLHNCQUFzQixHQUN2QixNQUFNLDRCQUE0QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBOb2RlIGV4cG9ydCBvZiB0aGUgc2hhcmVkIEdyYXBoaXRpIG9wdGlvbiBjb250cmFjdC5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuZXhwb3J0IHtcbiAgR1JBUEhJVElfREVGQVVMVFMsXG4gIEdyYXBoaXRpQ2xpT3B0aW9uc1NjaGVtYSxcbiAgR3JhcGhpdGlPcHRpb25zU2NoZW1hLFxuICBSZXNvbHZlZEdyYXBoaXRpT3B0aW9uc1NjaGVtYSxcbiAgZ3JhcGhpdGlPcHRpb25PdmVycmlkZXMsXG4gIGdyYXBoaXRpT3B0aW9uc0Vudmlyb25tZW50LFxuICBncmFwaGl0aU9wdGlvbnNGcm9tRW52aXJvbm1lbnQsXG4gIHJlc29sdmVHcmFwaGl0aU9wdGlvbnMsXG59IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1ncmFwaGl0aVwiO1xuZXhwb3J0IHR5cGUgeyBHcmFwaGl0aU9wdGlvbnMsIFJlc29sdmVkR3JhcGhpdGlPcHRpb25zIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWdyYXBoaXRpXCI7XG4iXX0=
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node Graphiti runtime and process supervision.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import type { ChildProcessResult } from "@dbx-tools/core/exec";
|
|
7
|
+
import { type GraphitiOptions, type ResolvedGraphitiOptions } from "./options.ts";
|
|
8
|
+
/** Context passed to one Graphiti sidecar readiness probe. */
|
|
9
|
+
export interface GraphitiHealthCheckContext {
|
|
10
|
+
readonly process: ChildProcessResult;
|
|
11
|
+
readonly signal: AbortSignal;
|
|
12
|
+
readonly attempt: number;
|
|
13
|
+
}
|
|
14
|
+
/** HTTP probe used to decide that the Graphiti sidecar has started listening. */
|
|
15
|
+
export type GraphitiHealthCheck = (context: GraphitiHealthCheckContext) => boolean | PromiseLike<boolean>;
|
|
16
|
+
/** Async creation result that preserves the awaitable child handle. */
|
|
17
|
+
export interface GraphitiChildProcess {
|
|
18
|
+
child: ChildProcessResult;
|
|
19
|
+
}
|
|
20
|
+
/** Shared Graphiti options plus the Node-only sidecar readiness probe. */
|
|
21
|
+
export type GraphitiRuntimeOptions = GraphitiOptions & {
|
|
22
|
+
/** Readiness probe for {@link createGraphitiChildProcess}. Defaults to `/healthcheck`. */
|
|
23
|
+
healthCheck?: GraphitiHealthCheck;
|
|
24
|
+
/** Cancels sidecar startup without changing the serialized Graphiti configuration. */
|
|
25
|
+
signal?: AbortSignal;
|
|
26
|
+
};
|
|
27
|
+
/** Milliseconds left in a startup budget after `startedAt`. */
|
|
28
|
+
export declare function remainingTimeoutMs(startedAt: number, timeoutMs: number, now?: number): number;
|
|
29
|
+
/** Return whether the Graphiti `/healthcheck` endpoint responds successfully. */
|
|
30
|
+
export declare function graphitiHealthCheck(options: Pick<ResolvedGraphitiOptions, "listen" | "bearer">, signal: AbortSignal): Promise<boolean>;
|
|
31
|
+
/** Poll `/healthcheck` until it succeeds or `timeoutMs` elapses. */
|
|
32
|
+
export declare function waitForGraphitiHealth(options: Pick<ResolvedGraphitiOptions, "listen" | "bearer">, timeoutMs: number, signal?: AbortSignal): Promise<void>;
|
|
33
|
+
/** Build authorization headers for one optionally secured Graphiti runtime. */
|
|
34
|
+
export declare function graphitiRequestHeaders(options: Pick<ResolvedGraphitiOptions, "bearer">): Readonly<Record<string, string>>;
|
|
35
|
+
/** Executable and arguments used to launch Graphiti. */
|
|
36
|
+
export interface GraphitiPythonCommand {
|
|
37
|
+
command: string;
|
|
38
|
+
args: string[];
|
|
39
|
+
}
|
|
40
|
+
/** Resolve configured or app-installed Python, otherwise a uv-provisioned runtime. */
|
|
41
|
+
export declare function resolveGraphitiPythonCommand(options?: {
|
|
42
|
+
dev?: boolean;
|
|
43
|
+
}, ...args: string[]): Promise<GraphitiPythonCommand>;
|
|
44
|
+
/** Build one HTTP URL for a resolved Graphiti listener. */
|
|
45
|
+
export declare function graphitiHttpUrl(options: Pick<ResolvedGraphitiOptions, "listen">, path: string): string;
|
|
46
|
+
/** Build one readiness-gated Graphiti sidecar from the shared typed options. */
|
|
47
|
+
export declare function createGraphitiChildProcess(options?: GraphitiRuntimeOptions): Promise<GraphitiChildProcess>;
|
|
48
|
+
/** Run the supervised stack until the child exits. */
|
|
49
|
+
export declare function runGraphiti(options?: GraphitiRuntimeOptions): Promise<void>;
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node Graphiti runtime and process supervision.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { delimiter, dirname } from "node:path";
|
|
7
|
+
import { exec } from "@dbx-tools/core";
|
|
8
|
+
import { asyncUtils, environmentUtils, functionUtils, options as sharedOptions, } from "@dbx-tools/shared-core";
|
|
9
|
+
import { coerce, rcompare } from "semver";
|
|
10
|
+
import { graphitiOptionsEnvironment, resolveGraphitiOptions, } from "./options.js";
|
|
11
|
+
const HEALTH_CHECK_INTERVAL_MS = 200;
|
|
12
|
+
const PYTHON_CANDIDATES = ["python", "python3"];
|
|
13
|
+
const GRAPHITI_IMPORT_PROBE = "import dbx_tools.graphiti";
|
|
14
|
+
const graphitiPython = functionUtils.memoize(async () => {
|
|
15
|
+
const available = (await Promise.all(PYTHON_CANDIDATES.map((command) => _probePython(command)))).filter((candidate) => candidate !== undefined);
|
|
16
|
+
available.sort((left, right) => rcompare(left.version, right.version));
|
|
17
|
+
return available[0]?.command;
|
|
18
|
+
});
|
|
19
|
+
function graphitiOptions(options) {
|
|
20
|
+
const { healthCheck: _healthCheck, signal: _signal, ...graphiti } = options;
|
|
21
|
+
return graphiti;
|
|
22
|
+
}
|
|
23
|
+
/** Milliseconds left in a startup budget after `startedAt`. */
|
|
24
|
+
export function remainingTimeoutMs(startedAt, timeoutMs, now = Date.now()) {
|
|
25
|
+
return Math.max(0, timeoutMs - (now - startedAt));
|
|
26
|
+
}
|
|
27
|
+
function _runtimeEnvironment(options) {
|
|
28
|
+
if (options.listen.scheme !== "tcp")
|
|
29
|
+
throw new Error("Graphiti requires a TCP listener");
|
|
30
|
+
const nodeBin = process.env.DBX_TOOLS_NODE_BIN?.trim();
|
|
31
|
+
const path = nodeBin
|
|
32
|
+
? [dirname(nodeBin), process.env.PATH].filter(Boolean).join(delimiter)
|
|
33
|
+
: process.env.PATH;
|
|
34
|
+
return {
|
|
35
|
+
...process.env,
|
|
36
|
+
...(path ? { PATH: path } : {}),
|
|
37
|
+
...graphitiOptionsEnvironment(options),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/** Return whether the Graphiti `/healthcheck` endpoint responds successfully. */
|
|
41
|
+
export async function graphitiHealthCheck(options, signal) {
|
|
42
|
+
try {
|
|
43
|
+
return (await fetch(graphitiHttpUrl(options, "/healthcheck"), {
|
|
44
|
+
signal,
|
|
45
|
+
headers: graphitiRequestHeaders(options),
|
|
46
|
+
})).ok;
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
if (signal.aborted)
|
|
50
|
+
throw error;
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** Poll `/healthcheck` until it succeeds or `timeoutMs` elapses. */
|
|
55
|
+
export async function waitForGraphitiHealth(options, timeoutMs, signal) {
|
|
56
|
+
const budget = Math.max(1, timeoutMs);
|
|
57
|
+
for await (const healthy of asyncUtils.poll(({ signal: pollSignal }) => graphitiHealthCheck(options, pollSignal), {
|
|
58
|
+
intervalMs: HEALTH_CHECK_INTERVAL_MS,
|
|
59
|
+
timeoutMs: budget,
|
|
60
|
+
signal,
|
|
61
|
+
predicate: (ready) => !ready,
|
|
62
|
+
})) {
|
|
63
|
+
if (healthy)
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
throw new Error("Graphiti sidecar healthcheck did not succeed");
|
|
67
|
+
}
|
|
68
|
+
/** Build authorization headers for one optionally secured Graphiti runtime. */
|
|
69
|
+
export function graphitiRequestHeaders(options) {
|
|
70
|
+
return options.bearer ? { authorization: `Bearer ${options.bearer}` } : {};
|
|
71
|
+
}
|
|
72
|
+
/** Resolve configured or app-installed Python, otherwise a uv-provisioned runtime. */
|
|
73
|
+
export async function resolveGraphitiPythonCommand(options = {}, ...args) {
|
|
74
|
+
const python = process.env.PYTHON?.trim();
|
|
75
|
+
if (python)
|
|
76
|
+
return { command: python, args };
|
|
77
|
+
if (environmentUtils.isDatabricksAppEnv()) {
|
|
78
|
+
const installed = await graphitiPython();
|
|
79
|
+
if (installed)
|
|
80
|
+
return { command: installed, args };
|
|
81
|
+
}
|
|
82
|
+
const extra = options.dev ? "[dev]" : "";
|
|
83
|
+
const packageArgs = [
|
|
84
|
+
"--with",
|
|
85
|
+
`dbx-tools-graphiti${extra}==${(await import("../../index.js")).PACKAGE_VERSION}`,
|
|
86
|
+
];
|
|
87
|
+
return {
|
|
88
|
+
command: "uv",
|
|
89
|
+
args: ["run", "--no-project", ...packageArgs, "--python", "python3", "python", ...args],
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
async function _probePython(command) {
|
|
93
|
+
const versionResult = await exec.spawn(command, ["-V"], {
|
|
94
|
+
check: false,
|
|
95
|
+
stdin: "ignore",
|
|
96
|
+
stdout: "capture",
|
|
97
|
+
stderr: "capture",
|
|
98
|
+
trim: true,
|
|
99
|
+
});
|
|
100
|
+
if (versionResult.exitCode !== 0)
|
|
101
|
+
return undefined;
|
|
102
|
+
const version = coerce(`${versionResult.stdout}\n${versionResult.stderr}`);
|
|
103
|
+
if (!version)
|
|
104
|
+
return undefined;
|
|
105
|
+
const importResult = await exec.spawn(command, ["-c", GRAPHITI_IMPORT_PROBE], {
|
|
106
|
+
check: false,
|
|
107
|
+
stdin: "ignore",
|
|
108
|
+
stdout: "ignore",
|
|
109
|
+
stderr: "ignore",
|
|
110
|
+
});
|
|
111
|
+
return importResult.exitCode === 0 ? { command, version } : undefined;
|
|
112
|
+
}
|
|
113
|
+
/** Build one HTTP URL for a resolved Graphiti listener. */
|
|
114
|
+
export function graphitiHttpUrl(options, path) {
|
|
115
|
+
return `${sharedOptions
|
|
116
|
+
.formatListenAddress(options.listen)
|
|
117
|
+
.replace(/^tcp:/, "http:")}${path.startsWith("/") ? path : `/${path}`}`;
|
|
118
|
+
}
|
|
119
|
+
/** Build one readiness-gated Graphiti sidecar from the shared typed options. */
|
|
120
|
+
export async function createGraphitiChildProcess(options = {}) {
|
|
121
|
+
const healthCheck = options.healthCheck;
|
|
122
|
+
const resolved = resolveGraphitiOptions(graphitiOptions(options));
|
|
123
|
+
const python = await resolveGraphitiPythonCommand({ dev: !resolved.databaseUrl }, "-m", "dbx_tools.graphiti");
|
|
124
|
+
const child = exec.spawn(python.command, python.args, {
|
|
125
|
+
env: _runtimeEnvironment(resolved),
|
|
126
|
+
forwardTerminationSignals: false,
|
|
127
|
+
});
|
|
128
|
+
const controller = new AbortController();
|
|
129
|
+
const startupSignal = options.signal
|
|
130
|
+
? AbortSignal.any([controller.signal, options.signal])
|
|
131
|
+
: controller.signal;
|
|
132
|
+
const probe = healthCheck ?? (({ signal }) => graphitiHealthCheck(resolved, signal));
|
|
133
|
+
try {
|
|
134
|
+
await Promise.race([
|
|
135
|
+
waitForGraphitiChild(child, probe, resolved.startupTimeoutMs, startupSignal),
|
|
136
|
+
child.then((result) => {
|
|
137
|
+
throw new Error(`Graphiti child ${child.pid ?? "<unknown>"} exited before becoming ready ` +
|
|
138
|
+
`(exit ${result.exitCode})`);
|
|
139
|
+
}),
|
|
140
|
+
]);
|
|
141
|
+
return { child };
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
await child.shutdown();
|
|
145
|
+
throw error;
|
|
146
|
+
}
|
|
147
|
+
finally {
|
|
148
|
+
controller.abort();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
async function waitForGraphitiChild(child, healthCheck, timeoutMs, signal) {
|
|
152
|
+
for await (const healthy of asyncUtils.poll(({ attempt, signal: pollSignal }) => healthCheck({ process: child, signal: pollSignal, attempt }), {
|
|
153
|
+
intervalMs: HEALTH_CHECK_INTERVAL_MS,
|
|
154
|
+
timeoutMs,
|
|
155
|
+
signal,
|
|
156
|
+
predicate: (ready) => !ready,
|
|
157
|
+
})) {
|
|
158
|
+
if (healthy)
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/** Run the supervised stack until the child exits. */
|
|
163
|
+
export async function runGraphiti(options = {}) {
|
|
164
|
+
const { child } = await createGraphitiChildProcess(options);
|
|
165
|
+
const outcome = await child;
|
|
166
|
+
if (outcome.exitCode !== 0) {
|
|
167
|
+
throw new Error(`Graphiti child exited with status ${outcome.exitCode}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVudGltZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9ncmFwaGl0aS9ydW50aW1lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7QUFFSCxPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUMvQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFdkMsT0FBTyxFQUNMLFVBQVUsRUFDVixnQkFBZ0IsRUFDaEIsYUFBYSxFQUNiLE9BQU8sSUFBSSxhQUFhLEdBQ3pCLE1BQU0sd0JBQXdCLENBQUM7QUFDaEMsT0FBTyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQWUsTUFBTSxRQUFRLENBQUM7QUFFdkQsT0FBTyxFQUNMLDBCQUEwQixFQUMxQixzQkFBc0IsR0FHdkIsTUFBTSxjQUFjLENBQUM7QUEyQnRCLE1BQU0sd0JBQXdCLEdBQUcsR0FBRyxDQUFDO0FBQ3JDLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxRQUFRLEVBQUUsU0FBUyxDQUFVLENBQUM7QUFDekQsTUFBTSxxQkFBcUIsR0FBRywyQkFBMkIsQ0FBQztBQU8xRCxNQUFNLGNBQWMsR0FBRyxhQUFhLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBaUMsRUFBRTtJQUNuRixNQUFNLFNBQVMsR0FBRyxDQUNoQixNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUM3RSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFNBQVMsRUFBZ0MsRUFBRSxDQUFDLFNBQVMsS0FBSyxTQUFTLENBQUMsQ0FBQztJQUMvRSxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFD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cEUsTUFBTSxFQUFFLEtBQUssRUFBRSxHQUFHLE1BQU0sMEJBQTBCLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDNUQsTUFBTSxPQUFPLEdBQUcsTUFBTSxLQUFLLENBQUM7SUFDNUIsSUFBSSxPQUFPLENBQUMsUUFBUSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQzNCLE1BQU0sSUFBSSxLQUFLLENBQUMscUNBQXFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBQzNFLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBOb2RlIEdyYXBoaXRpIHJ1bnRpbWUgYW5kIHByb2Nlc3Mgc3VwZXJ2aXNpb24uXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IGRlbGltaXRlciwgZGlybmFtZSB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IGV4ZWMgfSBmcm9tIFwiQGRieC10b29scy9jb3JlXCI7XG5pbXBvcnQgdHlwZSB7IENoaWxkUHJvY2Vzc1Jlc3VsdCB9IGZyb20gXCJAZGJ4LXRvb2xzL2NvcmUvZXhlY1wiO1xuaW1wb3J0IHtcbiAgYXN5bmNVdGlscyxcbiAgZW52aXJvbm1lbnRVdGlscyxcbiAgZnVuY3Rpb25VdGlscyxcbiAgb3B0aW9ucyBhcyBzaGFyZWRPcHRpb25zLFxufSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHsgY29lcmNlLCByY29tcGFyZSwgdHlwZSBTZW1WZXIgfSBmcm9tIFwic2VtdmVyXCI7XG5cbmltcG9ydCB7XG4gIGdyYXBoaXRpT3B0aW9uc0Vudmlyb25tZW50LFxuICByZXNvbHZlR3JhcGhpdGlPcHRpb25zLFxuICB0eXBlIEdyYXBoaXRpT3B0aW9ucyxcbiAgdHlwZSBSZXNvbHZlZEdyYXBoaXRpT3B0aW9ucyxcbn0gZnJvbSBcIi4vb3B0aW9ucy50c1wiO1xuXG4vKiogQ29udGV4dCBwYXNzZWQgdG8gb25lIEdyYXBoaXRpIHNpZGVjYXIgcmVhZGluZXNzIHByb2JlLiAqL1xuZXhwb3J0IGludGVyZmFjZSBHcmFwaGl0aUhlYWx0aENoZWNrQ29udGV4dCB7XG4gIHJlYWRvbmx5IHByb2Nlc3M6IENoaWxkUHJvY2Vzc1Jlc3VsdDtcbiAgcmVhZG9ubHkgc2lnbmFsOiBBYm9ydFNpZ25hbDtcbiAgcmVhZG9ubHkgYXR0ZW1wdDogbnVtYmVyO1xufVxuXG4vKiogSFRUUCBwcm9iZSB1c2VkIHRvIGRlY2lkZSB0aGF0IHRoZSBHcmFwaGl0aSBzaWRlY2FyIGhhcyBzdGFydGVkIGxpc3RlbmluZy4gKi9cbmV4cG9ydCB0eXBlIEdyYXBoaXRpSGVhbHRoQ2hlY2sgPSAoXG4gIGNvbnRleHQ6IEdyYXBoaXRpSGVhbHRoQ2hlY2tDb250ZXh0LFxuKSA9PiBib29sZWFuIHwgUHJvbWlzZUxpa2U8Ym9vbGVhbj47XG5cbi8qKiBBc3luYyBjcmVhdGlvbiByZXN1bHQgdGhhdCBwcmVzZXJ2ZXMgdGhlIGF3YWl0YWJsZSBjaGlsZCBoYW5kbGUuICovXG5leHBvcnQgaW50ZXJmYWNlIEdyYXBoaXRpQ2hpbGRQcm9jZXNzIHtcbiAgY2hpbGQ6IENoaWxkUHJvY2Vzc1Jlc3VsdDtcbn1cblxuLyoqIFNoYXJlZCBHcmFwaGl0aSBvcHRpb25zIHBsdXMgdGhlIE5vZGUtb25seSBzaWRlY2FyIHJlYWRpbmVzcyBwcm9iZS4gKi9cbmV4cG9ydCB0eXBlIEdyYXBoaXRpUnVudGltZU9wdGlvbnMgPSBHcmFwaGl0aU9wdGlvbnMgJiB7XG4gIC8qKiBSZWFkaW5lc3MgcHJvYmUgZm9yIHtAbGluayBjcmVhdGVHcmFwaGl0aUNoaWxkUHJvY2Vzc30uIERlZmF1bHRzIHRvIGAvaGVhbHRoY2hlY2tgLiAqL1xuICBoZWFsdGhDaGVjaz86IEdyYXBoaXRpSGVhbHRoQ2hlY2s7XG4gIC8qKiBDYW5jZWxzIHNpZGVjYXIgc3RhcnR1cCB3aXRob3V0IGNoYW5naW5nIHRoZSBzZXJpYWxpemVkIEdyYXBoaXRpIGNvbmZpZ3VyYXRpb24uICovXG4gIHNpZ25hbD86IEFib3J0U2lnbmFsO1xufTtcblxuY29uc3QgSEVBTFRIX0NIRUNLX0lOVEVSVkFMX01TID0gMjAwO1xuY29uc3QgUFlUSE9OX0NBTkRJREFURVMgPSBbXCJweXRob25cIiwgXCJweXRob24zXCJdIGFzIGNvbnN0O1xuY29uc3QgR1JBUEhJVElfSU1QT1JUX1BST0JFID0gXCJpbXBvcnQgZGJ4X3Rvb2xzLmdyYXBoaXRpXCI7XG5cbmludGVyZmFjZSBQeXRob25DYW5kaWRhdGUge1xuICBjb21tYW5kOiBzdHJpbmc7XG4gIHZlcnNpb246IFNlbVZlcjtcbn1cblxuY29uc3QgZ3JhcGhpdGlQeXRob24gPSBmdW5jdGlvblV0aWxzLm1lbW9pemUoYXN5bmMgKCk6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiA9PiB7XG4gIGNvbnN0IGF2YWlsYWJsZSA9IChcbiAgICBhd2FpdCBQcm9taXNlLmFsbChQWVRIT05fQ0FORElEQVRFUy5tYXAoKGNvbW1hbmQpID0+IF9wcm9iZVB5dGhvbihjb21tYW5kKSkpXG4gICkuZmlsdGVyKChjYW5kaWRhdGUpOiBjYW5kaWRhdGUgaXMgUHl0aG9uQ2FuZGlkYXRlID0+IGNhbmRpZGF0ZSAhPT0gdW5kZWZpbmVkKTtcbiAgYXZhaWxhYmxlLnNvcnQoKGxlZnQsIHJpZ2h0KSA9PiByY29tcGFyZShsZWZ0LnZlcnNpb24sIHJpZ2h0LnZlcnNpb24pKTtcbiAgcmV0dXJuIGF2YWlsYWJsZVswXT8uY29tbWFuZDtcbn0pO1xuXG5mdW5jdGlvbiBncmFwaGl0aU9wdGlvbnMob3B0aW9uczogR3JhcGhpdGlSdW50aW1lT3B0aW9ucyk6IEdyYXBoaXRpT3B0aW9ucyB7XG4gIGNvbnN0IHsgaGVhbHRoQ2hlY2s6IF9oZWFsdGhDaGVjaywgc2lnbmFsOiBfc2lnbmFsLCAuLi5ncmFwaGl0aSB9ID0gb3B0aW9ucztcbiAgcmV0dXJuIGdyYXBoaXRpO1xufVxuXG4vKiogTWlsbGlzZWNvbmRzIGxlZnQgaW4gYSBzdGFydHVwIGJ1ZGdldCBhZnRlciBgc3RhcnRlZEF0YC4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW1haW5pbmdUaW1lb3V0TXMoc3RhcnRlZEF0OiBudW1iZXIsIHRpbWVvdXRNczogbnVtYmVyLCBub3cgPSBEYXRlLm5vdygpKTogbnVtYmVyIHtcbiAgcmV0dXJuIE1hdGgubWF4KDAsIHRpbWVvdXRNcyAtIChub3cgLSBzdGFydGVkQXQpKTtcbn1cblxuZnVuY3Rpb24gX3J1bnRpbWVFbnZpcm9ubWVudChvcHRpb25zOiBSZXNvbHZlZEdyYXBoaXRpT3B0aW9ucyk6IE5vZGVKUy5Qcm9jZXNzRW52IHtcbiAgaWYgKG9wdGlvbnMubGlzdGVuLnNjaGVtZSAhPT0gXCJ0Y3BcIikgdGhyb3cgbmV3IEVycm9yKFwiR3JhcGhpdGkgcmVxdWlyZXMgYSBUQ1AgbGlzdGVuZXJcIik7XG4gIGNvbnN0IG5vZGVCaW4gPSBwcm9jZXNzLmVudi5EQlhfVE9PTFNfTk9ERV9CSU4/LnRyaW0oKTtcbiAgY29uc3QgcGF0aCA9IG5vZGVCaW5cbiAgICA/IFtkaXJuYW1lKG5vZGVCaW4pLCBwcm9jZXNzLmVudi5QQVRIXS5maWx0ZXIoQm9vbGVhbikuam9pbihkZWxpbWl0ZXIpXG4gICAgOiBwcm9jZXNzLmVudi5QQVRIO1xuICByZXR1cm4ge1xuICAgIC4uLnByb2Nlc3MuZW52LFxuICAgIC4uLihwYXRoID8geyBQQVRIOiBwYXRoIH0gOiB7fSksXG4gICAgLi4uZ3JhcGhpdGlPcHRpb25zRW52aXJvbm1lbnQob3B0aW9ucyksXG4gIH07XG59XG5cbi8qKiBSZXR1cm4gd2hldGhlciB0aGUgR3JhcGhpdGkgYC9oZWFsdGhjaGVja2AgZW5kcG9pbnQgcmVzcG9uZHMgc3VjY2Vzc2Z1bGx5LiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdyYXBoaXRpSGVhbHRoQ2hlY2soXG4gIG9wdGlvbnM6IFBpY2s8UmVzb2x2ZWRHcmFwaGl0aU9wdGlvbnMsIFwibGlzdGVuXCIgfCBcImJlYXJlclwiPixcbiAgc2lnbmFsOiBBYm9ydFNpZ25hbCxcbik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICB0cnkge1xuICAgIHJldHVybiAoXG4gICAgICBhd2FpdCBmZXRjaChncmFwaGl0aUh0dHBVcmwob3B0aW9ucywgXCIvaGVhbHRoY2hlY2tcIiksIHtcbiAgICAgICAgc2lnbmFsLFxuICAgICAgICBoZWFkZXJzOiBncmFwaGl0aVJlcXVlc3RIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgfSlcbiAgICApLm9rO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChzaWduYWwuYWJvcnRlZCkgdGhyb3cgZXJyb3I7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKiBQb2xsIGAvaGVhbHRoY2hlY2tgIHVudGlsIGl0IHN1Y2NlZWRzIG9yIGB0aW1lb3V0TXNgIGVsYXBzZXMuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gd2FpdEZvckdyYXBoaXRpSGVhbHRoKFxuICBvcHRpb25zOiBQaWNrPFJlc29sdmVkR3JhcGhpdGlPcHRpb25zLCBcImxpc3RlblwiIHwgXCJiZWFyZXJcIj4sXG4gIHRpbWVvdXRNczogbnVtYmVyLFxuICBzaWduYWw/OiBBYm9ydFNpZ25hbCxcbik6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBidWRnZXQgPSBNYXRoLm1heCgxLCB0aW1lb3V0TXMpO1xuICBmb3IgYXdhaXQgKGNvbnN0IGhlYWx0aHkgb2YgYXN5bmNVdGlscy5wb2xsKFxuICAgICh7IHNpZ25hbDogcG9sbFNpZ25hbCB9KSA9PiBncmFwaGl0aUhlYWx0aENoZWNrKG9wdGlvbnMsIHBvbGxTaWduYWwpLFxuICAgIHtcbiAgICAgIGludGVydmFsTXM6IEhFQUxUSF9DSEVDS19JTlRFUlZBTF9NUyxcbiAgICAgIHRpbWVvdXRNczogYnVkZ2V0LFxuICAgICAgc2lnbmFsLFxuICAgICAgcHJlZGljYXRlOiAocmVhZHkpID0+ICFyZWFkeSxcbiAgICB9LFxuICApKSB7XG4gICAgaWYgKGhlYWx0aHkpIHJldHVybjtcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoXCJHcmFwaGl0aSBzaWRlY2FyIGhlYWx0aGNoZWNrIGRpZCBub3Qgc3VjY2VlZFwiKTtcbn1cblxuLyoqIEJ1aWxkIGF1dGhvcml6YXRpb24gaGVhZGVycyBmb3Igb25lIG9wdGlvbmFsbHkgc2VjdXJlZCBHcmFwaGl0aSBydW50aW1lLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdyYXBoaXRpUmVxdWVzdEhlYWRlcnMoXG4gIG9wdGlvbnM6IFBpY2s8UmVzb2x2ZWRHcmFwaGl0aU9wdGlvbnMsIFwiYmVhcmVyXCI+LFxuKTogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgc3RyaW5nPj4ge1xuICByZXR1cm4gb3B0aW9ucy5iZWFyZXIgPyB7IGF1dGhvcml6YXRpb246IGBCZWFyZXIgJHtvcHRpb25zLmJlYXJlcn1gIH0gOiB7fTtcbn1cblxuLyoqIEV4ZWN1dGFibGUgYW5kIGFyZ3VtZW50cyB1c2VkIHRvIGxhdW5jaCBHcmFwaGl0aS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgR3JhcGhpdGlQeXRob25Db21tYW5kIHtcbiAgY29tbWFuZDogc3RyaW5nO1xuICBhcmdzOiBzdHJpbmdbXTtcbn1cblxuLyoqIFJlc29sdmUgY29uZmlndXJlZCBvciBhcHAtaW5zdGFsbGVkIFB5dGhvbiwgb3RoZXJ3aXNlIGEgdXYtcHJvdmlzaW9uZWQgcnVudGltZS4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXNvbHZlR3JhcGhpdGlQeXRob25Db21tYW5kKFxuICBvcHRpb25zOiB7IGRldj86IGJvb2xlYW4gfSA9IHt9LFxuICAuLi5hcmdzOiBzdHJpbmdbXVxuKTogUHJvbWlzZTxHcmFwaGl0aVB5dGhvbkNvbW1hbmQ+IHtcbiAgY29uc3QgcHl0aG9uID0gcHJvY2Vzcy5lbnYuUFlUSE9OPy50cmltKCk7XG4gIGlmIChweXRob24pIHJldHVybiB7IGNvbW1hbmQ6IHB5dGhvbiwgYXJncyB9O1xuICBpZiAoZW52aXJvbm1lbnRVdGlscy5pc0RhdGFicmlja3NBcHBFbnYoKSkge1xuICAgIGNvbnN0IGluc3RhbGxlZCA9IGF3YWl0IGdyYXBoaXRpUHl0aG9uKCk7XG4gICAgaWYgKGluc3RhbGxlZCkgcmV0dXJuIHsgY29tbWFuZDogaW5zdGFsbGVkLCBhcmdzIH07XG4gIH1cbiAgY29uc3QgZXh0cmEgPSBvcHRpb25zLmRldiA/IFwiW2Rldl1cIiA6IFwiXCI7XG4gIGNvbnN0IHBhY2thZ2VBcmdzID0gW1xuICAgIFwiLS13aXRoXCIsXG4gICAgYGRieC10b29scy1ncmFwaGl0aSR7ZXh0cmF9PT0keyhhd2FpdCBpbXBvcnQoXCIuLi8uLi9pbmRleC50c1wiKSkuUEFDS0FHRV9WRVJTSU9OfWAsXG4gIF07XG4gIHJldHVybiB7XG4gICAgY29tbWFuZDogXCJ1dlwiLFxuICAgIGFyZ3M6IFtcInJ1blwiLCBcIi0tbm8tcHJvamVjdFwiLCAuLi5wYWNrYWdlQXJncywgXCItLXB5dGhvblwiLCBcInB5dGhvbjNcIiwgXCJweXRob25cIiwgLi4uYXJnc10sXG4gIH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIF9wcm9iZVB5dGhvbihjb21tYW5kOiBzdHJpbmcpOiBQcm9taXNlPFB5dGhvbkNhbmRpZGF0ZSB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCB2ZXJzaW9uUmVzdWx0ID0gYXdhaXQgZXhlYy5zcGF3bihjb21tYW5kLCBbXCItVlwiXSwge1xuICAgIGNoZWNrOiBmYWxzZSxcbiAgICBzdGRpbjogXCJpZ25vcmVcIixcbiAgICBzdGRvdXQ6IFwiY2FwdHVyZVwiLFxuICAgIHN0ZGVycjogXCJjYXB0dXJlXCIsXG4gICAgdHJpbTogdHJ1ZSxcbiAgfSk7XG4gIGlmICh2ZXJzaW9uUmVzdWx0LmV4aXRDb2RlICE9PSAwKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCB2ZXJzaW9uID0gY29lcmNlKGAke3ZlcnNpb25SZXN1bHQuc3Rkb3V0fVxcbiR7dmVyc2lvblJlc3VsdC5zdGRlcnJ9YCk7XG4gIGlmICghdmVyc2lvbikgcmV0dXJuIHVuZGVmaW5lZDtcblxuICBjb25zdCBpbXBvcnRSZXN1bHQgPSBhd2FpdCBleGVjLnNwYXduKGNvbW1hbmQsIFtcIi1jXCIsIEdSQVBISVRJX0lNUE9SVF9QUk9CRV0sIHtcbiAgICBjaGVjazogZmFsc2UsXG4gICAgc3RkaW46IFwiaWdub3JlXCIsXG4gICAgc3Rkb3V0OiBcImlnbm9yZVwiLFxuICAgIHN0ZGVycjogXCJpZ25vcmVcIixcbiAgfSk7XG4gIHJldHVybiBpbXBvcnRSZXN1bHQuZXhpdENvZGUgPT09IDAgPyB7IGNvbW1hbmQsIHZlcnNpb24gfSA6IHVuZGVmaW5lZDtcbn1cblxuLyoqIEJ1aWxkIG9uZSBIVFRQIFVSTCBmb3IgYSByZXNvbHZlZCBHcmFwaGl0aSBsaXN0ZW5lci4gKi9cbmV4cG9ydCBmdW5jdGlvbiBncmFwaGl0aUh0dHBVcmwoXG4gIG9wdGlvbnM6IFBpY2s8UmVzb2x2ZWRHcmFwaGl0aU9wdGlvbnMsIFwibGlzdGVuXCI+LFxuICBwYXRoOiBzdHJpbmcsXG4pOiBzdHJpbmcge1xuICByZXR1cm4gYCR7c2hhcmVkT3B0aW9uc1xuICAgIC5mb3JtYXRMaXN0ZW5BZGRyZXNzKG9wdGlvbnMubGlzdGVuKVxuICAgIC5yZXBsYWNlKC9edGNwOi8sIFwiaHR0cDpcIil9JHtwYXRoLnN0YXJ0c1dpdGgoXCIvXCIpID8gcGF0aCA6IGAvJHtwYXRofWB9YDtcbn1cblxuLyoqIEJ1aWxkIG9uZSByZWFkaW5lc3MtZ2F0ZWQgR3JhcGhpdGkgc2lkZWNhciBmcm9tIHRoZSBzaGFyZWQgdHlwZWQgb3B0aW9ucy4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVHcmFwaGl0aUNoaWxkUHJvY2VzcyhcbiAgb3B0aW9uczogR3JhcGhpdGlSdW50aW1lT3B0aW9ucyA9IHt9LFxuKTogUHJvbWlzZTxHcmFwaGl0aUNoaWxkUHJvY2Vzcz4ge1xuICBjb25zdCBoZWFsdGhDaGVjayA9IG9wdGlvbnMuaGVhbHRoQ2hlY2s7XG4gIGNvbnN0IHJlc29sdmVkID0gcmVzb2x2ZUdyYXBoaXRpT3B0aW9ucyhncmFwaGl0aU9wdGlvbnMob3B0aW9ucykpO1xuICBjb25zdCBweXRob24gPSBhd2FpdCByZXNvbHZlR3JhcGhpdGlQeXRob25Db21tYW5kKFxuICAgIHsgZGV2OiAhcmVzb2x2ZWQuZGF0YWJhc2VVcmwgfSxcbiAgICBcIi1tXCIsXG4gICAgXCJkYnhfdG9vbHMuZ3JhcGhpdGlcIixcbiAgKTtcbiAgY29uc3QgY2hpbGQgPSBleGVjLnNwYXduKHB5dGhvbi5jb21tYW5kLCBweXRob24uYXJncywge1xuICAgIGVudjogX3J1bnRpbWVFbnZpcm9ubWVudChyZXNvbHZlZCksXG4gICAgZm9yd2FyZFRlcm1pbmF0aW9uU2lnbmFsczogZmFsc2UsXG4gIH0pO1xuICBjb25zdCBjb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICBjb25zdCBzdGFydHVwU2lnbmFsID0gb3B0aW9ucy5zaWduYWxcbiAgICA/IEFib3J0U2lnbmFsLmFueShbY29udHJvbGxlci5zaWduYWwsIG9wdGlvbnMuc2lnbmFsXSlcbiAgICA6IGNvbnRyb2xsZXIuc2lnbmFsO1xuICBjb25zdCBwcm9iZSA9IGhlYWx0aENoZWNrID8/ICgoeyBzaWduYWwgfSkgPT4gZ3JhcGhpdGlIZWFsdGhDaGVjayhyZXNvbHZlZCwgc2lnbmFsKSk7XG4gIHRyeSB7XG4gICAgYXdhaXQgUHJvbWlzZS5yYWNlKFtcbiAgICAgIHdhaXRGb3JHcmFwaGl0aUNoaWxkKGNoaWxkLCBwcm9iZSwgcmVzb2x2ZWQuc3RhcnR1cFRpbWVvdXRNcywgc3RhcnR1cFNpZ25hbCksXG4gICAgICBjaGlsZC50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBHcmFwaGl0aSBjaGlsZCAke2NoaWxkLnBpZCA/PyBcIjx1bmtub3duPlwifSBleGl0ZWQgYmVmb3JlIGJlY29taW5nIHJlYWR5IGAgK1xuICAgICAgICAgICAgYChleGl0ICR7cmVzdWx0LmV4aXRDb2RlfSlgLFxuICAgICAgICApO1xuICAgICAgfSksXG4gICAgXSk7XG4gICAgcmV0dXJuIHsgY2hpbGQgfTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBhd2FpdCBjaGlsZC5zaHV0ZG93bigpO1xuICAgIHRocm93IGVycm9yO1xuICB9IGZpbmFsbHkge1xuICAgIGNvbnRyb2xsZXIuYWJvcnQoKTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiB3YWl0Rm9yR3JhcGhpdGlDaGlsZChcbiAgY2hpbGQ6IENoaWxkUHJvY2Vzc1Jlc3VsdCxcbiAgaGVhbHRoQ2hlY2s6IEdyYXBoaXRpSGVhbHRoQ2hlY2ssXG4gIHRpbWVvdXRNczogbnVtYmVyLFxuICBzaWduYWw6IEFib3J0U2lnbmFsLFxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGZvciBhd2FpdCAoY29uc3QgaGVhbHRoeSBvZiBhc3luY1V0aWxzLnBvbGwoXG4gICAgKHsgYXR0ZW1wdCwgc2lnbmFsOiBwb2xsU2lnbmFsIH0pID0+XG4gICAgICBoZWFsdGhDaGVjayh7IHByb2Nlc3M6IGNoaWxkLCBzaWduYWw6IHBvbGxTaWduYWwsIGF0dGVtcHQgfSksXG4gICAge1xuICAgICAgaW50ZXJ2YWxNczogSEVBTFRIX0NIRUNLX0lOVEVSVkFMX01TLFxuICAgICAgdGltZW91dE1zLFxuICAgICAgc2lnbmFsLFxuICAgICAgcHJlZGljYXRlOiAocmVhZHkpID0+ICFyZWFkeSxcbiAgICB9LFxuICApKSB7XG4gICAgaWYgKGhlYWx0aHkpIHJldHVybjtcbiAgfVxufVxuXG4vKiogUnVuIHRoZSBzdXBlcnZpc2VkIHN0YWNrIHVudGlsIHRoZSBjaGlsZCBleGl0cy4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBydW5HcmFwaGl0aShvcHRpb25zOiBHcmFwaGl0aVJ1bnRpbWVPcHRpb25zID0ge30pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyBjaGlsZCB9ID0gYXdhaXQgY3JlYXRlR3JhcGhpdGlDaGlsZFByb2Nlc3Mob3B0aW9ucyk7XG4gIGNvbnN0IG91dGNvbWUgPSBhd2FpdCBjaGlsZDtcbiAgaWYgKG91dGNvbWUuZXhpdENvZGUgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEdyYXBoaXRpIGNoaWxkIGV4aXRlZCB3aXRoIHN0YXR1cyAke291dGNvbWUuZXhpdENvZGV9YCk7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AppKit memory plugin with Databricks-first tools and lazy Graphiti fallback.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { type PluginManifest } from "@databricks/appkit";
|
|
7
|
+
import { type ToolkitEntry, type ToolkitOptions, type ToolRegistry } from "@databricks/appkit/beta";
|
|
8
|
+
import { ToolRegistryPlugin, type AgentToolExecutionContext } from "@dbx-tools/appkit";
|
|
9
|
+
import { type MemoryPluginConfig } from "./config.ts";
|
|
10
|
+
/** AppKit memory plugin with Databricks managed memory and Graphiti fallback. */
|
|
11
|
+
export declare class MemoryPlugin extends ToolRegistryPlugin<MemoryPluginConfig> {
|
|
12
|
+
static phase: "deferred";
|
|
13
|
+
static manifest: PluginManifest<"memory">;
|
|
14
|
+
private readonly logger;
|
|
15
|
+
private resolved?;
|
|
16
|
+
private databricks?;
|
|
17
|
+
private graphiti?;
|
|
18
|
+
private graphitiStarting?;
|
|
19
|
+
private readonly graphitiStartupAbort;
|
|
20
|
+
private closed;
|
|
21
|
+
protected get toolRegistry(): ToolRegistry;
|
|
22
|
+
setup(): Promise<void>;
|
|
23
|
+
toolkit(options?: ToolkitOptions): Promise<Record<string, ToolkitEntry>>;
|
|
24
|
+
executeAgentTool(name: string, args: unknown, signal?: AbortSignal, context?: AgentToolExecutionContext): Promise<unknown>;
|
|
25
|
+
abortActiveOperations(): void;
|
|
26
|
+
shutdown(): Promise<void>;
|
|
27
|
+
private registry;
|
|
28
|
+
private remember;
|
|
29
|
+
private recall;
|
|
30
|
+
private saveTurn;
|
|
31
|
+
private databricksBackend;
|
|
32
|
+
private shouldFallbackFromDatabricks;
|
|
33
|
+
private graphitiBackend;
|
|
34
|
+
private actorId;
|
|
35
|
+
private requireConfig;
|
|
36
|
+
}
|
|
37
|
+
/** AppKit registration factory for {@link MemoryPlugin}. */
|
|
38
|
+
export declare const memory: import("@databricks/appkit").ToPlugin<typeof MemoryPlugin, MemoryPluginConfig, "memory">;
|