@fluidframework/tree-agent 2.63.0-359461 → 2.63.0-359734

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/api-report/tree-agent.alpha.api.md +9 -2
  2. package/dist/agent.d.ts +0 -3
  3. package/dist/agent.d.ts.map +1 -1
  4. package/dist/agent.js +21 -49
  5. package/dist/agent.js.map +1 -1
  6. package/dist/alpha.d.ts +1 -0
  7. package/dist/api.d.ts +18 -7
  8. package/dist/api.d.ts.map +1 -1
  9. package/dist/api.js.map +1 -1
  10. package/dist/index.d.ts +1 -0
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +3 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/langchain.d.ts.map +1 -1
  15. package/dist/langchain.js +2 -3
  16. package/dist/langchain.js.map +1 -1
  17. package/dist/prompt.d.ts.map +1 -1
  18. package/dist/prompt.js +15 -17
  19. package/dist/prompt.js.map +1 -1
  20. package/dist/ses.d.ts +21 -0
  21. package/dist/ses.d.ts.map +1 -0
  22. package/dist/ses.js +64 -0
  23. package/dist/ses.js.map +1 -0
  24. package/dist/utils.d.ts +4 -0
  25. package/dist/utils.d.ts.map +1 -1
  26. package/dist/utils.js +16 -1
  27. package/dist/utils.js.map +1 -1
  28. package/lib/agent.d.ts +0 -3
  29. package/lib/agent.d.ts.map +1 -1
  30. package/lib/agent.js +22 -50
  31. package/lib/agent.js.map +1 -1
  32. package/lib/alpha.d.ts +1 -0
  33. package/lib/api.d.ts +18 -7
  34. package/lib/api.d.ts.map +1 -1
  35. package/lib/api.js.map +1 -1
  36. package/lib/index.d.ts +1 -0
  37. package/lib/index.d.ts.map +1 -1
  38. package/lib/index.js +1 -0
  39. package/lib/index.js.map +1 -1
  40. package/lib/langchain.d.ts.map +1 -1
  41. package/lib/langchain.js +2 -3
  42. package/lib/langchain.js.map +1 -1
  43. package/lib/prompt.d.ts.map +1 -1
  44. package/lib/prompt.js +15 -17
  45. package/lib/prompt.js.map +1 -1
  46. package/lib/ses.d.ts +21 -0
  47. package/lib/ses.d.ts.map +1 -0
  48. package/lib/ses.js +60 -0
  49. package/lib/ses.js.map +1 -0
  50. package/lib/utils.d.ts +4 -0
  51. package/lib/utils.d.ts.map +1 -1
  52. package/lib/utils.js +14 -0
  53. package/lib/utils.js.map +1 -1
  54. package/package.json +10 -10
  55. package/src/agent.ts +29 -61
  56. package/src/api.ts +19 -12
  57. package/src/index.ts +1 -0
  58. package/src/langchain.ts +2 -3
  59. package/src/prompt.ts +15 -17
  60. package/src/ses.ts +73 -0
  61. package/src/utils.ts +14 -0
  62. package/dist/functionParsing.d.ts +0 -13
  63. package/dist/functionParsing.d.ts.map +0 -1
  64. package/dist/functionParsing.js +0 -215
  65. package/dist/functionParsing.js.map +0 -1
  66. package/lib/functionParsing.d.ts +0 -13
  67. package/lib/functionParsing.d.ts.map +0 -1
  68. package/lib/functionParsing.js +0 -210
  69. package/lib/functionParsing.js.map +0 -1
  70. package/src/functionParsing.ts +0 -268
