@fluidframework/tree-agent 2.63.0-359461 → 2.63.0-359962
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/api-report/tree-agent.alpha.api.md +3 -24
- package/dist/agent.d.ts +0 -3
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +21 -49
- package/dist/agent.js.map +1 -1
- package/dist/alpha.d.ts +0 -2
- package/dist/api.d.ts +19 -7
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -4
- package/dist/index.js.map +1 -1
- package/dist/prompt.d.ts.map +1 -1
- package/dist/prompt.js +15 -17
- package/dist/prompt.js.map +1 -1
- package/dist/utils.d.ts +4 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +16 -1
- package/dist/utils.js.map +1 -1
- package/lib/agent.d.ts +0 -3
- package/lib/agent.d.ts.map +1 -1
- package/lib/agent.js +22 -50
- package/lib/agent.js.map +1 -1
- package/lib/alpha.d.ts +0 -2
- package/lib/api.d.ts +19 -7
- package/lib/api.d.ts.map +1 -1
- package/lib/api.js.map +1 -1
- package/lib/index.d.ts +0 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +0 -1
- package/lib/index.js.map +1 -1
- package/lib/prompt.d.ts.map +1 -1
- package/lib/prompt.js +15 -17
- package/lib/prompt.js.map +1 -1
- package/lib/utils.d.ts +4 -0
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +14 -0
- package/lib/utils.js.map +1 -1
- package/package.json +11 -12
- package/src/agent.ts +29 -61
- package/src/api.ts +20 -12
- package/src/index.ts +0 -1
- package/src/prompt.ts +15 -17
- package/src/utils.ts +14 -0
- package/dist/functionParsing.d.ts +0 -13
- package/dist/functionParsing.d.ts.map +0 -1
- package/dist/functionParsing.js +0 -215
- package/dist/functionParsing.js.map +0 -1
- package/dist/langchain.d.ts +0 -43
- package/dist/langchain.d.ts.map +0 -1
- package/dist/langchain.js +0 -90
- package/dist/langchain.js.map +0 -1
- package/lib/functionParsing.d.ts +0 -13
- package/lib/functionParsing.d.ts.map +0 -1
- package/lib/functionParsing.js +0 -210
- package/lib/functionParsing.js.map +0 -1
- package/lib/langchain.d.ts +0 -43
- package/lib/langchain.d.ts.map +0 -1
- package/lib/langchain.js +0 -84
- package/lib/langchain.js.map +0 -1
- package/src/functionParsing.ts +0 -268
- package/src/langchain.ts +0 -146
|
@@ -20,15 +20,6 @@ export function buildFunc<const Return extends z.ZodTypeAny, const Args extends
|
|
|
20
20
|
rest?: Rest;
|
|
21
21
|
}, ...args: Args): FunctionDef<Args, Return, Rest>;
|
|
22
22
|
|
|
23
|
-
// @alpha @deprecated
|
|
24
|
-
export function createSemanticAgent<TSchema extends ImplicitFieldSchema_2>(client: BaseChatModel, treeView: TreeView<TSchema>, options?: Readonly<SemanticAgentOptions>): SharedTreeSemanticAgent<TSchema>;
|
|
25
|
-
|
|
26
|
-
// @alpha @deprecated
|
|
27
|
-
export function createSemanticAgent<TSchema extends ImplicitFieldSchema_2>(client: BaseChatModel, node: ReadableField<TSchema> & TreeNode_2, options?: Readonly<SemanticAgentOptions>): SharedTreeSemanticAgent<TSchema>;
|
|
28
|
-
|
|
29
|
-
// @alpha @deprecated
|
|
30
|
-
export function createSemanticAgent<TSchema extends ImplicitFieldSchema_2>(client: BaseChatModel, treeView: TreeView<TSchema> | (ReadableField<TSchema> & TreeNode_2), options?: Readonly<SemanticAgentOptions>): SharedTreeSemanticAgent<TSchema>;
|
|
31
|
-
|
|
32
23
|
// @alpha
|
|
33
24
|
export type Ctor<T = any> = new (...args: any[]) => T;
|
|
34
25
|
|
|
@@ -36,7 +27,7 @@ export type Ctor<T = any> = new (...args: any[]) => T;
|
|
|
36
27
|
export interface EditResult {
|
|
37
28
|
message: string;
|
|
38
29
|
// (undocumented)
|
|
39
|
-
type: "success" | "disabledError" | "validationError" | "
|
|
30
|
+
type: "success" | "disabledError" | "validationError" | "executionError" | "tooManyEditsError" | "expiredError";
|
|
40
31
|
}
|
|
41
32
|
|
|
42
33
|
// @alpha
|
|
@@ -72,19 +63,6 @@ export interface IExposedMethods {
|
|
|
72
63
|
// @alpha
|
|
73
64
|
export type Infer<T> = T extends FunctionDef<infer Args, infer Return, infer Rest> ? z.infer<z.ZodFunction<z.ZodTuple<ArgsTuple<Args>, Rest>, Return>> : never;
|
|
74
65
|
|
|
75
|
-
// @alpha
|
|
76
|
-
export class LangchainChatModel implements SharedTreeChatModel {
|
|
77
|
-
constructor(model: BaseChatModel);
|
|
78
|
-
// (undocumented)
|
|
79
|
-
appendContext(text: string): void;
|
|
80
|
-
// (undocumented)
|
|
81
|
-
readonly editToolName = "GenerateTreeEditingCode";
|
|
82
|
-
// (undocumented)
|
|
83
|
-
get name(): string | undefined;
|
|
84
|
-
// (undocumented)
|
|
85
|
-
query(query: SharedTreeChatQuery): Promise<string>;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
66
|
// @alpha
|
|
89
67
|
export const llmDefault: unique symbol;
|
|
90
68
|
|
|
@@ -101,9 +79,10 @@ export type MethodKeys<T> = {
|
|
|
101
79
|
// @alpha
|
|
102
80
|
export interface SemanticAgentOptions {
|
|
103
81
|
domainHints?: string;
|
|
82
|
+
executeEdit?: (context: Record<string, unknown>, code: string) => void | Promise<void>;
|
|
104
83
|
logger?: Logger;
|
|
105
84
|
maximumSequentialEdits?: number;
|
|
106
|
-
|
|
85
|
+
validateEdit?: (code: string) => void | Promise<void>;
|
|
107
86
|
}
|
|
108
87
|
|
|
109
88
|
// @alpha
|
package/dist/agent.d.ts
CHANGED
package/dist/agent.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACX,mBAAmB,EAGnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,KAAK,EACX,aAAa,EAIb,MAAM,4BAA4B,CAAC;AAGpC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACX,mBAAmB,EAGnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,KAAK,EACX,aAAa,EAIb,MAAM,4BAA4B,CAAC;AAGpC,OAAO,KAAK,EAAE,mBAAmB,EAAc,oBAAoB,EAAU,MAAM,UAAU,CAAC;AAG9F,OAAO,EAIN,KAAK,QAAQ,EAGb,MAAM,YAAY,CAAC;AAQpB;;;;GAIG;AACH,qBAAa,uBAAuB,CAAC,OAAO,SAAS,mBAAmB;IAStE,OAAO,CAAC,QAAQ,CAAC,MAAM;IAEvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAT1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmB;IAC7C;;OAEG;IACH,OAAO,CAAC,gBAAgB,CAAS;gBAGf,MAAM,EAAE,mBAAmB,EAC5C,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,EAC5C,OAAO,CAAC,4CAAgC;IAiC1D;;;;;OAKG;IACU,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAsEvD"}
|
package/dist/agent.js
CHANGED
|
@@ -7,7 +7,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
exports.SharedTreeSemanticAgent = void 0;
|
|
8
8
|
const tree_1 = require("@fluidframework/tree");
|
|
9
9
|
const alpha_1 = require("@fluidframework/tree/alpha");
|
|
10
|
-
const functionParsing_js_1 = require("./functionParsing.js");
|
|
11
10
|
const prompt_js_1 = require("./prompt.js");
|
|
12
11
|
const subtree_js_1 = require("./subtree.js");
|
|
13
12
|
const utils_js_1 = require("./utils.js");
|
|
@@ -16,10 +15,6 @@ const utils_js_1 = require("./utils.js");
|
|
|
16
15
|
* @remarks This can be overridden by passing {@link SemanticAgentOptions.maximumSequentialEdits | maximumSequentialEdits} to {@link createSemanticAgent}.
|
|
17
16
|
*/
|
|
18
17
|
const defaultMaxSequentialEdits = 20;
|
|
19
|
-
/**
|
|
20
|
-
* The name of the parameter passed to the edit function.
|
|
21
|
-
*/
|
|
22
|
-
const paramsName = "params";
|
|
23
18
|
/**
|
|
24
19
|
* An agent that uses a {@link SharedTreeChatModel} to interact with a SharedTree.
|
|
25
20
|
* @remarks This class forwards user queries to the chat model, and handles the application of any edits to the tree that the model requests.
|
|
@@ -85,7 +80,7 @@ class SharedTreeSemanticAgent {
|
|
|
85
80
|
let editCount = 0;
|
|
86
81
|
let editFailed = false;
|
|
87
82
|
const { editToolName } = this.client;
|
|
88
|
-
const edit = async (
|
|
83
|
+
const edit = async (editCode) => {
|
|
89
84
|
if (editToolName === undefined) {
|
|
90
85
|
return {
|
|
91
86
|
type: "disabledError",
|
|
@@ -105,7 +100,7 @@ class SharedTreeSemanticAgent {
|
|
|
105
100
|
message: `The maximum number of edits (${maxEditCount}) for this query has been exceeded.`,
|
|
106
101
|
};
|
|
107
102
|
}
|
|
108
|
-
const editResult = await applyTreeFunction(queryTree,
|
|
103
|
+
const editResult = await applyTreeFunction(queryTree, editCode, this.options?.validateEdit ?? defaultValidateEdit, this.options?.executeEdit ?? defaultExecuteEdit, this.options?.logger);
|
|
109
104
|
editFailed ||= editResult.type !== "success";
|
|
110
105
|
return editResult;
|
|
111
106
|
};
|
|
@@ -156,14 +151,18 @@ function constructTreeNode(schema, value) {
|
|
|
156
151
|
/**
|
|
157
152
|
* Applies the given function (as a string of JavaScript code or an actual function) to the given tree.
|
|
158
153
|
*/
|
|
159
|
-
async function applyTreeFunction(tree,
|
|
154
|
+
async function applyTreeFunction(tree, editCode, validateEdit, executeEdit, logger) {
|
|
160
155
|
logger?.log(`### Editing Tool Invoked\n\n`);
|
|
161
|
-
logger?.log(`#### Generated Code\n\n\`\`\`javascript\n${
|
|
162
|
-
|
|
156
|
+
logger?.log(`#### Generated Code\n\n\`\`\`javascript\n${editCode}\n\`\`\`\n\n`);
|
|
157
|
+
try {
|
|
158
|
+
await validateEdit(editCode);
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
163
161
|
logger?.log(`#### Code Validation Failed\n\n`);
|
|
162
|
+
logger?.log(`\`\`\`JSON\n${(0, utils_js_1.toErrorString)(error)}\n\`\`\`\n\n`);
|
|
164
163
|
return {
|
|
165
164
|
type: "validationError",
|
|
166
|
-
message:
|
|
165
|
+
message: `The generated code did not pass validation: ${(0, utils_js_1.toErrorString)(error)}`,
|
|
167
166
|
};
|
|
168
167
|
}
|
|
169
168
|
// Stick the tree schema constructors on an object passed to the function so that the LLM can create new nodes.
|
|
@@ -174,7 +173,7 @@ async function applyTreeFunction(tree, fn, validator, logger) {
|
|
|
174
173
|
}
|
|
175
174
|
// Fork a branch to edit. If the edit fails or produces an error, we discard this branch, otherwise we merge it.
|
|
176
175
|
const editTree = tree.fork();
|
|
177
|
-
const
|
|
176
|
+
const context = {
|
|
178
177
|
get root() {
|
|
179
178
|
return editTree.field;
|
|
180
179
|
},
|
|
@@ -183,36 +182,16 @@ async function applyTreeFunction(tree, fn, validator, logger) {
|
|
|
183
182
|
},
|
|
184
183
|
create,
|
|
185
184
|
};
|
|
186
|
-
let editFunction;
|
|
187
|
-
if (typeof fn === "string") {
|
|
188
|
-
try {
|
|
189
|
-
editFunction = processLlmCode(fn);
|
|
190
|
-
}
|
|
191
|
-
catch (error) {
|
|
192
|
-
logger?.log(`#### Error\n\n`);
|
|
193
|
-
const errorMessage = error instanceof Error ? error.message : JSON.stringify(error);
|
|
194
|
-
logger?.log(`\`\`\`JSON\n${errorMessage}\n\`\`\`\n\n`);
|
|
195
|
-
editTree.branch.dispose();
|
|
196
|
-
return {
|
|
197
|
-
type: "compileError",
|
|
198
|
-
message: `The supplied JavaScript function is not valid: ${errorMessage}`,
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
else {
|
|
203
|
-
editFunction = fn;
|
|
204
|
-
}
|
|
205
185
|
try {
|
|
206
|
-
await
|
|
186
|
+
await executeEdit(context, editCode);
|
|
207
187
|
}
|
|
208
188
|
catch (error) {
|
|
209
189
|
logger?.log(`#### Error\n\n`);
|
|
210
|
-
|
|
211
|
-
logger?.log(`\`\`\`JSON\n${errorMessage}\n\`\`\`\n\n`);
|
|
190
|
+
logger?.log(`\`\`\`JSON\n${(0, utils_js_1.toErrorString)(error)}\n\`\`\`\n\n`);
|
|
212
191
|
editTree.branch.dispose();
|
|
213
192
|
return {
|
|
214
|
-
type: "
|
|
215
|
-
message: `Running the
|
|
193
|
+
type: "executionError",
|
|
194
|
+
message: `Running the generated code produced an error. The state of the tree will be reset to its previous state as it was before the code ran. Please try again. Here is the error: ${(0, utils_js_1.toErrorString)(error)}`,
|
|
216
195
|
};
|
|
217
196
|
}
|
|
218
197
|
tree.branch.merge(editTree.branch);
|
|
@@ -220,20 +199,13 @@ async function applyTreeFunction(tree, fn, validator, logger) {
|
|
|
220
199
|
logger?.log(`${`\`\`\`JSON\n${(0, prompt_js_1.stringifyTree)(tree.field)}\n\`\`\``}\n\n`);
|
|
221
200
|
return {
|
|
222
201
|
type: "success",
|
|
223
|
-
message: `After running the
|
|
202
|
+
message: `After running the code, the new state of the tree is:\n\n\`\`\`JSON\n${(0, prompt_js_1.stringifyTree)(tree.field)}\n\`\`\``,
|
|
224
203
|
};
|
|
225
204
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
if (functionName === undefined) {
|
|
229
|
-
throw new Error("Generated code does not contain an invokable function");
|
|
230
|
-
}
|
|
231
|
-
const executionCode = `${(0, functionParsing_js_1.stripExportSyntax)(code)}\n\nreturn ${functionName}(${paramsName});`;
|
|
205
|
+
const defaultValidateEdit = () => { };
|
|
206
|
+
const defaultExecuteEdit = async (context, code) => {
|
|
232
207
|
// eslint-disable-next-line no-new-func, @typescript-eslint/no-implied-eval
|
|
233
|
-
const fn = new Function(
|
|
234
|
-
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Finds the name of the first invocable function in the given code.
|
|
238
|
-
*/
|
|
208
|
+
const fn = new Function("context", code);
|
|
209
|
+
await fn(context);
|
|
210
|
+
};
|
|
239
211
|
//# sourceMappingURL=agent.js.map
|
package/dist/agent.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tImplicitFieldSchema,\n\tTreeFieldFromImplicitField,\n\tTreeNodeSchema,\n} from \"@fluidframework/tree\";\nimport { TreeNode } from \"@fluidframework/tree\";\nimport type {\n\tReadableField,\n\tFactoryContentObject,\n\tInsertableContent,\n\tReadSchema,\n} from \"@fluidframework/tree/alpha\";\nimport { ObjectNodeSchema, Tree } from \"@fluidframework/tree/alpha\";\n\nimport type {\n\tSharedTreeChatModel,\n\tEditFunction,\n\tEditResult,\n\tSemanticAgentOptions,\n\tLogger,\n} from \"./api.js\";\nimport { findInvocableFunctionName, stripExportSyntax } from \"./functionParsing.js\";\nimport { getPrompt, stringifyTree } from \"./prompt.js\";\nimport { Subtree } from \"./subtree.js\";\nimport {\n\tconstructNode,\n\tgetFriendlyName,\n\tllmDefault,\n\ttype TreeView,\n\tfindNamedSchemas,\n} from \"./utils.js\";\n\n/**\n * The default maximum number of sequential edits the LLM can make before we assume it's stuck in a loop.\n * @remarks This can be overridden by passing {@link SemanticAgentOptions.maximumSequentialEdits | maximumSequentialEdits} to {@link createSemanticAgent}.\n */\nconst defaultMaxSequentialEdits = 20;\n\n/**\n * The name of the parameter passed to the edit function.\n */\nconst paramsName = \"params\";\n\n/**\n * An agent that uses a {@link SharedTreeChatModel} to interact with a SharedTree.\n * @remarks This class forwards user queries to the chat model, and handles the application of any edits to the tree that the model requests.\n * @alpha @sealed\n */\nexport class SharedTreeSemanticAgent<TSchema extends ImplicitFieldSchema> {\n\t// Converted from ECMAScript private fields (#name) to TypeScript private members for easier debugger inspection.\n\tprivate readonly outerTree: Subtree<TSchema>;\n\t/**\n\t * Whether or not the outer tree has changed since the last query finished.\n\t */\n\tprivate outerTreeIsDirty = false;\n\n\tpublic constructor(\n\t\tprivate readonly client: SharedTreeChatModel,\n\t\ttree: TreeView<TSchema> | (ReadableField<TSchema> & TreeNode),\n\t\tprivate readonly options?: Readonly<SemanticAgentOptions>,\n\t) {\n\t\tif (tree instanceof TreeNode) {\n\t\t\tTree.on(tree, \"treeChanged\", () => (this.outerTreeIsDirty = true));\n\t\t} else {\n\t\t\ttree.events.on(\"changed\", () => (this.outerTreeIsDirty = true));\n\t\t}\n\n\t\tthis.outerTree = new Subtree(tree);\n\t\tconst prompt = getPrompt({\n\t\t\tsubtree: this.outerTree,\n\t\t\teditToolName: this.client.editToolName,\n\t\t\tdomainHints: this.options?.domainHints,\n\t\t});\n\t\tthis.options?.logger?.log(`# Fluid Framework SharedTree AI Agent Log\\n\\n`);\n\t\tconst now = new Date();\n\t\tconst formattedDate = now.toLocaleString(undefined, {\n\t\t\tweekday: \"long\",\n\t\t\tyear: \"numeric\",\n\t\t\tmonth: \"long\",\n\t\t\tday: \"numeric\",\n\t\t\thour: \"numeric\",\n\t\t\tminute: \"2-digit\",\n\t\t\tsecond: \"2-digit\",\n\t\t});\n\t\tthis.options?.logger?.log(`Agent created: **${formattedDate}**\\n\\n`);\n\t\tif (this.client.name !== undefined) {\n\t\t\tthis.options?.logger?.log(`Model: **${this.client.name}**\\n\\n`);\n\t\t}\n\t\tthis.client.appendContext?.(prompt);\n\t\tthis.options?.logger?.log(`## System Prompt\\n\\n${prompt}\\n\\n`);\n\t}\n\n\t/**\n\t * Given a user prompt, return a response.\n\t *\n\t * @param userPrompt - The prompt to send to the agent.\n\t * @returns The agent's response.\n\t */\n\tpublic async query(userPrompt: string): Promise<string> {\n\t\tthis.options?.logger?.log(`## User Query\\n\\n${userPrompt}\\n\\n`);\n\n\t\t// Notify the llm if the tree has changed since the last query, and if so, provide the new state of the tree.\n\t\tif (this.outerTreeIsDirty) {\n\t\t\tconst stringified = stringifyTree(this.outerTree.field);\n\t\t\tthis.client.appendContext?.(\n\t\t\t\t`The tree has changed since the last query. The new state of the tree is: \\n\\n\\`\\`\\`JSON\\n${stringified}\\n\\`\\`\\``,\n\t\t\t);\n\t\t\tthis.options?.logger?.log(\n\t\t\t\t`### Latest Tree State\\n\\nThe Tree was edited by a local or remote user since the previous query. The latest state is:\\n\\n\\`\\`\\`JSON\\n${stringified}\\n\\`\\`\\`\\n\\n`,\n\t\t\t);\n\t\t}\n\n\t\t// Fork a branch that will live for the lifetime of this query (which can be multiple LLM calls if the there are errors or the LLM decides to take multiple steps to accomplish a task).\n\t\t// The branch will be merged back into the outer branch if and only if the query succeeds.\n\t\tconst queryTree = this.outerTree.fork();\n\t\tconst maxEditCount = this.options?.maximumSequentialEdits ?? defaultMaxSequentialEdits;\n\t\tlet active = true;\n\t\tlet editCount = 0;\n\t\tlet editFailed = false;\n\t\tconst { editToolName } = this.client;\n\t\tconst edit = async (js: string): Promise<EditResult> => {\n\t\t\tif (editToolName === undefined) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"disabledError\",\n\t\t\t\t\tmessage: \"Editing is not enabled for this model.\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (!active) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"expiredError\",\n\t\t\t\t\tmessage: `The query has already completed. Further edits are not allowed.`,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (++editCount > maxEditCount) {\n\t\t\t\teditFailed = true;\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"tooManyEditsError\",\n\t\t\t\t\tmessage: `The maximum number of edits (${maxEditCount}) for this query has been exceeded.`,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst editResult = await applyTreeFunction(\n\t\t\t\tqueryTree,\n\t\t\t\tjs,\n\t\t\t\tthis.options?.validator,\n\t\t\t\tthis.options?.logger,\n\t\t\t);\n\n\t\t\teditFailed ||= editResult.type !== \"success\";\n\t\t\treturn editResult;\n\t\t};\n\n\t\tconst responseMessage = await this.client.query({\n\t\t\ttext: userPrompt,\n\t\t\tedit,\n\t\t});\n\t\tactive = false;\n\n\t\tif (!editFailed) {\n\t\t\tthis.outerTree.branch.merge(queryTree.branch);\n\t\t\tthis.outerTreeIsDirty = false;\n\t\t}\n\t\tthis.options?.logger?.log(`## Response\\n\\n`);\n\t\tthis.options?.logger?.log(`${responseMessage}\\n\\n`);\n\t\treturn responseMessage;\n\t}\n}\n\n/**\n * Creates an unhydrated node of the given schema with the given value.\n * @remarks If the schema is an object with {@link llmDefault | default values}, this function populates the node with those defaults.\n */\nfunction constructTreeNode(schema: TreeNodeSchema, value: FactoryContentObject): TreeNode {\n\tif (schema instanceof ObjectNodeSchema) {\n\t\tconst inputWithDefaults: Record<string, InsertableContent | undefined> = {};\n\t\tfor (const [key, field] of schema.fields) {\n\t\t\tif (value[key] === undefined) {\n\t\t\t\tif (\n\t\t\t\t\ttypeof field.metadata.custom === \"object\" &&\n\t\t\t\t\tfield.metadata.custom !== null &&\n\t\t\t\t\tllmDefault in field.metadata.custom\n\t\t\t\t) {\n\t\t\t\t\tconst defaulter = field.metadata.custom[llmDefault];\n\t\t\t\t\tif (typeof defaulter === \"function\") {\n\t\t\t\t\t\tconst defaultValue: unknown = defaulter();\n\t\t\t\t\t\tif (defaultValue !== undefined) {\n\t\t\t\t\t\t\tinputWithDefaults[key] = defaultValue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tinputWithDefaults[key] = value[key];\n\t\t\t}\n\t\t}\n\t\treturn constructNode(schema, inputWithDefaults);\n\t}\n\treturn constructNode(schema, value);\n}\n\n/**\n * Applies the given function (as a string of JavaScript code or an actual function) to the given tree.\n */\nasync function applyTreeFunction<TSchema extends ImplicitFieldSchema>(\n\ttree: Subtree<TSchema>,\n\tfn: string | EditFunction<TSchema>,\n\tvalidator: ((js: string) => boolean) | undefined,\n\tlogger: Logger | undefined,\n): Promise<EditResult> {\n\tlogger?.log(`### Editing Tool Invoked\\n\\n`);\n\tlogger?.log(`#### Generated Code\\n\\n\\`\\`\\`javascript\\n${fn}\\n\\`\\`\\`\\n\\n`);\n\n\tif (validator?.(fn.toString()) === false) {\n\t\tlogger?.log(`#### Code Validation Failed\\n\\n`);\n\t\treturn {\n\t\t\ttype: \"validationError\",\n\t\t\tmessage: \"The generated code did not pass validation. Please try again.\",\n\t\t};\n\t}\n\n\t// Stick the tree schema constructors on an object passed to the function so that the LLM can create new nodes.\n\tconst create: Record<string, (input: FactoryContentObject) => TreeNode> = {};\n\tfor (const schema of findNamedSchemas(tree.schema)) {\n\t\tconst name = getFriendlyName(schema);\n\t\tcreate[name] = (input: FactoryContentObject) => constructTreeNode(schema, input);\n\t}\n\n\t// Fork a branch to edit. If the edit fails or produces an error, we discard this branch, otherwise we merge it.\n\tconst editTree = tree.fork();\n\tconst params = {\n\t\tget root(): ReadableField<TSchema> {\n\t\t\treturn editTree.field;\n\t\t},\n\t\tset root(value: TreeFieldFromImplicitField<ReadSchema<TSchema>>) {\n\t\t\teditTree.field = value;\n\t\t},\n\t\tcreate,\n\t};\n\n\tlet editFunction: EditFunction<TSchema>;\n\tif (typeof fn === \"string\") {\n\t\ttry {\n\t\t\teditFunction = processLlmCode(fn);\n\t\t} catch (error) {\n\t\t\tlogger?.log(`#### Error\\n\\n`);\n\t\t\tconst errorMessage = error instanceof Error ? error.message : JSON.stringify(error);\n\t\t\tlogger?.log(`\\`\\`\\`JSON\\n${errorMessage}\\n\\`\\`\\`\\n\\n`);\n\t\t\teditTree.branch.dispose();\n\t\t\treturn {\n\t\t\t\ttype: \"compileError\",\n\t\t\t\tmessage: `The supplied JavaScript function is not valid: ${errorMessage}`,\n\t\t\t};\n\t\t}\n\t} else {\n\t\teditFunction = fn;\n\t}\n\n\ttry {\n\t\tawait editFunction(params);\n\t} catch (error: unknown) {\n\t\tlogger?.log(`#### Error\\n\\n`);\n\t\tconst errorMessage = error instanceof Error ? error.message : JSON.stringify(error);\n\t\tlogger?.log(`\\`\\`\\`JSON\\n${errorMessage}\\n\\`\\`\\`\\n\\n`);\n\t\teditTree.branch.dispose();\n\t\treturn {\n\t\t\ttype: \"runtimeError\",\n\t\t\tmessage: `Running the function produced an error. The state of the tree will be reset to its previous state as it was before the function ran. Please try again. Here is the error: ${errorMessage}`,\n\t\t};\n\t}\n\n\ttree.branch.merge(editTree.branch);\n\tlogger?.log(`#### New Tree State\\n\\n`);\n\tlogger?.log(`${`\\`\\`\\`JSON\\n${stringifyTree(tree.field)}\\n\\`\\`\\``}\\n\\n`);\n\treturn {\n\t\ttype: \"success\",\n\t\tmessage: `After running the function, the new state of the tree is:\\n\\n\\`\\`\\`JSON\\n${stringifyTree(tree.field)}\\n\\`\\`\\``,\n\t};\n}\n\nfunction processLlmCode<TSchema extends ImplicitFieldSchema>(\n\tcode: string,\n): EditFunction<TSchema> {\n\tconst functionName = findInvocableFunctionName(code);\n\tif (functionName === undefined) {\n\t\tthrow new Error(\"Generated code does not contain an invokable function\");\n\t}\n\n\tconst executionCode = `${stripExportSyntax(code)}\\n\\nreturn ${functionName}(${paramsName});`;\n\t// eslint-disable-next-line no-new-func, @typescript-eslint/no-implied-eval\n\tconst fn = new Function(paramsName, executionCode);\n\treturn fn as EditFunction<TSchema>;\n}\n\n/**\n * Finds the name of the first invocable function in the given code.\n */\n"]}
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tImplicitFieldSchema,\n\tTreeFieldFromImplicitField,\n\tTreeNodeSchema,\n} from \"@fluidframework/tree\";\nimport { TreeNode } from \"@fluidframework/tree\";\nimport type {\n\tReadableField,\n\tFactoryContentObject,\n\tInsertableContent,\n\tReadSchema,\n} from \"@fluidframework/tree/alpha\";\nimport { ObjectNodeSchema, Tree } from \"@fluidframework/tree/alpha\";\n\nimport type { SharedTreeChatModel, EditResult, SemanticAgentOptions, Logger } from \"./api.js\";\nimport { getPrompt, stringifyTree } from \"./prompt.js\";\nimport { Subtree } from \"./subtree.js\";\nimport {\n\tconstructNode,\n\tgetFriendlyName,\n\tllmDefault,\n\ttype TreeView,\n\tfindNamedSchemas,\n\ttoErrorString,\n} from \"./utils.js\";\n\n/**\n * The default maximum number of sequential edits the LLM can make before we assume it's stuck in a loop.\n * @remarks This can be overridden by passing {@link SemanticAgentOptions.maximumSequentialEdits | maximumSequentialEdits} to {@link createSemanticAgent}.\n */\nconst defaultMaxSequentialEdits = 20;\n\n/**\n * An agent that uses a {@link SharedTreeChatModel} to interact with a SharedTree.\n * @remarks This class forwards user queries to the chat model, and handles the application of any edits to the tree that the model requests.\n * @alpha @sealed\n */\nexport class SharedTreeSemanticAgent<TSchema extends ImplicitFieldSchema> {\n\t// Converted from ECMAScript private fields (#name) to TypeScript private members for easier debugger inspection.\n\tprivate readonly outerTree: Subtree<TSchema>;\n\t/**\n\t * Whether or not the outer tree has changed since the last query finished.\n\t */\n\tprivate outerTreeIsDirty = false;\n\n\tpublic constructor(\n\t\tprivate readonly client: SharedTreeChatModel,\n\t\ttree: TreeView<TSchema> | (ReadableField<TSchema> & TreeNode),\n\t\tprivate readonly options?: Readonly<SemanticAgentOptions>,\n\t) {\n\t\tif (tree instanceof TreeNode) {\n\t\t\tTree.on(tree, \"treeChanged\", () => (this.outerTreeIsDirty = true));\n\t\t} else {\n\t\t\ttree.events.on(\"changed\", () => (this.outerTreeIsDirty = true));\n\t\t}\n\n\t\tthis.outerTree = new Subtree(tree);\n\t\tconst prompt = getPrompt({\n\t\t\tsubtree: this.outerTree,\n\t\t\teditToolName: this.client.editToolName,\n\t\t\tdomainHints: this.options?.domainHints,\n\t\t});\n\t\tthis.options?.logger?.log(`# Fluid Framework SharedTree AI Agent Log\\n\\n`);\n\t\tconst now = new Date();\n\t\tconst formattedDate = now.toLocaleString(undefined, {\n\t\t\tweekday: \"long\",\n\t\t\tyear: \"numeric\",\n\t\t\tmonth: \"long\",\n\t\t\tday: \"numeric\",\n\t\t\thour: \"numeric\",\n\t\t\tminute: \"2-digit\",\n\t\t\tsecond: \"2-digit\",\n\t\t});\n\t\tthis.options?.logger?.log(`Agent created: **${formattedDate}**\\n\\n`);\n\t\tif (this.client.name !== undefined) {\n\t\t\tthis.options?.logger?.log(`Model: **${this.client.name}**\\n\\n`);\n\t\t}\n\t\tthis.client.appendContext?.(prompt);\n\t\tthis.options?.logger?.log(`## System Prompt\\n\\n${prompt}\\n\\n`);\n\t}\n\n\t/**\n\t * Given a user prompt, return a response.\n\t *\n\t * @param userPrompt - The prompt to send to the agent.\n\t * @returns The agent's response.\n\t */\n\tpublic async query(userPrompt: string): Promise<string> {\n\t\tthis.options?.logger?.log(`## User Query\\n\\n${userPrompt}\\n\\n`);\n\n\t\t// Notify the llm if the tree has changed since the last query, and if so, provide the new state of the tree.\n\t\tif (this.outerTreeIsDirty) {\n\t\t\tconst stringified = stringifyTree(this.outerTree.field);\n\t\t\tthis.client.appendContext?.(\n\t\t\t\t`The tree has changed since the last query. The new state of the tree is: \\n\\n\\`\\`\\`JSON\\n${stringified}\\n\\`\\`\\``,\n\t\t\t);\n\t\t\tthis.options?.logger?.log(\n\t\t\t\t`### Latest Tree State\\n\\nThe Tree was edited by a local or remote user since the previous query. The latest state is:\\n\\n\\`\\`\\`JSON\\n${stringified}\\n\\`\\`\\`\\n\\n`,\n\t\t\t);\n\t\t}\n\n\t\t// Fork a branch that will live for the lifetime of this query (which can be multiple LLM calls if the there are errors or the LLM decides to take multiple steps to accomplish a task).\n\t\t// The branch will be merged back into the outer branch if and only if the query succeeds.\n\t\tconst queryTree = this.outerTree.fork();\n\t\tconst maxEditCount = this.options?.maximumSequentialEdits ?? defaultMaxSequentialEdits;\n\t\tlet active = true;\n\t\tlet editCount = 0;\n\t\tlet editFailed = false;\n\t\tconst { editToolName } = this.client;\n\t\tconst edit = async (editCode: string): Promise<EditResult> => {\n\t\t\tif (editToolName === undefined) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"disabledError\",\n\t\t\t\t\tmessage: \"Editing is not enabled for this model.\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (!active) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"expiredError\",\n\t\t\t\t\tmessage: `The query has already completed. Further edits are not allowed.`,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (++editCount > maxEditCount) {\n\t\t\t\teditFailed = true;\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"tooManyEditsError\",\n\t\t\t\t\tmessage: `The maximum number of edits (${maxEditCount}) for this query has been exceeded.`,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst editResult = await applyTreeFunction(\n\t\t\t\tqueryTree,\n\t\t\t\teditCode,\n\t\t\t\tthis.options?.validateEdit ?? defaultValidateEdit,\n\t\t\t\tthis.options?.executeEdit ?? defaultExecuteEdit,\n\t\t\t\tthis.options?.logger,\n\t\t\t);\n\n\t\t\teditFailed ||= editResult.type !== \"success\";\n\t\t\treturn editResult;\n\t\t};\n\n\t\tconst responseMessage = await this.client.query({\n\t\t\ttext: userPrompt,\n\t\t\tedit,\n\t\t});\n\t\tactive = false;\n\n\t\tif (!editFailed) {\n\t\t\tthis.outerTree.branch.merge(queryTree.branch);\n\t\t\tthis.outerTreeIsDirty = false;\n\t\t}\n\t\tthis.options?.logger?.log(`## Response\\n\\n`);\n\t\tthis.options?.logger?.log(`${responseMessage}\\n\\n`);\n\t\treturn responseMessage;\n\t}\n}\n\n/**\n * Creates an unhydrated node of the given schema with the given value.\n * @remarks If the schema is an object with {@link llmDefault | default values}, this function populates the node with those defaults.\n */\nfunction constructTreeNode(schema: TreeNodeSchema, value: FactoryContentObject): TreeNode {\n\tif (schema instanceof ObjectNodeSchema) {\n\t\tconst inputWithDefaults: Record<string, InsertableContent | undefined> = {};\n\t\tfor (const [key, field] of schema.fields) {\n\t\t\tif (value[key] === undefined) {\n\t\t\t\tif (\n\t\t\t\t\ttypeof field.metadata.custom === \"object\" &&\n\t\t\t\t\tfield.metadata.custom !== null &&\n\t\t\t\t\tllmDefault in field.metadata.custom\n\t\t\t\t) {\n\t\t\t\t\tconst defaulter = field.metadata.custom[llmDefault];\n\t\t\t\t\tif (typeof defaulter === \"function\") {\n\t\t\t\t\t\tconst defaultValue: unknown = defaulter();\n\t\t\t\t\t\tif (defaultValue !== undefined) {\n\t\t\t\t\t\t\tinputWithDefaults[key] = defaultValue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tinputWithDefaults[key] = value[key];\n\t\t\t}\n\t\t}\n\t\treturn constructNode(schema, inputWithDefaults);\n\t}\n\treturn constructNode(schema, value);\n}\n\n/**\n * Applies the given function (as a string of JavaScript code or an actual function) to the given tree.\n */\nasync function applyTreeFunction<TSchema extends ImplicitFieldSchema>(\n\ttree: Subtree<TSchema>,\n\teditCode: string,\n\tvalidateEdit: Required<SemanticAgentOptions>[\"validateEdit\"],\n\texecuteEdit: Required<SemanticAgentOptions>[\"executeEdit\"],\n\tlogger: Logger | undefined,\n): Promise<EditResult> {\n\tlogger?.log(`### Editing Tool Invoked\\n\\n`);\n\tlogger?.log(`#### Generated Code\\n\\n\\`\\`\\`javascript\\n${editCode}\\n\\`\\`\\`\\n\\n`);\n\n\ttry {\n\t\tawait validateEdit(editCode);\n\t} catch (error: unknown) {\n\t\tlogger?.log(`#### Code Validation Failed\\n\\n`);\n\t\tlogger?.log(`\\`\\`\\`JSON\\n${toErrorString(error)}\\n\\`\\`\\`\\n\\n`);\n\t\treturn {\n\t\t\ttype: \"validationError\",\n\t\t\tmessage: `The generated code did not pass validation: ${toErrorString(error)}`,\n\t\t};\n\t}\n\n\t// Stick the tree schema constructors on an object passed to the function so that the LLM can create new nodes.\n\tconst create: Record<string, (input: FactoryContentObject) => TreeNode> = {};\n\tfor (const schema of findNamedSchemas(tree.schema)) {\n\t\tconst name = getFriendlyName(schema);\n\t\tcreate[name] = (input: FactoryContentObject) => constructTreeNode(schema, input);\n\t}\n\n\t// Fork a branch to edit. If the edit fails or produces an error, we discard this branch, otherwise we merge it.\n\tconst editTree = tree.fork();\n\tconst context = {\n\t\tget root(): ReadableField<TSchema> {\n\t\t\treturn editTree.field;\n\t\t},\n\t\tset root(value: TreeFieldFromImplicitField<ReadSchema<TSchema>>) {\n\t\t\teditTree.field = value;\n\t\t},\n\t\tcreate,\n\t};\n\n\ttry {\n\t\tawait executeEdit(context, editCode);\n\t} catch (error: unknown) {\n\t\tlogger?.log(`#### Error\\n\\n`);\n\t\tlogger?.log(`\\`\\`\\`JSON\\n${toErrorString(error)}\\n\\`\\`\\`\\n\\n`);\n\t\teditTree.branch.dispose();\n\t\treturn {\n\t\t\ttype: \"executionError\",\n\t\t\tmessage: `Running the generated code produced an error. The state of the tree will be reset to its previous state as it was before the code ran. Please try again. Here is the error: ${toErrorString(error)}`,\n\t\t};\n\t}\n\n\ttree.branch.merge(editTree.branch);\n\tlogger?.log(`#### New Tree State\\n\\n`);\n\tlogger?.log(`${`\\`\\`\\`JSON\\n${stringifyTree(tree.field)}\\n\\`\\`\\``}\\n\\n`);\n\treturn {\n\t\ttype: \"success\",\n\t\tmessage: `After running the code, the new state of the tree is:\\n\\n\\`\\`\\`JSON\\n${stringifyTree(tree.field)}\\n\\`\\`\\``,\n\t};\n}\n\nconst defaultValidateEdit: Required<SemanticAgentOptions>[\"validateEdit\"] = () => {};\n\nconst defaultExecuteEdit: Required<SemanticAgentOptions>[\"executeEdit\"] = async (\n\tcontext,\n\tcode,\n) => {\n\t// eslint-disable-next-line no-new-func, @typescript-eslint/no-implied-eval\n\tconst fn = new Function(\"context\", code);\n\tawait fn(context);\n};\n"]}
|
package/dist/alpha.d.ts
CHANGED
|
@@ -25,7 +25,6 @@ export {
|
|
|
25
25
|
FunctionDef,
|
|
26
26
|
IExposedMethods,
|
|
27
27
|
Infer,
|
|
28
|
-
LangchainChatModel,
|
|
29
28
|
Logger,
|
|
30
29
|
MethodKeys,
|
|
31
30
|
SemanticAgentOptions,
|
|
@@ -34,7 +33,6 @@ export {
|
|
|
34
33
|
SharedTreeSemanticAgent,
|
|
35
34
|
TreeView,
|
|
36
35
|
buildFunc,
|
|
37
|
-
createSemanticAgent,
|
|
38
36
|
exposeMethodsSymbol,
|
|
39
37
|
llmDefault
|
|
40
38
|
// #endregion
|
package/dist/api.d.ts
CHANGED
|
@@ -24,10 +24,22 @@ export interface SemanticAgentOptions {
|
|
|
24
24
|
*/
|
|
25
25
|
domainHints?: string;
|
|
26
26
|
/**
|
|
27
|
-
* Validates any generated JavaScript created by the {@link SharedTreeChatModel.editToolName | model's editing tool}
|
|
28
|
-
* @remarks
|
|
27
|
+
* Validates any generated JavaScript created by the {@link SharedTreeChatModel.editToolName | model's editing tool}.
|
|
28
|
+
* @remarks This happens before the code is executed - execution can be intercepted by using the {@link SemanticAgentOptions.executeEdit | executeEdit} callback.
|
|
29
|
+
* @param code - The generated JavaScript code as a string.
|
|
30
|
+
* @throws If the code is invalid, this function should throw an error with a human-readable message describing why it is invalid.
|
|
29
31
|
*/
|
|
30
|
-
|
|
32
|
+
validateEdit?: (code: string) => void | Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Evaluates/runs any generated JavaScript created by the {@link SharedTreeChatModel.editToolName | model's editing tool}.
|
|
35
|
+
* @remarks This happens only after the code has been successfully validated by the optional {@link SemanticAgentOptions.validateEdit | validateEdit} function.
|
|
36
|
+
* @param context - An object that must be provided to the generated code as a variable named "context" in its top-level scope.
|
|
37
|
+
* @param code - The generated JavaScript code as a string.
|
|
38
|
+
* @throws If an error is thrown while executing the code, it will be caught and the message will be forwarded to the model for debugging.
|
|
39
|
+
* @remarks If this function is not provided, the generated code will be executed using a simple `eval` call, which may not provide sufficient security guarantees for some environments.
|
|
40
|
+
* Use a library such as SES to provide a more secure implementation - see `@fluidframework/tree-agent-ses` for a drop-in implementation.
|
|
41
|
+
*/
|
|
42
|
+
executeEdit?: (context: Record<string, unknown>, code: string) => void | Promise<void>;
|
|
31
43
|
/**
|
|
32
44
|
* The maximum number of sequential edits the LLM can make before we assume it's stuck in a loop.
|
|
33
45
|
*/
|
|
@@ -42,15 +54,14 @@ export interface SemanticAgentOptions {
|
|
|
42
54
|
* @remarks
|
|
43
55
|
* - `success`: The edit was successfully applied.
|
|
44
56
|
* - `disabledError`: The model is not allowed to edit the tree (i.e. {@link SharedTreeChatModel.editToolName} was not provided).
|
|
45
|
-
* - `validationError`: The provided JavaScript did not pass the optional {@link SemanticAgentOptions.
|
|
46
|
-
* - `
|
|
47
|
-
* - `runtimeError`: An error was thrown while executing the provided JavaScript.
|
|
57
|
+
* - `validationError`: The provided JavaScript did not pass the optional {@link SemanticAgentOptions.validateEdit} function.
|
|
58
|
+
* - `executionError`: An error was thrown while parsing or executing the provided JavaScript.
|
|
48
59
|
* - `tooManyEditsError`: The {@link SharedTreeChatQuery.edit} function has been called more than the number of times specified by {@link SemanticAgentOptions.maximumSequentialEdits} for the same message.
|
|
49
60
|
* - `expiredError`: The {@link SharedTreeChatQuery.edit} function was called after the issuing query has already completed.
|
|
50
61
|
* @alpha
|
|
51
62
|
*/
|
|
52
63
|
export interface EditResult {
|
|
53
|
-
type: "success" | "disabledError" | "validationError" | "
|
|
64
|
+
type: "success" | "disabledError" | "validationError" | "executionError" | "tooManyEditsError" | "expiredError";
|
|
54
65
|
/**
|
|
55
66
|
* A human-readable message describing the result of the edit attempt.
|
|
56
67
|
* @remarks In the case of an error, this message is appropriate to include in a model's chat history.
|
|
@@ -80,6 +91,7 @@ export interface SharedTreeChatQuery {
|
|
|
80
91
|
/**
|
|
81
92
|
* A plugin interface that handles queries from a {@link SharedTreeSemanticAgent}.
|
|
82
93
|
* @remarks This wraps an underlying communication with an LLM and receives all necessary {@link SharedTreeChatModel.appendContext | context} from the {@link SharedTreeSemanticAgent | agent} for the LLM to properly analyze and edit the tree.
|
|
94
|
+
* See `@fluidframework/tree-agent-langchain` for a drop-in implementation based on the LangChain library.
|
|
83
95
|
* @alpha
|
|
84
96
|
*/
|
|
85
97
|
export interface SharedTreeChatModel {
|
package/dist/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAE1E,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEtF;;;GAGG;AACH,MAAM,WAAW,MAAM;IACtB;;OAEG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACpC;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvF;;OAEG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,UAAU;IAC1B,IAAI,EACD,SAAS,GACT,eAAe,GACf,iBAAiB,GACjB,gBAAgB,GAChB,mBAAmB,GACnB,cAAc,CAAC;IAElB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAQhE;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IACnC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACtC;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IACnC;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,aAAa,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC;;;OAGG;IACH,KAAK,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACrD;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,CAAC,OAAO,SAAS,mBAAmB,IAAI,CAAC,EAChE,IAAI,EACJ,MAAM,GACN,EAAE;IACF,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,QAAQ,CAAC,CAAC;CAClE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC"}
|
package/dist/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAgFH;;GAEG;AACH,SAAgB,YAAY,CAAC,KAAc;IAC1C,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACjD,OAAO,KAAK,CAAC;IACd,CAAC;IACD,OAAO,CACN,OAAQ,KAAoB,CAAC,IAAI,KAAK,QAAQ;QAC9C,OAAQ,KAAoB,CAAC,OAAO,KAAK,QAAQ,CACjD,CAAC;AACH,CAAC;AARD,oCAQC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { ImplicitFieldSchema, TreeNode } from \"@fluidframework/tree\";\n// This is used for doc links\nimport type { FactoryContentObject, ReadableField } from \"@fluidframework/tree/alpha\";\n\n/**\n * Logger interface for logging events from a {@link SharedTreeSemanticAgent}.\n * @alpha\n */\nexport interface Logger {\n\t/**\n\t * Log a message.\n\t */\n\tlog(message: string): void;\n}\n\n/**\n * Options used to parameterize the creation of a {@link SharedTreeSemanticAgent}.\n * @alpha\n */\nexport interface SemanticAgentOptions {\n\t/**\n\t * Additional information about the application domain that will be included in the context provided to the {@link SharedTreeChatModel | model}.\n\t */\n\tdomainHints?: string;\n\t/**\n\t * Validates any generated JavaScript created by the {@link SharedTreeChatModel.editToolName | model's editing tool}.\n\t * @remarks This happens before the code is executed - execution can be intercepted by using the {@link SemanticAgentOptions.executeEdit | executeEdit} callback.\n\t * @param code - The generated JavaScript code as a string.\n\t * @throws If the code is invalid, this function should throw an error with a human-readable message describing why it is invalid.\n\t */\n\tvalidateEdit?: (code: string) => void | Promise<void>;\n\t/**\n\t * Evaluates/runs any generated JavaScript created by the {@link SharedTreeChatModel.editToolName | model's editing tool}.\n\t * @remarks This happens only after the code has been successfully validated by the optional {@link SemanticAgentOptions.validateEdit | validateEdit} function.\n\t * @param context - An object that must be provided to the generated code as a variable named \"context\" in its top-level scope.\n\t * @param code - The generated JavaScript code as a string.\n\t * @throws If an error is thrown while executing the code, it will be caught and the message will be forwarded to the model for debugging.\n\t * @remarks If this function is not provided, the generated code will be executed using a simple `eval` call, which may not provide sufficient security guarantees for some environments.\n\t * Use a library such as SES to provide a more secure implementation - see `@fluidframework/tree-agent-ses` for a drop-in implementation.\n\t */\n\texecuteEdit?: (context: Record<string, unknown>, code: string) => void | Promise<void>;\n\t/**\n\t * The maximum number of sequential edits the LLM can make before we assume it's stuck in a loop.\n\t */\n\tmaximumSequentialEdits?: number;\n\t/**\n\t * If supplied, generates human-readable markdown text describing the actions taken by the {@link SharedTreeSemanticAgent | agent} as it performs queries.\n\t */\n\tlogger?: Logger;\n}\n\n/**\n * A result from an edit attempt via the {@link SharedTreeChatQuery.edit} function.\n * @remarks\n * - `success`: The edit was successfully applied.\n * - `disabledError`: The model is not allowed to edit the tree (i.e. {@link SharedTreeChatModel.editToolName} was not provided).\n * - `validationError`: The provided JavaScript did not pass the optional {@link SemanticAgentOptions.validateEdit} function.\n * - `executionError`: An error was thrown while parsing or executing the provided JavaScript.\n * - `tooManyEditsError`: The {@link SharedTreeChatQuery.edit} function has been called more than the number of times specified by {@link SemanticAgentOptions.maximumSequentialEdits} for the same message.\n * - `expiredError`: The {@link SharedTreeChatQuery.edit} function was called after the issuing query has already completed.\n * @alpha\n */\nexport interface EditResult {\n\ttype:\n\t\t| \"success\"\n\t\t| \"disabledError\"\n\t\t| \"validationError\"\n\t\t| \"executionError\"\n\t\t| \"tooManyEditsError\"\n\t\t| \"expiredError\";\n\n\t/**\n\t * A human-readable message describing the result of the edit attempt.\n\t * @remarks In the case of an error, this message is appropriate to include in a model's chat history.\n\t */\n\tmessage: string;\n}\n\n/**\n * Type guard for {@link EditResult}.\n */\nexport function isEditResult(value: unknown): value is EditResult {\n\tif (value === null || typeof value !== \"object\") {\n\t\treturn false;\n\t}\n\treturn (\n\t\ttypeof (value as EditResult).type === \"string\" &&\n\t\ttypeof (value as EditResult).message === \"string\"\n\t);\n}\n\n/**\n * A query from a user to a {@link SharedTreeSemanticAgent}.\n * @remarks Processing a query may involve editing the SharedTree via the provided {@link SharedTreeChatQuery.edit} function.\n * @alpha\n */\nexport interface SharedTreeChatQuery {\n\t/**\n\t * The user's query.\n\t */\n\ttext: string;\n\t/**\n\t * Edit the tree with the provided JavaScript function code.\n\t * @remarks Attempting an edit may fail for a variety of reasons which are captured in the {@link EditResult | returned object}.\n\t */\n\tedit(js: string): Promise<EditResult>;\n}\n\n/**\n * A plugin interface that handles queries from a {@link SharedTreeSemanticAgent}.\n * @remarks This wraps an underlying communication with an LLM and receives all necessary {@link SharedTreeChatModel.appendContext | context} from the {@link SharedTreeSemanticAgent | agent} for the LLM to properly analyze and edit the tree.\n * See `@fluidframework/tree-agent-langchain` for a drop-in implementation based on the LangChain library.\n * @alpha\n */\nexport interface SharedTreeChatModel {\n\t/**\n\t * A optional name of this chat model.\n\t * @remarks If supplied, this may be used in logging or debugging information.\n\t * @example \"gpt-5\"\n\t */\n\tname?: string;\n\t/**\n\t * The name of the tool that the model should use to edit the tree.\n\t * @remarks If supplied, this will be mentioned in the context provided to the model so that the underlying LLM will be encouraged to use it when a user query requires an edit.\n\t * The model should \"implement\" the tool by registering it with the underlying LLM API.\n\t * The tool should take an LLM-generated JavaScript function as input and supply it to the {@link SharedTreeChatQuery.edit | edit} function.\n\t * Instructions for generating the proper function signature and implementation will be provided by the {@link SharedTreeSemanticAgent | agent} via {@link SharedTreeChatModel.appendContext | context}.\n\t * If not supplied, the model will not be able to edit the tree (running the {@link SharedTreeChatQuery.edit | edit} function will fail).\n\t */\n\teditToolName?: string;\n\t/**\n\t * Add contextual information to the model that may be relevant to future queries.\n\t * @remarks In practice, this may be implemented by e.g. appending a \"system\" message to an LLM's chat/message history.\n\t * This context must be present in the context window of every {@link SharedTreeChatModel.query | query} for e.g. {@link SharedTreeChatModel.editToolName | editing} to work.\n\t * @param text - The message or context to append.\n\t */\n\tappendContext?(text: string): void;\n\t/**\n\t * Queries the chat model with a request from the user.\n\t * @remarks This model may simply return a text response to the query, or it may first call the {@link SharedTreeChatQuery.edit} function (potentially multiple times) to modify the tree in response to the query.\n\t */\n\tquery(message: SharedTreeChatQuery): Promise<string>;\n}\n\n/**\n * A function that edits a SharedTree.\n */\nexport type EditFunction<TSchema extends ImplicitFieldSchema> = ({\n\troot,\n\tcreate,\n}: {\n\troot: ReadableField<TSchema>;\n\tcreate: Record<string, (input: FactoryContentObject) => TreeNode>;\n}) => void | Promise<void>;\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,5 +11,4 @@ export { SharedTreeSemanticAgent } from "./agent.js";
|
|
|
11
11
|
export type { EditResult, SharedTreeChatModel, SharedTreeChatQuery, Logger, SemanticAgentOptions, } from "./api.js";
|
|
12
12
|
export { type TreeView, llmDefault } from "./utils.js";
|
|
13
13
|
export { buildFunc, exposeMethodsSymbol, type ArgsTuple, type ExposedMethods, type Arg, type FunctionDef, type MethodKeys, type BindableSchema, type Ctor, type Infer, type IExposedMethods, } from "./methodBinding.js";
|
|
14
|
-
export { LangchainChatModel, createSemanticAgent } from "./langchain.js";
|
|
15
14
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,YAAY,EACX,UAAU,EACV,mBAAmB,EACnB,mBAAmB,EACnB,MAAM,EACN,oBAAoB,GACpB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,KAAK,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EACN,SAAS,EACT,mBAAmB,EACnB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,GAAG,EACR,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,IAAI,EACT,KAAK,KAAK,EACV,KAAK,eAAe,GACpB,MAAM,oBAAoB,CAAC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,YAAY,EACX,UAAU,EACV,mBAAmB,EACnB,mBAAmB,EACnB,MAAM,EACN,oBAAoB,GACpB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,KAAK,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EACN,SAAS,EACT,mBAAmB,EACnB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,GAAG,EACR,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,IAAI,EACT,KAAK,KAAK,EACV,KAAK,eAAe,GACpB,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.
|
|
7
|
+
exports.exposeMethodsSymbol = exports.buildFunc = exports.llmDefault = exports.SharedTreeSemanticAgent = void 0;
|
|
8
8
|
/**
|
|
9
9
|
* A library for creating AI agents to interact with a {@link SharedTree | https://fluidframework.com/docs/data-structures/tree/}.
|
|
10
10
|
*
|
|
@@ -17,7 +17,4 @@ Object.defineProperty(exports, "llmDefault", { enumerable: true, get: function (
|
|
|
17
17
|
var methodBinding_js_1 = require("./methodBinding.js");
|
|
18
18
|
Object.defineProperty(exports, "buildFunc", { enumerable: true, get: function () { return methodBinding_js_1.buildFunc; } });
|
|
19
19
|
Object.defineProperty(exports, "exposeMethodsSymbol", { enumerable: true, get: function () { return methodBinding_js_1.exposeMethodsSymbol; } });
|
|
20
|
-
var langchain_js_1 = require("./langchain.js");
|
|
21
|
-
Object.defineProperty(exports, "LangchainChatModel", { enumerable: true, get: function () { return langchain_js_1.LangchainChatModel; } });
|
|
22
|
-
Object.defineProperty(exports, "createSemanticAgent", { enumerable: true, get: function () { return langchain_js_1.createSemanticAgent; } });
|
|
23
20
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;;;GAIG;AAEH,uCAAqD;AAA5C,mHAAA,uBAAuB,OAAA;AAQhC,uCAAuD;AAA/B,sGAAA,UAAU,OAAA;AAClC,uDAY4B;AAX3B,6GAAA,SAAS,OAAA;AACT,uHAAA,mBAAmB,OAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;;;GAIG;AAEH,uCAAqD;AAA5C,mHAAA,uBAAuB,OAAA;AAQhC,uCAAuD;AAA/B,sGAAA,UAAU,OAAA;AAClC,uDAY4B;AAX3B,6GAAA,SAAS,OAAA;AACT,uHAAA,mBAAmB,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * A library for creating AI agents to interact with a {@link SharedTree | https://fluidframework.com/docs/data-structures/tree/}.\n *\n * @packageDocumentation\n */\n\nexport { SharedTreeSemanticAgent } from \"./agent.js\";\nexport type {\n\tEditResult,\n\tSharedTreeChatModel,\n\tSharedTreeChatQuery,\n\tLogger,\n\tSemanticAgentOptions,\n} from \"./api.js\";\nexport { type TreeView, llmDefault } from \"./utils.js\";\nexport {\n\tbuildFunc,\n\texposeMethodsSymbol,\n\ttype ArgsTuple,\n\ttype ExposedMethods,\n\ttype Arg,\n\ttype FunctionDef,\n\ttype MethodKeys,\n\ttype BindableSchema,\n\ttype Ctor,\n\ttype Infer,\n\ttype IExposedMethods,\n} from \"./methodBinding.js\";\n"]}
|
package/dist/prompt.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAe,MAAM,sBAAsB,CAAC;AAC7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAIhE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAW5C;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,SAAS,mBAAmB,EAAE,IAAI,EAAE;IAClE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAe,MAAM,sBAAsB,CAAC;AAC7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAIhE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAW5C;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,SAAS,mBAAmB,EAAE,IAAI,EAAE;IAClE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,CA4IT;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,mBAAmB,CAAC,GAAG,MAAM,CA8C9E"}
|
package/dist/prompt.js
CHANGED
|
@@ -53,22 +53,20 @@ function getPrompt(args) {
|
|
|
53
53
|
const details = { hasHelperMethods: false };
|
|
54
54
|
const typescriptSchemaTypes = (0, utils_js_1.getZodSchemaAsTypeScript)(domainTypes, details);
|
|
55
55
|
const helperMethodExplanation = details.hasHelperMethods
|
|
56
|
-
? `Manipulating the data using the APIs described below is allowed, but when possible ALWAYS prefer to use
|
|
56
|
+
? `Manipulating the data using the APIs described below is allowed, but when possible ALWAYS prefer to use any application helper methods exposed on the schema TypeScript types if the goal can be accomplished that way.
|
|
57
57
|
It will often not be possible to fully accomplish the goal using those helpers. When this is the case, mutate the objects as normal, taking into account the following guidance.`
|
|
58
58
|
: "";
|
|
59
59
|
const builderExplanation = exampleObjectName === undefined
|
|
60
60
|
? ""
|
|
61
61
|
: `When constructing new objects, you should wrap them in the appropriate builder function rather than simply making a javascript object.
|
|
62
|
-
The builders are available on the
|
|
62
|
+
The builders are available on the \`create\` property on the context object and are named according to the type that they create.
|
|
63
63
|
For example:
|
|
64
64
|
|
|
65
65
|
\`\`\`javascript
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
// const ${(0, utils_js_1.communize)(exampleObjectName)} = { /* ...properties... */ };
|
|
71
|
-
}
|
|
66
|
+
// This creates a new ${exampleObjectName} object:
|
|
67
|
+
const ${(0, utils_js_1.communize)(exampleObjectName)} = context.create.${exampleObjectName}({ /* ...properties... */ });
|
|
68
|
+
// Don't do this:
|
|
69
|
+
// const ${(0, utils_js_1.communize)(exampleObjectName)} = { /* ...properties... */ };
|
|
72
70
|
\`\`\`\n\n`;
|
|
73
71
|
const arrayEditing = `#### Editing Arrays
|
|
74
72
|
|
|
@@ -99,20 +97,20 @@ ${getTreeMapNodeDocumentation(mapInterfaceName)}
|
|
|
99
97
|
|
|
100
98
|
`;
|
|
101
99
|
const rootTypes = (0, internal_1.normalizeFieldSchema)(schema).allowedTypeSet;
|
|
102
|
-
const editing = `If the user asks you to edit the tree, you should author a JavaScript
|
|
103
|
-
You must use the "${editToolName}" tool to
|
|
100
|
+
const editing = `If the user asks you to edit the tree, you should author a snippet of JavaScript code to accomplish the user-specified goal, following the instructions for editing detailed below.
|
|
101
|
+
You must use the "${editToolName}" tool to run the generated code.
|
|
104
102
|
After editing the tree, review the latest state of the tree to see if it satisfies the user's request.
|
|
105
103
|
If it does not, or if you receive an error, you may try again with a different approach.
|
|
106
104
|
Once the tree is in the desired state, you should inform the user that the request has been completed.
|
|
107
105
|
|
|
108
106
|
### Editing
|
|
109
107
|
|
|
110
|
-
If the user asks you to edit the document, you will write a JavaScript
|
|
111
|
-
The
|
|
112
|
-
The
|
|
113
|
-
This \`
|
|
114
|
-
You may mutate any part of the tree as necessary, taking into account the caveats around arrays and maps detailed below.
|
|
115
|
-
You may also set the \`root\` property to be an entirely new value as long as it is one of the types allowed at the root of the tree (\`${Array.from(rootTypes.values(), (t) => (0, utils_js_1.getFriendlyName)(t)).join(" | ")}\`).
|
|
108
|
+
If the user asks you to edit the document, you will write a snippet of JavaScript code that mutates the data in-place to achieve the user's goal.
|
|
109
|
+
The snippet may be synchronous or asynchronous (i.e. it may \`await\` functions if necessary).
|
|
110
|
+
The snippet has a \`context\` variable in its scope.
|
|
111
|
+
This \`context\` variable holds the current state of the tree in the \`root\` property.
|
|
112
|
+
You may mutate any part of the root tree as necessary, taking into account the caveats around${hasArrays ? ` arrays${hasMaps ? " and" : ""}` : ""}${hasMaps ? " maps" : ""} detailed below.
|
|
113
|
+
You may also set the \`root\` property of the context to be an entirely new value as long as it is one of the types allowed at the root of the tree (\`${Array.from(rootTypes.values(), (t) => (0, utils_js_1.getFriendlyName)(t)).join(" | ")}\`).
|
|
116
114
|
${helperMethodExplanation}
|
|
117
115
|
|
|
118
116
|
${hasArrays ? arrayEditing : ""}${hasMaps ? mapEditing : ""}#### Additional Notes
|
|
@@ -139,7 +137,7 @@ ${editToolName === undefined ? "" : editing}### Application data
|
|
|
139
137
|
${domainHints === undefined
|
|
140
138
|
? ""
|
|
141
139
|
: `\nThe application supplied the following additional instructions: ${domainHints}`}
|
|
142
|
-
The current state of
|
|
140
|
+
The current state of \`context.root\` (a \`${field === undefined ? "undefined" : (0, utils_js_1.getFriendlyName)(tree_1.Tree.schema(field))}\`) is:
|
|
143
141
|
|
|
144
142
|
\`\`\`JSON
|
|
145
143
|
${stringified}
|