@@ -29,6 +29,12 @@ export function createSemanticAgent<TSchema extends ImplicitFieldSchema_2>(clien
29
29
  // @alpha @deprecated
30
30
  export function createSemanticAgent<TSchema extends ImplicitFieldSchema_2>(client: BaseChatModel, treeView: TreeView<TSchema> | (ReadableField<TSchema> & TreeNode_2), options?: Readonly<SemanticAgentOptions>): SharedTreeSemanticAgent<TSchema>;
31
31
 
32
+ // @alpha
33
+ export function createSesEditEvaluator(options?: {
34
+ compartmentOptions?: CompartmentOptions;
35
+ lockdownOptions?: LockdownOptions;
36
+ }): Promise<SemanticAgentOptions["executeEdit"]>;
37
+
32
38
  // @alpha
33
39
  export type Ctor<T = any> = new (...args: any[]) => T;
34
40
 
@@ -36,7 +42,7 @@ export type Ctor<T = any> = new (...args: any[]) => T;
36
42
  export interface EditResult {
37
43
  message: string;
38
44
  // (undocumented)
39
- type: "success" | "disabledError" | "validationError" | "compileError" | "runtimeError" | "tooManyEditsError" | "expiredError";
45
+ type: "success" | "disabledError" | "validationError" | "executionError" | "tooManyEditsError" | "expiredError";
40
46
  }
41
47
 
42
48
  // @alpha
@@ -101,9 +107,10 @@ export type MethodKeys<T> = {
101
107
  // @alpha
102
108
  export interface SemanticAgentOptions {
103
109
  domainHints?: string;
110
+ executeEdit?: (context: Record<string, unknown>, code: string) => void | Promise<void>;
104
111
  logger?: Logger;
105
112
  maximumSequentialEdits?: number;
106
- validator?: (js: string) => boolean;
113
+ validateEdit?: (code: string) => void | Promise<void>;
107
114
  }
108
115
 
109
116
  // @alpha
package/dist/agent.d.ts CHANGED
@@ -29,7 +29,4 @@ export declare class SharedTreeSemanticAgent<TSchema extends ImplicitFieldSchema
29
29
  */
30
30
  query(userPrompt: string): Promise<string>;
31
31
  }
32
- /**
33
- * Finds the name of the first invocable function in the given code.
34
- */
35
32
  //# sourceMappingURL=agent.d.ts.map
@@ -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,EACX,mBAAmB,EAGnB,oBAAoB,EAEpB,MAAM,UAAU,CAAC;AAIlB,OAAO,EAIN,KAAK,QAAQ,EAEb,MAAM,YAAY,CAAC;AAapB;;;;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;CAqEvD;AA8HD;;GAEG"}
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 (js) => {
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, js, this.options?.validator, this.options?.logger);
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, fn, validator, logger) {
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${fn}\n\`\`\`\n\n`);
162
- if (validator?.(fn.toString()) === false) {
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: "The generated code did not pass validation. Please try again.",
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 params = {
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 editFunction(params);
186
+ await executeEdit(context, editCode);
207
187
  }
208
188
  catch (error) {
209
189
  logger?.log(`#### Error\n\n`);
210
- const errorMessage = error instanceof Error ? error.message : JSON.stringify(error);
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: "runtimeError",
215
- message: `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}`,
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 function, the new state of the tree is:\n\n\`\`\`JSON\n${(0, prompt_js_1.stringifyTree)(tree.field)}\n\`\`\``,
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
- function processLlmCode(code) {
227
- const functionName = (0, functionParsing_js_1.findInvocableFunctionName)(code);
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(paramsName, executionCode);
234
- return fn;
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
@@ -35,6 +35,7 @@ export {
35
35
  TreeView,
36
36
  buildFunc,
37
37
  createSemanticAgent,
38
+ createSesEditEvaluator,
38
39
  exposeMethodsSymbol,
39
40
  llmDefault
40
41
  // #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} before running it.
28
- * @remarks If this returns false, then the edit will throw an error instead of attempting to execute the JavaScript.
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
- validator?: (js: string) => boolean;
32
+ validateEdit?: (code: string) => void | Promise<void>;
33
+ /**
34
+ * Evaluates (executes) 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 evaluating 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 {@link createSesEditEvaluator} for a drop-in option.
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.validator} function.
46
- * - `compileError`: The provided JavaScript could not be parsed or compiled.
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" | "compileError" | "runtimeError" | "tooManyEditsError" | "expiredError";
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.
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;AAC1E,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAMtF;;;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;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IACpC;;OAEG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,UAAU;IAC1B,IAAI,EACD,SAAS,GACT,eAAe,GACf,iBAAiB,GACjB,cAAc,GACd,cAAc,GACd,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;;;;GAIG;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"}
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;;;;GAIG;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;;;AAyEH;;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\";\nimport type { FactoryContentObject, ReadableField } from \"@fluidframework/tree/alpha\";\n\n// This is used for doc links\n// eslint-disable-next-line unused-imports/no-unused-imports\nimport type { SharedTreeSemanticAgent } from \"./agent.js\";\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} before running it.\n\t * @remarks If this returns false, then the edit will throw an error instead of attempting to execute the JavaScript.\n\t */\n\tvalidator?: (js: string) => boolean;\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.validator} function.\n * - `compileError`: The provided JavaScript could not be parsed or compiled.\n * - `runtimeError`: An error was thrown while 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| \"compileError\"\n\t\t| \"runtimeError\"\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 * @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"]}
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 (executes) 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 evaluating 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 {@link createSesEditEvaluator} for a drop-in option.\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 * @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
@@ -12,4 +12,5 @@ export type { EditResult, SharedTreeChatModel, SharedTreeChatQuery, Logger, Sema
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
14
  export { LangchainChatModel, createSemanticAgent } from "./langchain.js";
15
+ export { createSesEditEvaluator } from "./ses.js";
15
16
  //# sourceMappingURL=index.d.ts.map
@@ -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;AAC5B,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,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;AAC5B,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,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.createSemanticAgent = exports.LangchainChatModel = exports.exposeMethodsSymbol = exports.buildFunc = exports.llmDefault = exports.SharedTreeSemanticAgent = void 0;
7
+ exports.createSesEditEvaluator = exports.createSemanticAgent = exports.LangchainChatModel = 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
  *
@@ -20,4 +20,6 @@ Object.defineProperty(exports, "exposeMethodsSymbol", { enumerable: true, get: f
20
20
  var langchain_js_1 = require("./langchain.js");
21
21
  Object.defineProperty(exports, "LangchainChatModel", { enumerable: true, get: function () { return langchain_js_1.LangchainChatModel; } });
22
22
  Object.defineProperty(exports, "createSemanticAgent", { enumerable: true, get: function () { return langchain_js_1.createSemanticAgent; } });
23
+ var ses_js_1 = require("./ses.js");
24
+ Object.defineProperty(exports, "createSesEditEvaluator", { enumerable: true, get: function () { return ses_js_1.createSesEditEvaluator; } });
23
25
  //# 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;AAWpB,+CAAyE;AAAhE,kHAAA,kBAAkB,OAAA;AAAE,mHAAA,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\";\nexport { LangchainChatModel, createSemanticAgent } from \"./langchain.js\";\n"]}
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;AAWpB,+CAAyE;AAAhE,kHAAA,kBAAkB,OAAA;AAAE,mHAAA,mBAAmB,OAAA;AAChD,mCAAkD;AAAzC,gHAAA,sBAAsB,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\";\nexport { LangchainChatModel, createSemanticAgent } from \"./langchain.js\";\nexport { createSesEditEvaluator } from \"./ses.js\";\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"langchain.d.ts","sourceRoot":"","sources":["../src/langchain.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAE/F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAYjF,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAEN,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;GAIG;AACH,qBAAa,kBAAmB,YAAW,mBAAmB;IAE1C,OAAO,CAAC,QAAQ,CAAC,KAAK;IADzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkD;gBACvC,KAAK,EAAE,aAAa;IAExD,SAAgB,YAAY,6BAA6B;IAEzD,IAAW,IAAI,IAAI,MAAM,GAAG,SAAS,CAGpC;IAEM,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI3B,KAAK,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC;YAKjD,SAAS;CA4CvB;AAID;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,SAAS,mBAAmB,EACtE,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,EAC3B,OAAO,CAAC,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GACtC,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACpC;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,SAAS,mBAAmB,EACtE,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,QAAQ,EACvC,OAAO,CAAC,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GACtC,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACpC;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,SAAS,mBAAmB,EACtE,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,EACjE,OAAO,CAAC,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GACtC,uBAAuB,CAAC,OAAO,CAAC,CAAC"}
1
+ {"version":3,"file":"langchain.d.ts","sourceRoot":"","sources":["../src/langchain.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAE/F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAYjF,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAEN,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;GAIG;AACH,qBAAa,kBAAmB,YAAW,mBAAmB;IAE1C,OAAO,CAAC,QAAQ,CAAC,KAAK;IADzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkD;gBACvC,KAAK,EAAE,aAAa;IAExD,SAAgB,YAAY,6BAA6B;IAEzD,IAAW,IAAI,IAAI,MAAM,GAAG,SAAS,CAGpC;IAEM,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI3B,KAAK,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC;YAKjD,SAAS;CA2CvB;AAID;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,SAAS,mBAAmB,EACtE,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,EAC3B,OAAO,CAAC,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GACtC,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACpC;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,SAAS,mBAAmB,EACtE,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,QAAQ,EACvC,OAAO,CAAC,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GACtC,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACpC;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,SAAS,mBAAmB,EACtE,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,EACjE,OAAO,CAAC,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GACtC,uBAAuB,CAAC,OAAO,CAAC,CAAC"}
package/dist/langchain.js CHANGED
@@ -42,10 +42,9 @@ class LangchainChatModel {
42
42
  return edit(functionCode);
43
43
  }, {
44
44
  name: this.editToolName,
45
- description: `Invokes a JavaScript function to edit a user's tree`,
45
+ description: `Invokes a JavaScript code snippet to edit a tree of application data.`,
46
46
  schema: zod_1.default.object({
47
- functionCode: zod_1.default.string().describe(`The code of the JavaScript function.
48
- For example: "function editTree({ root, create }) { /* your code here */ }"`),
47
+ functionCode: zod_1.default.string().describe(`The JavaScript snippet code.`),
49
48
  }),
50
49
  });
51
50
  const runnable = this.model.bindTools?.([editingTool], { tool_choice: "auto" });
@@ -1 +1 @@
1
- {"version":3,"file":"langchain.js","sourceRoot":"","sources":["../src/langchain.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 { UsageError } from \"@fluidframework/telemetry-utils/internal\";\nimport type { ImplicitFieldSchema, ReadableField, TreeNode } from \"@fluidframework/tree/alpha\";\n// eslint-disable-next-line import/no-internal-modules\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\n// eslint-disable-next-line import/no-internal-modules\nimport type { AIMessage, ToolMessage } from \"@langchain/core/messages\";\nimport {\n\tHumanMessage,\n\tSystemMessage,\n\t// eslint-disable-next-line import/no-internal-modules\n} from \"@langchain/core/messages\";\n// eslint-disable-next-line import/no-internal-modules\nimport { tool } from \"@langchain/core/tools\";\nimport z from \"zod\";\n\nimport { SharedTreeSemanticAgent } from \"./agent.js\";\nimport {\n\tisEditResult,\n\ttype SemanticAgentOptions,\n\ttype SharedTreeChatModel,\n\ttype SharedTreeChatQuery,\n} from \"./api.js\";\nimport type { TreeView } from \"./utils.js\";\n\n/**\n * An implementation of {@link SharedTreeChatModel} that wraps a Langchain chat model.\n * @remarks This class is responsible for managing the conversation history and interacting with the Langchain model (e.g. via Tool use for editing).\n * @alpha\n */\nexport class LangchainChatModel implements SharedTreeChatModel {\n\tprivate readonly messages: (HumanMessage | AIMessage | ToolMessage)[] = [];\n\tpublic constructor(private readonly model: BaseChatModel) {}\n\n\tpublic readonly editToolName = \"GenerateTreeEditingCode\";\n\n\tpublic get name(): string | undefined {\n\t\tconst name = this.model.metadata?.modelName;\n\t\treturn typeof name === \"string\" ? name : undefined;\n\t}\n\n\tpublic appendContext(text: string): void {\n\t\tthis.messages.push(new SystemMessage(text));\n\t}\n\n\tpublic async query(query: SharedTreeChatQuery): Promise<string> {\n\t\tthis.messages.push(new HumanMessage(query.text));\n\t\treturn this.queryEdit(async (js) => query.edit(js));\n\t}\n\n\tprivate async queryEdit(edit: SharedTreeChatQuery[\"edit\"]): Promise<string> {\n\t\tconst editingTool = tool(\n\t\t\tasync ({ functionCode }) => {\n\t\t\t\treturn edit(functionCode);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: this.editToolName,\n\t\t\t\tdescription: `Invokes a JavaScript function to edit a user's tree`,\n\t\t\t\tschema: z.object({\n\t\t\t\t\tfunctionCode: z.string().describe(`The code of the JavaScript function.\nFor example: \"function editTree({ root, create }) { /* your code here */ }\"`),\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\t\tconst runnable = this.model.bindTools?.([editingTool], { tool_choice: \"auto\" });\n\t\tif (runnable === undefined) {\n\t\t\tthrow new UsageError(\"LLM client must support function calling or tool use.\");\n\t\t}\n\n\t\tconst responseMessage = await runnable.invoke(this.messages);\n\t\tthis.messages.push(responseMessage);\n\n\t\tif (responseMessage.tool_calls !== undefined && responseMessage.tool_calls.length > 0) {\n\t\t\tfor (const toolCall of responseMessage.tool_calls) {\n\t\t\t\tswitch (toolCall.name) {\n\t\t\t\t\tcase editingTool.name: {\n\t\t\t\t\t\tconst toolResult = await editingTool.invoke(toolCall);\n\t\t\t\t\t\tthis.messages.push(toolResult);\n\t\t\t\t\t\tconst editResult: unknown = JSON.parse(toolResult.text);\n\t\t\t\t\t\tif (isEditResult(editResult) && editResult.type === \"tooManyEditsError\") {\n\t\t\t\t\t\t\treturn editResult.message;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// This call will either terminate the edit chain (if the LLM decides not to edit further) or continue it if more edits are required.\n\t\t\t\t\t\treturn this.queryEdit(edit);\n\t\t\t\t\t}\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tthis.messages.push(new HumanMessage(`Unrecognized tool call: ${toolCall.name}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn responseMessage.text;\n\t}\n}\n\n// #region Legacy APIs\n\n/**\n * Create a {@link SharedTreeSemanticAgent} using a Langchain chat model.\n * @alpha\n * @deprecated Use {@link SharedTreeSemanticAgent} with a {@link LangchainChatModel} instead.\n */\nexport function createSemanticAgent<TSchema extends ImplicitFieldSchema>(\n\tclient: BaseChatModel,\n\ttreeView: TreeView<TSchema>,\n\toptions?: Readonly<SemanticAgentOptions>,\n): SharedTreeSemanticAgent<TSchema>;\n/**\n * Create a {@link SharedTreeSemanticAgent} using a Langchain chat model.\n * @alpha\n * @deprecated Use {@link SharedTreeSemanticAgent} with a {@link LangchainChatModel} instead.\n */\nexport function createSemanticAgent<TSchema extends ImplicitFieldSchema>(\n\tclient: BaseChatModel,\n\tnode: ReadableField<TSchema> & TreeNode,\n\toptions?: Readonly<SemanticAgentOptions>,\n): SharedTreeSemanticAgent<TSchema>;\n/**\n * Create a {@link SharedTreeSemanticAgent} using a Langchain chat model.\n * @alpha\n * @deprecated Use {@link SharedTreeSemanticAgent} with a {@link LangchainChatModel} instead.\n */\nexport function createSemanticAgent<TSchema extends ImplicitFieldSchema>(\n\tclient: BaseChatModel,\n\ttreeView: TreeView<TSchema> | (ReadableField<TSchema> & TreeNode),\n\toptions?: Readonly<SemanticAgentOptions>,\n): SharedTreeSemanticAgent<TSchema>;\n/**\n * Create a {@link SharedTreeSemanticAgent} using a Langchain chat model.\n * @alpha\n * @deprecated Use {@link SharedTreeSemanticAgent} with a {@link LangchainChatModel} instead.\n */\nexport function createSemanticAgent<TSchema extends ImplicitFieldSchema>(\n\tclient: BaseChatModel,\n\ttreeView: TreeView<TSchema> | (ReadableField<TSchema> & TreeNode),\n\toptions?: Readonly<SemanticAgentOptions>,\n): SharedTreeSemanticAgent<TSchema> {\n\treturn new SharedTreeSemanticAgent(new LangchainChatModel(client), treeView, options);\n}\n\n// #endregion Legacy APIs\n"]}
1
+ {"version":3,"file":"langchain.js","sourceRoot":"","sources":["../src/langchain.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 { UsageError } from \"@fluidframework/telemetry-utils/internal\";\nimport type { ImplicitFieldSchema, ReadableField, TreeNode } from \"@fluidframework/tree/alpha\";\n// eslint-disable-next-line import/no-internal-modules\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\n// eslint-disable-next-line import/no-internal-modules\nimport type { AIMessage, ToolMessage } from \"@langchain/core/messages\";\nimport {\n\tHumanMessage,\n\tSystemMessage,\n\t// eslint-disable-next-line import/no-internal-modules\n} from \"@langchain/core/messages\";\n// eslint-disable-next-line import/no-internal-modules\nimport { tool } from \"@langchain/core/tools\";\nimport z from \"zod\";\n\nimport { SharedTreeSemanticAgent } from \"./agent.js\";\nimport {\n\tisEditResult,\n\ttype SemanticAgentOptions,\n\ttype SharedTreeChatModel,\n\ttype SharedTreeChatQuery,\n} from \"./api.js\";\nimport type { TreeView } from \"./utils.js\";\n\n/**\n * An implementation of {@link SharedTreeChatModel} that wraps a Langchain chat model.\n * @remarks This class is responsible for managing the conversation history and interacting with the Langchain model (e.g. via Tool use for editing).\n * @alpha\n */\nexport class LangchainChatModel implements SharedTreeChatModel {\n\tprivate readonly messages: (HumanMessage | AIMessage | ToolMessage)[] = [];\n\tpublic constructor(private readonly model: BaseChatModel) {}\n\n\tpublic readonly editToolName = \"GenerateTreeEditingCode\";\n\n\tpublic get name(): string | undefined {\n\t\tconst name = this.model.metadata?.modelName;\n\t\treturn typeof name === \"string\" ? name : undefined;\n\t}\n\n\tpublic appendContext(text: string): void {\n\t\tthis.messages.push(new SystemMessage(text));\n\t}\n\n\tpublic async query(query: SharedTreeChatQuery): Promise<string> {\n\t\tthis.messages.push(new HumanMessage(query.text));\n\t\treturn this.queryEdit(async (js) => query.edit(js));\n\t}\n\n\tprivate async queryEdit(edit: SharedTreeChatQuery[\"edit\"]): Promise<string> {\n\t\tconst editingTool = tool(\n\t\t\tasync ({ functionCode }) => {\n\t\t\t\treturn edit(functionCode);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: this.editToolName,\n\t\t\t\tdescription: `Invokes a JavaScript code snippet to edit a tree of application data.`,\n\t\t\t\tschema: z.object({\n\t\t\t\t\tfunctionCode: z.string().describe(`The JavaScript snippet code.`),\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\t\tconst runnable = this.model.bindTools?.([editingTool], { tool_choice: \"auto\" });\n\t\tif (runnable === undefined) {\n\t\t\tthrow new UsageError(\"LLM client must support function calling or tool use.\");\n\t\t}\n\n\t\tconst responseMessage = await runnable.invoke(this.messages);\n\t\tthis.messages.push(responseMessage);\n\n\t\tif (responseMessage.tool_calls !== undefined && responseMessage.tool_calls.length > 0) {\n\t\t\tfor (const toolCall of responseMessage.tool_calls) {\n\t\t\t\tswitch (toolCall.name) {\n\t\t\t\t\tcase editingTool.name: {\n\t\t\t\t\t\tconst toolResult = await editingTool.invoke(toolCall);\n\t\t\t\t\t\tthis.messages.push(toolResult);\n\t\t\t\t\t\tconst editResult: unknown = JSON.parse(toolResult.text);\n\t\t\t\t\t\tif (isEditResult(editResult) && editResult.type === \"tooManyEditsError\") {\n\t\t\t\t\t\t\treturn editResult.message;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// This call will either terminate the edit chain (if the LLM decides not to edit further) or continue it if more edits are required.\n\t\t\t\t\t\treturn this.queryEdit(edit);\n\t\t\t\t\t}\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tthis.messages.push(new HumanMessage(`Unrecognized tool call: ${toolCall.name}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn responseMessage.text;\n\t}\n}\n\n// #region Legacy APIs\n\n/**\n * Create a {@link SharedTreeSemanticAgent} using a Langchain chat model.\n * @alpha\n * @deprecated Use {@link SharedTreeSemanticAgent} with a {@link LangchainChatModel} instead.\n */\nexport function createSemanticAgent<TSchema extends ImplicitFieldSchema>(\n\tclient: BaseChatModel,\n\ttreeView: TreeView<TSchema>,\n\toptions?: Readonly<SemanticAgentOptions>,\n): SharedTreeSemanticAgent<TSchema>;\n/**\n * Create a {@link SharedTreeSemanticAgent} using a Langchain chat model.\n * @alpha\n * @deprecated Use {@link SharedTreeSemanticAgent} with a {@link LangchainChatModel} instead.\n */\nexport function createSemanticAgent<TSchema extends ImplicitFieldSchema>(\n\tclient: BaseChatModel,\n\tnode: ReadableField<TSchema> & TreeNode,\n\toptions?: Readonly<SemanticAgentOptions>,\n): SharedTreeSemanticAgent<TSchema>;\n/**\n * Create a {@link SharedTreeSemanticAgent} using a Langchain chat model.\n * @alpha\n * @deprecated Use {@link SharedTreeSemanticAgent} with a {@link LangchainChatModel} instead.\n */\nexport function createSemanticAgent<TSchema extends ImplicitFieldSchema>(\n\tclient: BaseChatModel,\n\ttreeView: TreeView<TSchema> | (ReadableField<TSchema> & TreeNode),\n\toptions?: Readonly<SemanticAgentOptions>,\n): SharedTreeSemanticAgent<TSchema>;\n/**\n * Create a {@link SharedTreeSemanticAgent} using a Langchain chat model.\n * @alpha\n * @deprecated Use {@link SharedTreeSemanticAgent} with a {@link LangchainChatModel} instead.\n */\nexport function createSemanticAgent<TSchema extends ImplicitFieldSchema>(\n\tclient: BaseChatModel,\n\ttreeView: TreeView<TSchema> | (ReadableField<TSchema> & TreeNode),\n\toptions?: Readonly<SemanticAgentOptions>,\n): SharedTreeSemanticAgent<TSchema> {\n\treturn new SharedTreeSemanticAgent(new LangchainChatModel(client), treeView, options);\n}\n\n// #endregion Legacy APIs\n"]}
@@ -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,CA8IT;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,mBAAmB,CAAC,GAAG,MAAM,CA8C9E"}
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 the application helper methods exposed on the schema TypeScript types if the goal can be accomplished that way.
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 "create" property on the first argument of the edit function and are named according to the type that they create.
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
- function editTree({ root, create }) {
67
- // This creates a new ${exampleObjectName} object:
68
- const ${(0, utils_js_1.communize)(exampleObjectName)} = create.${exampleObjectName}({ /* ...properties... */ });
69
- // Don't do this:
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 function to accomplish the user-specified goal, following the instructions for editing detailed below.
103
- You must use the "${editToolName}" tool to perform the edit.
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 function that mutates the data in-place to achieve the user's goal.
111
- The edit function may be synchronous or asynchronous.
112
- The edit function must have a first parameter which has a \`root\` property.
113
- This \`root\` property holds the current state of the tree as shown above.
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 the application tree (a \`${field === undefined ? "undefined" : (0, utils_js_1.getFriendlyName)(tree_1.Tree.schema(field))}\`) is:
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}