@fluidframework/tree-agent 2.72.0 → 2.73.0

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 (73) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/api-report/tree-agent.alpha.api.md +88 -17
  3. package/dist/agent.d.ts +5 -31
  4. package/dist/agent.d.ts.map +1 -1
  5. package/dist/agent.js +19 -38
  6. package/dist/agent.js.map +1 -1
  7. package/dist/alpha.d.ts +12 -3
  8. package/dist/api.d.ts +38 -20
  9. package/dist/api.d.ts.map +1 -1
  10. package/dist/api.js.map +1 -1
  11. package/dist/index.d.ts +4 -3
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +2 -4
  14. package/dist/index.js.map +1 -1
  15. package/dist/prompt.d.ts +2 -2
  16. package/dist/prompt.d.ts.map +1 -1
  17. package/dist/prompt.js +4 -4
  18. package/dist/prompt.js.map +1 -1
  19. package/dist/propertyBinding.d.ts +106 -0
  20. package/dist/propertyBinding.d.ts.map +1 -0
  21. package/dist/propertyBinding.js +64 -0
  22. package/dist/propertyBinding.js.map +1 -0
  23. package/dist/subtree.d.ts +8 -9
  24. package/dist/subtree.d.ts.map +1 -1
  25. package/dist/subtree.js +21 -21
  26. package/dist/subtree.js.map +1 -1
  27. package/dist/typeGeneration.d.ts.map +1 -1
  28. package/dist/typeGeneration.js +78 -21
  29. package/dist/typeGeneration.js.map +1 -1
  30. package/dist/utils.d.ts +1 -7
  31. package/dist/utils.d.ts.map +1 -1
  32. package/dist/utils.js +17 -3
  33. package/dist/utils.js.map +1 -1
  34. package/lib/agent.d.ts +5 -31
  35. package/lib/agent.d.ts.map +1 -1
  36. package/lib/agent.js +17 -35
  37. package/lib/agent.js.map +1 -1
  38. package/lib/alpha.d.ts +12 -3
  39. package/lib/api.d.ts +38 -20
  40. package/lib/api.d.ts.map +1 -1
  41. package/lib/api.js.map +1 -1
  42. package/lib/index.d.ts +4 -3
  43. package/lib/index.d.ts.map +1 -1
  44. package/lib/index.js +1 -1
  45. package/lib/index.js.map +1 -1
  46. package/lib/prompt.d.ts +2 -2
  47. package/lib/prompt.d.ts.map +1 -1
  48. package/lib/prompt.js +4 -4
  49. package/lib/prompt.js.map +1 -1
  50. package/lib/propertyBinding.d.ts +106 -0
  51. package/lib/propertyBinding.d.ts.map +1 -0
  52. package/lib/propertyBinding.js +59 -0
  53. package/lib/propertyBinding.js.map +1 -0
  54. package/lib/subtree.d.ts +8 -9
  55. package/lib/subtree.d.ts.map +1 -1
  56. package/lib/subtree.js +21 -21
  57. package/lib/subtree.js.map +1 -1
  58. package/lib/typeGeneration.d.ts.map +1 -1
  59. package/lib/typeGeneration.js +78 -21
  60. package/lib/typeGeneration.js.map +1 -1
  61. package/lib/utils.d.ts +1 -7
  62. package/lib/utils.d.ts.map +1 -1
  63. package/lib/utils.js +17 -3
  64. package/lib/utils.js.map +1 -1
  65. package/package.json +10 -10
  66. package/src/agent.ts +27 -69
  67. package/src/api.ts +56 -29
  68. package/src/index.ts +16 -4
  69. package/src/prompt.ts +6 -6
  70. package/src/propertyBinding.ts +181 -0
  71. package/src/subtree.ts +26 -29
  72. package/src/typeGeneration.ts +90 -24
  73. package/src/utils.ts +21 -15
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # @fluidframework/tree-agent
2
2
 
3
+ ## 2.73.0
4
+
5
+ Dependency updates only.
6
+
3
7
  ## 2.72.0
4
8
 
5
9
  Dependency updates only.
@@ -11,20 +11,11 @@ export type Arg<T extends z.ZodTypeAny = z.ZodTypeAny> = readonly [name: string,
11
11
  export type ArgsTuple<T extends readonly Arg[]> = T extends readonly [infer Single extends Arg] ? [Single[1]] : T extends readonly [infer Head extends Arg, ...infer Tail extends readonly Arg[]] ? [Head[1], ...ArgsTuple<Tail>] : never;
12
12
 
13
13
  // @alpha
14
- export type AsynchronousEditor = (context: Record<string, unknown>, code: string) => Promise<void>;
14
+ export type AsynchronousEditor<TSchema extends ImplicitFieldSchema> = (tree: ViewOrTree<TSchema>, code: string) => Promise<void>;
15
15
 
16
16
  // @alpha
17
17
  export type BindableSchema = TreeNodeSchema<string, NodeKind.Object> | TreeNodeSchema<string, NodeKind.Record> | TreeNodeSchema<string, NodeKind.Array> | TreeNodeSchema<string, NodeKind.Map>;
18
18
 
19
- // @alpha
20
- export const bindEditor: typeof bindEditorImpl;
21
-
22
- // @alpha
23
- export function bindEditorImpl<TSchema extends ImplicitFieldSchema>(tree: TreeView<TSchema> | (ReadableField<TSchema> & TreeNode), editor: AsynchronousEditor): (code: string) => Promise<void>;
24
-
25
- // @alpha
26
- export function bindEditorImpl<TSchema extends ImplicitFieldSchema>(tree: TreeView<TSchema> | (ReadableField<TSchema> & TreeNode), editor: SynchronousEditor): (code: string) => void;
27
-
28
19
  // @alpha
29
20
  export function buildFunc<const Return extends z.ZodTypeAny, const Args extends readonly Arg[], const Rest extends z.ZodTypeAny | null = null>(def: {
30
21
  description?: string;
@@ -33,10 +24,21 @@ export function buildFunc<const Return extends z.ZodTypeAny, const Args extends
33
24
  }, ...args: Args): FunctionDef<Args, Return, Rest>;
34
25
 
35
26
  // @alpha
36
- export type Ctor<T = any> = new (...args: any[]) => T;
27
+ export interface Context<TSchema extends ImplicitFieldSchema> {
28
+ create: Record<string, (input: FactoryContentObject) => TreeNode>;
29
+ is: Record<string, <T extends TreeNode>(input: T) => input is T>;
30
+ isArray(value: unknown): boolean;
31
+ isMap(value: unknown): boolean;
32
+ key(child: TreeNode): string | number;
33
+ parent(child: TreeNode): TreeNode | undefined;
34
+ root: ReadableField<TSchema>;
35
+ }
37
36
 
38
37
  // @alpha
39
- export const defaultEditor: AsynchronousEditor;
38
+ export function createContext<TSchema extends ImplicitFieldSchema>(tree: ViewOrTree<TSchema>): Context<TSchema>;
39
+
40
+ // @alpha
41
+ export type Ctor<T = any> = new (...args: any[]) => T;
40
42
 
41
43
  // @alpha
42
44
  export interface EditResult {
@@ -44,6 +46,11 @@ export interface EditResult {
44
46
  type: "success" | "disabledError" | "editingError" | "tooManyEditsError" | "expiredError";
45
47
  }
46
48
 
49
+ // @alpha
50
+ export type ExposableKeys<T> = {
51
+ [K in keyof T]?: T[K] extends (...args: any[]) => any ? never : K;
52
+ }[keyof T];
53
+
47
54
  // @alpha
48
55
  export interface ExposedMethods {
49
56
  // (undocumented)
@@ -53,9 +60,23 @@ export interface ExposedMethods {
53
60
  instanceOf<T extends TreeNodeSchemaClass>(schema: T): z.ZodType<InstanceType<T>, z.ZodTypeDef, InstanceType<T>>;
54
61
  }
55
62
 
63
+ // @alpha
64
+ export interface ExposedProperties {
65
+ // (undocumented)
66
+ exposeProperty<S extends BindableSchema & Ctor, K extends string & ExposableKeys<InstanceType<S>>, TZ extends ZodTypeAny>(schema: S, name: K, def: {
67
+ schema: TZ;
68
+ description?: string;
69
+ } & ReadOnlyRequirement<InstanceType<S>, K> & TypeMatchOrError<InstanceType<S>[K], infer<TZ>>): void;
70
+ // (undocumented)
71
+ instanceOf<T extends TreeNodeSchemaClass>(schema: T): ZodType<InstanceType<T>, ZodTypeDef, InstanceType<T>>;
72
+ }
73
+
56
74
  // @alpha
57
75
  export const exposeMethodsSymbol: unique symbol;
58
76
 
77
+ // @alpha
78
+ export const exposePropertiesSymbol: unique symbol;
79
+
59
80
  // @alpha
60
81
  export interface FunctionDef<Args extends readonly Arg[], Return extends z.ZodTypeAny, Rest extends z.ZodTypeAny | null = null> {
61
82
  // (undocumented)
@@ -74,6 +95,15 @@ export interface IExposedMethods {
74
95
  [exposeMethodsSymbol](methods: ExposedMethods): void;
75
96
  }
76
97
 
98
+ // @alpha
99
+ export interface IExposedProperties {
100
+ // (undocumented)
101
+ [exposePropertiesSymbol]?(properties: ExposedProperties): void;
102
+ }
103
+
104
+ // @alpha
105
+ export type IfEquals<X, Y, A = true, B = false> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? A : B;
106
+
77
107
  // @alpha
78
108
  export type Infer<T> = T extends FunctionDef<infer Args, infer Return, infer Rest> ? z.infer<z.ZodFunction<z.ZodTuple<ArgsTuple<Args>, Rest>, Return>> : never;
79
109
 
@@ -91,9 +121,40 @@ export type MethodKeys<T> = {
91
121
  };
92
122
 
93
123
  // @alpha
94
- export interface SemanticAgentOptions {
124
+ export class PropertyDef {
125
+ constructor(name: string, description: string | undefined, schema: ZodTypeAny, readOnly: boolean);
126
+ // (undocumented)
127
+ readonly description: string | undefined;
128
+ // (undocumented)
129
+ readonly name: string;
130
+ // (undocumented)
131
+ readonly readOnly: boolean;
132
+ // (undocumented)
133
+ readonly schema: ZodTypeAny;
134
+ }
135
+
136
+ // @alpha
137
+ export type ReadonlyKeys<T> = {
138
+ [P in keyof T]-?: IfEquals<{
139
+ [Q in P]: T[P];
140
+ }, {
141
+ -readonly [Q in P]: T[P];
142
+ }, never, P>;
143
+ }[keyof T];
144
+
145
+ // @alpha
146
+ export type ReadOnlyRequirement<TObj, K extends keyof TObj> = {
147
+ [P in K]-?: P extends ReadonlyKeys<TObj> ? {
148
+ readOnly: true;
149
+ } : {
150
+ readOnly?: false;
151
+ };
152
+ }[K];
153
+
154
+ // @alpha
155
+ export interface SemanticAgentOptions<TSchema extends ImplicitFieldSchema> {
95
156
  domainHints?: string;
96
- editor?: SynchronousEditor | AsynchronousEditor;
157
+ editor?: SynchronousEditor<TSchema> | AsynchronousEditor<TSchema>;
97
158
  logger?: Logger;
98
159
  maximumSequentialEdits?: number;
99
160
  }
@@ -114,14 +175,24 @@ export interface SharedTreeChatQuery {
114
175
 
115
176
  // @alpha @sealed
116
177
  export class SharedTreeSemanticAgent<TSchema extends ImplicitFieldSchema> {
117
- constructor(client: SharedTreeChatModel, tree: TreeView<TSchema> | (ReadableField<TSchema> & TreeNode), options?: Readonly<SemanticAgentOptions> | undefined);
178
+ constructor(client: SharedTreeChatModel, tree: ViewOrTree<TSchema>, options?: Readonly<SemanticAgentOptions<TSchema>> | undefined);
118
179
  query(userPrompt: string): Promise<string>;
119
180
  }
120
181
 
121
182
  // @alpha
122
- export type SynchronousEditor = (context: Record<string, unknown>, code: string) => void;
183
+ export type SynchronousEditor<TSchema extends ImplicitFieldSchema> = (tree: ViewOrTree<TSchema>, code: string) => void;
184
+
185
+ // @alpha
186
+ export type TreeView<TRoot extends ImplicitFieldSchema> = Pick<TreeViewAlpha<TRoot>, "root" | "fork" | "merge" | "rebaseOnto" | "schema" | "events"> & TreeBranchAlpha;
187
+
188
+ // @alpha
189
+ export type TypeMatchOrError<Expected, Received> = [Received] extends [Expected] ? unknown : {
190
+ __error__: "Zod schema value type does not match the property's declared type";
191
+ expected: Expected;
192
+ received: Received;
193
+ };
123
194
 
124
195
  // @alpha
125
- export type TreeView<TRoot extends ImplicitFieldSchema | UnsafeUnknownSchema> = Pick<TreeViewAlpha<TRoot>, "root" | "fork" | "merge" | "rebaseOnto" | "schema" | "events"> & TreeBranchAlpha;
196
+ export type ViewOrTree<TSchema extends ImplicitFieldSchema> = TreeView<TSchema> | (ReadableField<TSchema> & TreeNode);
126
197
 
127
198
  ```
package/dist/agent.d.ts CHANGED
@@ -3,10 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import type { ImplicitFieldSchema } from "@fluidframework/tree";
6
- import { TreeNode } from "@fluidframework/tree";
7
- import type { ReadableField } from "@fluidframework/tree/alpha";
8
- import type { SharedTreeChatModel, SemanticAgentOptions, SynchronousEditor, AsynchronousEditor } from "./api.js";
9
- import { type TreeView } from "./utils.js";
6
+ import type { SharedTreeChatModel, SemanticAgentOptions, Context, ViewOrTree } from "./api.js";
10
7
  /**
11
8
  * An agent that uses a {@link SharedTreeChatModel} to interact with a SharedTree.
12
9
  * @remarks This class forwards user queries to the chat model, and handles the application of any edits to the tree that the model requests.
@@ -16,11 +13,12 @@ export declare class SharedTreeSemanticAgent<TSchema extends ImplicitFieldSchema
16
13
  private readonly client;
17
14
  private readonly options?;
18
15
  private readonly outerTree;
16
+ private readonly editor;
19
17
  /**
20
18
  * Whether or not the outer tree has changed since the last query finished.
21
19
  */
22
20
  private outerTreeIsDirty;
23
- constructor(client: SharedTreeChatModel, tree: TreeView<TSchema> | (ReadableField<TSchema> & TreeNode), options?: Readonly<SemanticAgentOptions> | undefined);
21
+ constructor(client: SharedTreeChatModel, tree: ViewOrTree<TSchema>, options?: Readonly<SemanticAgentOptions<TSchema>> | undefined);
24
22
  /**
25
23
  * Given a user prompt, return a response.
26
24
  *
@@ -30,32 +28,8 @@ export declare class SharedTreeSemanticAgent<TSchema extends ImplicitFieldSchema
30
28
  query(userPrompt: string): Promise<string>;
31
29
  }
32
30
  /**
33
- * The default {@link AsynchronousEditor | editor} implementation that simply uses `new Function` to run the provided code.
34
- * @remarks This editor allows both synchronous and asynchronous code (i.e. the provided code may return a Promise).
35
- * @example `await new Function("context", code)(context);`
31
+ * Creates a {@link Context} for the given subtree.
36
32
  * @alpha
37
33
  */
38
- export declare const defaultEditor: AsynchronousEditor;
39
- /**
40
- * Binds the given {@link AsynchronousEditor | editor} to the given view or tree.
41
- * @returns A function that takes a string of JavaScript code and executes it on the given view or tree using the given editor function.
42
- * @remarks This is useful for testing/debugging code execution without needing to set up a full {@link SharedTreeSemanticAgent | agent}.
43
- * @alpha
44
- */
45
- export declare function bindEditorImpl<TSchema extends ImplicitFieldSchema>(tree: TreeView<TSchema> | (ReadableField<TSchema> & TreeNode), editor: AsynchronousEditor): (code: string) => Promise<void>;
46
- /**
47
- * Binds the given {@link SynchronousEditor | editor} to the given view or tree.
48
- * @returns A function that takes a string of JavaScript code and executes it on the given view or tree using the given editor function.
49
- * @remarks This is useful for testing/debugging code execution without needing to set up a full {@link SharedTreeSemanticAgent | agent}.
50
- * @alpha
51
- */
52
- export declare function bindEditorImpl<TSchema extends ImplicitFieldSchema>(tree: TreeView<TSchema> | (ReadableField<TSchema> & TreeNode), editor: SynchronousEditor): (code: string) => void;
53
- /**
54
- * Binds the given {@link SynchronousEditor | synchronous} or {@link AsynchronousEditor | asynchronous} editor to the given view or tree.
55
- * @returns A function that takes a string of JavaScript code and executes it on the given view or tree using the given editor.
56
- * @remarks This is useful for testing/debugging code execution without needing to set up a full {@link SharedTreeSemanticAgent | agent}.
57
- * @alpha
58
- * @privateRemarks This exists (as opposed to just exporting bindEditorImpl directly) so that API documentation links work correctly.
59
- */
60
- export declare const bindEditor: typeof bindEditorImpl;
34
+ export declare function createContext<TSchema extends ImplicitFieldSchema>(tree: ViewOrTree<TSchema>): Context<TSchema>;
61
35
  //# 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,EAAY,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EACX,aAAa,EAIb,MAAM,4BAA4B,CAAC;AAGpC,OAAO,KAAK,EACX,mBAAmB,EAEnB,oBAAoB,EAEpB,iBAAiB,EACjB,kBAAkB,EAElB,MAAM,UAAU,CAAC;AAGlB,OAAO,EAEN,KAAK,QAAQ,EAKb,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;CAqEvD;AAwED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,kBAI3B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,SAAS,mBAAmB,EACjE,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,EAC7D,MAAM,EAAE,kBAAkB,GACxB,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AACnC;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,SAAS,mBAAmB,EACjE,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,EAC7D,MAAM,EAAE,iBAAiB,GACvB,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;AAe1B;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,uBAAiB,CAAC"}
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;AAU9B,OAAO,KAAK,EACX,mBAAmB,EAEnB,oBAAoB,EAGpB,OAAO,EAEP,UAAU,EACV,MAAM,UAAU,CAAC;AAiBlB;;;;GAIG;AACH,qBAAa,uBAAuB,CAAC,OAAO,SAAS,mBAAmB;IAUtE,OAAO,CAAC,QAAQ,CAAC,MAAM;IAEvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAV1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2D;IAClF;;OAEG;IACH,OAAO,CAAC,gBAAgB,CAAS;gBAGf,MAAM,EAAE,mBAAmB,EAC5C,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,EACR,OAAO,CAAC,qDAAyC;IAkCnE;;;;;OAKG;IACU,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAqEvD;AAkFD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,SAAS,mBAAmB,EAChE,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,GACvB,OAAO,CAAC,OAAO,CAAC,CA2ClB"}
package/dist/agent.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.bindEditor = exports.bindEditorImpl = exports.defaultEditor = exports.SharedTreeSemanticAgent = void 0;
7
+ exports.createContext = exports.SharedTreeSemanticAgent = void 0;
8
8
  const tree_1 = require("@fluidframework/tree");
9
9
  const alpha_1 = require("@fluidframework/tree/alpha");
10
10
  const prompt_js_1 = require("./prompt.js");
@@ -35,6 +35,7 @@ class SharedTreeSemanticAgent {
35
35
  tree.events.on("changed", () => (this.outerTreeIsDirty = true));
36
36
  }
37
37
  this.outerTree = new subtree_js_1.Subtree(tree);
38
+ this.editor = this.options?.editor ?? createDefaultEditor();
38
39
  const prompt = (0, prompt_js_1.getPrompt)({
39
40
  subtree: this.outerTree,
40
41
  editToolName: this.client.editToolName,
@@ -100,7 +101,7 @@ class SharedTreeSemanticAgent {
100
101
  message: `The maximum number of edits (${maxEditCount}) for this query has been exceeded.`,
101
102
  };
102
103
  }
103
- const editResult = await applyTreeFunction(queryTree, editCode, this.options?.editor ?? exports.defaultEditor, this.options?.logger);
104
+ const editResult = await applyTreeFunction(queryTree, editCode, this.editor, this.options?.logger);
104
105
  rollbackEdits = editResult.type !== "success";
105
106
  return editResult;
106
107
  };
@@ -158,9 +159,8 @@ async function applyTreeFunction(tree, editCode, editor, logger) {
158
159
  logger?.log(`#### Generated Code\n\n\`\`\`javascript\n${editCode}\n\`\`\`\n\n`);
159
160
  // Fork a branch to edit. If the edit fails or produces an error, we discard this branch, otherwise we merge it.
160
161
  const editTree = tree.fork();
161
- const boundEditor = bindEditorToSubtree(editTree, editor);
162
162
  try {
163
- await boundEditor(editCode);
163
+ await editor(editTree.viewOrTree, editCode);
164
164
  }
165
165
  catch (error) {
166
166
  logger?.log(`#### Error\n\n`);
@@ -179,52 +179,34 @@ async function applyTreeFunction(tree, editCode, editor, logger) {
179
179
  message: `After running the code, the new state of the tree is:\n\n\`\`\`JSON\n${(0, prompt_js_1.stringifyTree)(tree.field)}\n\`\`\``,
180
180
  };
181
181
  }
182
- /**
183
- * The default {@link AsynchronousEditor | editor} implementation that simply uses `new Function` to run the provided code.
184
- * @remarks This editor allows both synchronous and asynchronous code (i.e. the provided code may return a Promise).
185
- * @example `await new Function("context", code)(context);`
186
- * @alpha
187
- */
188
- const defaultEditor = async (context, code) => {
189
- // eslint-disable-next-line no-new-func, @typescript-eslint/no-implied-eval
190
- const fn = new Function("context", code);
191
- await fn(context);
192
- };
193
- exports.defaultEditor = defaultEditor;
194
- /**
195
- * Binds the given {@link SynchronousEditor | editor} or {@link AsynchronousEditor | editor} to the given view or tree.
196
- * @returns A function that takes a string of JavaScript code and executes it on the given view or tree using the given editor function.
197
- * @remarks This is useful for testing/debugging code execution without needing to set up a full {@link SharedTreeSemanticAgent | agent}.
198
- * @alpha
199
- */
200
- function bindEditorImpl(tree, editor) {
201
- const subtree = new subtree_js_1.Subtree(tree);
202
- return bindEditorToSubtree(subtree, editor);
182
+ function createDefaultEditor() {
183
+ return async (tree, code) => {
184
+ const context = createContext(tree);
185
+ // eslint-disable-next-line no-new-func, @typescript-eslint/no-implied-eval
186
+ const fn = new Function("context", code);
187
+ await fn(context);
188
+ };
203
189
  }
204
- exports.bindEditorImpl = bindEditorImpl;
205
190
  /**
206
- * Binds the given {@link SynchronousEditor | synchronous} or {@link AsynchronousEditor | asynchronous} editor to the given view or tree.
207
- * @returns A function that takes a string of JavaScript code and executes it on the given view or tree using the given editor.
208
- * @remarks This is useful for testing/debugging code execution without needing to set up a full {@link SharedTreeSemanticAgent | agent}.
191
+ * Creates a {@link Context} for the given subtree.
209
192
  * @alpha
210
- * @privateRemarks This exists (as opposed to just exporting bindEditorImpl directly) so that API documentation links work correctly.
211
193
  */
212
- exports.bindEditor = bindEditorImpl;
213
- function bindEditorToSubtree(tree, executeEdit) {
194
+ function createContext(tree) {
195
+ const subTree = new subtree_js_1.Subtree(tree);
214
196
  // Stick the tree schema constructors on an object passed to the function so that the LLM can create new nodes.
215
197
  const create = {};
216
198
  const is = {};
217
- for (const schema of (0, utils_js_1.findSchemas)(tree.schema, (s) => (0, utils_js_1.isNamedSchema)(s.identifier))) {
199
+ for (const schema of (0, utils_js_1.findSchemas)(subTree.schema, (s) => (0, utils_js_1.isNamedSchema)(s.identifier))) {
218
200
  const name = (0, utils_js_1.unqualifySchema)(schema.identifier);
219
201
  create[name] = (input) => constructTreeNode(schema, input);
220
202
  is[name] = (input) => alpha_1.Tree.is(input, schema);
221
203
  }
222
- const context = {
204
+ return {
223
205
  get root() {
224
- return tree.field;
206
+ return subTree.field;
225
207
  },
226
208
  set root(value) {
227
- tree.field = value;
209
+ subTree.field = value;
228
210
  },
229
211
  create,
230
212
  is,
@@ -251,7 +233,6 @@ function bindEditorToSubtree(tree, executeEdit) {
251
233
  parent: (child) => alpha_1.Tree.parent(child),
252
234
  key: (child) => alpha_1.Tree.key(child),
253
235
  };
254
- // eslint-disable-next-line @typescript-eslint/promise-function-async
255
- return (code) => executeEdit(context, code);
256
236
  }
237
+ exports.createContext = createContext;
257
238
  //# 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 { NodeKind, TreeNode } from \"@fluidframework/tree\";\nimport type {\n\tReadableField,\n\tFactoryContentObject,\n\tInsertableContent,\n\tReadSchema,\n} from \"@fluidframework/tree/alpha\";\nimport { ObjectNodeSchema, Tree, TreeAlpha } from \"@fluidframework/tree/alpha\";\n\nimport type {\n\tSharedTreeChatModel,\n\tEditResult,\n\tSemanticAgentOptions,\n\tLogger,\n\tSynchronousEditor,\n\tAsynchronousEditor,\n\tContext,\n} from \"./api.js\";\nimport { getPrompt, stringifyTree } from \"./prompt.js\";\nimport { Subtree } from \"./subtree.js\";\nimport {\n\tllmDefault,\n\ttype TreeView,\n\tfindSchemas,\n\ttoErrorString,\n\tunqualifySchema,\n\tisNamedSchema,\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 rollbackEdits = 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\trollbackEdits = 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?.editor ?? defaultEditor,\n\t\t\t\tthis.options?.logger,\n\t\t\t);\n\n\t\t\trollbackEdits = 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 (!rollbackEdits) {\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, content: FactoryContentObject): TreeNode {\n\tlet toInsert = content;\n\tif (schema instanceof ObjectNodeSchema) {\n\t\tconst contentWithDefaults: Record<string, InsertableContent | undefined> = {};\n\t\tfor (const [key, field] of schema.fields) {\n\t\t\tif (content[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\tcontentWithDefaults[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\tcontentWithDefaults[key] = content[key];\n\t\t\t}\n\t\t}\n\t\ttoInsert = contentWithDefaults;\n\t}\n\n\t// Cast to never because tagContentSchema is typed to only accept InsertableContent, but we know that 'toInsert' (either the original content or contentWithDefaults) produces valid content for the schema.\n\treturn TreeAlpha.tagContentSchema(schema, toInsert as never);\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\teditor: Required<SemanticAgentOptions>[\"editor\"],\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\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 boundEditor = bindEditorToSubtree(editTree, editor);\n\ttry {\n\t\tawait boundEditor(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: \"editingError\",\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\n/**\n * The default {@link AsynchronousEditor | editor} implementation that simply uses `new Function` to run the provided code.\n * @remarks This editor allows both synchronous and asynchronous code (i.e. the provided code may return a Promise).\n * @example `await new Function(\"context\", code)(context);`\n * @alpha\n */\nexport const defaultEditor: AsynchronousEditor = async (context, code) => {\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\n/**\n * Binds the given {@link AsynchronousEditor | editor} to the given view or tree.\n * @returns A function that takes a string of JavaScript code and executes it on the given view or tree using the given editor function.\n * @remarks This is useful for testing/debugging code execution without needing to set up a full {@link SharedTreeSemanticAgent | agent}.\n * @alpha\n */\nexport function bindEditorImpl<TSchema extends ImplicitFieldSchema>(\n\ttree: TreeView<TSchema> | (ReadableField<TSchema> & TreeNode),\n\teditor: AsynchronousEditor,\n): (code: string) => Promise<void>;\n/**\n * Binds the given {@link SynchronousEditor | editor} to the given view or tree.\n * @returns A function that takes a string of JavaScript code and executes it on the given view or tree using the given editor function.\n * @remarks This is useful for testing/debugging code execution without needing to set up a full {@link SharedTreeSemanticAgent | agent}.\n * @alpha\n */\nexport function bindEditorImpl<TSchema extends ImplicitFieldSchema>(\n\ttree: TreeView<TSchema> | (ReadableField<TSchema> & TreeNode),\n\teditor: SynchronousEditor,\n): (code: string) => void;\n/**\n * Binds the given {@link SynchronousEditor | editor} or {@link AsynchronousEditor | editor} to the given view or tree.\n * @returns A function that takes a string of JavaScript code and executes it on the given view or tree using the given editor function.\n * @remarks This is useful for testing/debugging code execution without needing to set up a full {@link SharedTreeSemanticAgent | agent}.\n * @alpha\n */\nexport function bindEditorImpl<TSchema extends ImplicitFieldSchema>(\n\ttree: TreeView<TSchema> | (ReadableField<TSchema> & TreeNode),\n\teditor: SynchronousEditor | AsynchronousEditor,\n): ((code: string) => void) | ((code: string) => Promise<void>) {\n\tconst subtree = new Subtree(tree);\n\treturn bindEditorToSubtree(subtree, editor);\n}\n\n/**\n * Binds the given {@link SynchronousEditor | synchronous} or {@link AsynchronousEditor | asynchronous} editor to the given view or tree.\n * @returns A function that takes a string of JavaScript code and executes it on the given view or tree using the given editor.\n * @remarks This is useful for testing/debugging code execution without needing to set up a full {@link SharedTreeSemanticAgent | agent}.\n * @alpha\n * @privateRemarks This exists (as opposed to just exporting bindEditorImpl directly) so that API documentation links work correctly.\n */\nexport const bindEditor = bindEditorImpl;\n\nfunction bindEditorToSubtree<TSchema extends ImplicitFieldSchema>(\n\ttree: Subtree<TSchema>,\n\texecuteEdit: SynchronousEditor | AsynchronousEditor,\n): (code: string) => void | Promise<void> {\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\tconst is: Record<string, <T extends TreeNode>(input: unknown) => input is T> = {};\n\tfor (const schema of findSchemas(tree.schema, (s) => isNamedSchema(s.identifier))) {\n\t\tconst name = unqualifySchema(schema.identifier);\n\t\tcreate[name] = (input: FactoryContentObject) => constructTreeNode(schema, input);\n\t\tis[name] = <T extends TreeNode>(input: unknown): input is T => Tree.is(input, schema);\n\t}\n\n\tconst context = {\n\t\tget root(): ReadableField<TSchema> {\n\t\t\treturn tree.field;\n\t\t},\n\t\tset root(value: TreeFieldFromImplicitField<ReadSchema<TSchema>>) {\n\t\t\ttree.field = value;\n\t\t},\n\t\tcreate,\n\t\tis,\n\t\tisArray(node) {\n\t\t\tif (Array.isArray(node)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (node instanceof TreeNode) {\n\t\t\t\tconst schema = Tree.schema(node);\n\t\t\t\treturn schema.kind === NodeKind.Array;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tisMap(node) {\n\t\t\tif (node instanceof Map) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (node instanceof TreeNode) {\n\t\t\t\tconst schema = Tree.schema(node);\n\t\t\t\treturn schema.kind === NodeKind.Map;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tparent: (child: TreeNode): TreeNode | undefined => Tree.parent(child),\n\t\tkey: (child: TreeNode): string | number => Tree.key(child),\n\t} satisfies Context<TSchema>;\n\n\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\treturn (code: string) => executeEdit(context, 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 { NodeKind, TreeNode } from \"@fluidframework/tree\";\nimport type {\n\tReadableField,\n\tFactoryContentObject,\n\tInsertableContent,\n\tReadSchema,\n} from \"@fluidframework/tree/alpha\";\nimport { ObjectNodeSchema, Tree, TreeAlpha } from \"@fluidframework/tree/alpha\";\n\nimport type {\n\tSharedTreeChatModel,\n\tEditResult,\n\tSemanticAgentOptions,\n\tLogger,\n\tAsynchronousEditor,\n\tContext,\n\tSynchronousEditor,\n\tViewOrTree,\n} from \"./api.js\";\nimport { getPrompt, stringifyTree } from \"./prompt.js\";\nimport { Subtree } from \"./subtree.js\";\nimport {\n\tllmDefault,\n\tfindSchemas,\n\ttoErrorString,\n\tunqualifySchema,\n\tisNamedSchema,\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\tprivate readonly editor: SynchronousEditor<TSchema> | AsynchronousEditor<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: ViewOrTree<TSchema>,\n\t\tprivate readonly options?: Readonly<SemanticAgentOptions<TSchema>>,\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\tthis.editor = this.options?.editor ?? createDefaultEditor();\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 rollbackEdits = 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\trollbackEdits = 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.editor,\n\t\t\t\tthis.options?.logger,\n\t\t\t);\n\n\t\t\trollbackEdits = 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 (!rollbackEdits) {\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, content: FactoryContentObject): TreeNode {\n\tlet toInsert = content;\n\tif (schema instanceof ObjectNodeSchema) {\n\t\tconst contentWithDefaults: Record<string, InsertableContent | undefined> = {};\n\t\tfor (const [key, field] of schema.fields) {\n\t\t\tif (content[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\tcontentWithDefaults[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\tcontentWithDefaults[key] = content[key];\n\t\t\t}\n\t\t}\n\t\ttoInsert = contentWithDefaults;\n\t}\n\n\t// Cast to never because tagContentSchema is typed to only accept InsertableContent, but we know that 'toInsert' (either the original content or contentWithDefaults) produces valid content for the schema.\n\treturn TreeAlpha.tagContentSchema(schema, toInsert as never);\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\teditor: SynchronousEditor<TSchema> | AsynchronousEditor<TSchema>,\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\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\ttry {\n\t\tawait editor(editTree.viewOrTree, 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: \"editingError\",\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\nfunction createDefaultEditor<\n\tTSchema extends ImplicitFieldSchema = ImplicitFieldSchema,\n>(): AsynchronousEditor<TSchema> {\n\treturn async (tree, code) => {\n\t\tconst context = createContext(tree);\n\t\t// eslint-disable-next-line no-new-func, @typescript-eslint/no-implied-eval\n\t\tconst fn = new Function(\"context\", code);\n\t\tawait fn(context);\n\t};\n}\n\n/**\n * Creates a {@link Context} for the given subtree.\n * @alpha\n */\nexport function createContext<TSchema extends ImplicitFieldSchema>(\n\ttree: ViewOrTree<TSchema>,\n): Context<TSchema> {\n\tconst subTree = new Subtree(tree);\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\tconst is: Record<string, <T extends TreeNode>(input: unknown) => input is T> = {};\n\tfor (const schema of findSchemas(subTree.schema, (s) => isNamedSchema(s.identifier))) {\n\t\tconst name = unqualifySchema(schema.identifier);\n\t\tcreate[name] = (input: FactoryContentObject) => constructTreeNode(schema, input);\n\t\tis[name] = <T extends TreeNode>(input: unknown): input is T => Tree.is(input, schema);\n\t}\n\n\treturn {\n\t\tget root(): ReadableField<TSchema> {\n\t\t\treturn subTree.field;\n\t\t},\n\t\tset root(value: TreeFieldFromImplicitField<ReadSchema<TSchema>>) {\n\t\t\tsubTree.field = value;\n\t\t},\n\t\tcreate,\n\t\tis,\n\t\tisArray(node) {\n\t\t\tif (Array.isArray(node)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (node instanceof TreeNode) {\n\t\t\t\tconst schema = Tree.schema(node);\n\t\t\t\treturn schema.kind === NodeKind.Array;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tisMap(node) {\n\t\t\tif (node instanceof Map) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (node instanceof TreeNode) {\n\t\t\t\tconst schema = Tree.schema(node);\n\t\t\t\treturn schema.kind === NodeKind.Map;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tparent: (child: TreeNode): TreeNode | undefined => Tree.parent(child),\n\t\tkey: (child: TreeNode): string | number => Tree.key(child),\n\t} satisfies Context<TSchema>;\n}\n"]}
package/dist/alpha.d.ts CHANGED
@@ -20,25 +20,34 @@ export {
20
20
  ArgsTuple,
21
21
  AsynchronousEditor,
22
22
  BindableSchema,
23
+ Context,
23
24
  Ctor,
24
25
  EditResult,
26
+ ExposableKeys,
25
27
  ExposedMethods,
28
+ ExposedProperties,
26
29
  FunctionDef,
27
30
  IExposedMethods,
31
+ IExposedProperties,
32
+ IfEquals,
28
33
  Infer,
29
34
  Logger,
30
35
  MethodKeys,
36
+ PropertyDef,
37
+ ReadOnlyRequirement,
38
+ ReadonlyKeys,
31
39
  SemanticAgentOptions,
32
40
  SharedTreeChatModel,
33
41
  SharedTreeChatQuery,
34
42
  SharedTreeSemanticAgent,
35
43
  SynchronousEditor,
36
44
  TreeView,
37
- bindEditor,
38
- bindEditorImpl,
45
+ TypeMatchOrError,
46
+ ViewOrTree,
39
47
  buildFunc,
40
- defaultEditor,
48
+ createContext,
41
49
  exposeMethodsSymbol,
50
+ exposePropertiesSymbol,
42
51
  llmDefault
43
52
  // #endregion
44
53
  } from "./index.js";
package/dist/api.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import type { ImplicitFieldSchema, TreeNode } from "@fluidframework/tree";
6
- import type { FactoryContentObject, ReadableField } from "@fluidframework/tree/alpha";
6
+ import type { FactoryContentObject, ReadableField, TreeBranchAlpha, TreeViewAlpha } from "@fluidframework/tree/alpha";
7
7
  /**
8
8
  * Logger interface for logging events from a {@link SharedTreeSemanticAgent}.
9
9
  * @alpha
@@ -14,10 +14,23 @@ export interface Logger {
14
14
  */
15
15
  log(message: string): void;
16
16
  }
17
+ /**
18
+ * A SharedTree view for use by a {@link SharedTreeSemanticAgent}.
19
+ * @alpha
20
+ * @privateRemarks This is a subset of the TreeViewAlpha functionality because if take it wholesale, it causes problems with invariance of the generic parameters.
21
+ */
22
+ export type TreeView<TRoot extends ImplicitFieldSchema> = Pick<TreeViewAlpha<TRoot>, "root" | "fork" | "merge" | "rebaseOnto" | "schema" | "events"> & TreeBranchAlpha;
23
+ /**
24
+ * A value that is either a {@link TreeView} or a subtree within a {@link TreeView}.
25
+ * @alpha
26
+ */
27
+ export type ViewOrTree<TSchema extends ImplicitFieldSchema> = TreeView<TSchema> | (ReadableField<TSchema> & TreeNode);
17
28
  /**
18
29
  * The context object available to generated code when editing a tree.
19
30
  * @remarks This object is provided to JavaScript code executed by the {@link SynchronousEditor | editor} as a variable named `context`.
20
31
  * It contains the current state of the tree and utilities for creating and inspecting tree nodes.
32
+ *
33
+ * Use {@link createContext} to create a context.
21
34
  * @alpha
22
35
  */
23
36
  export interface Context<TSchema extends ImplicitFieldSchema> {
@@ -82,25 +95,39 @@ export interface Context<TSchema extends ImplicitFieldSchema> {
82
95
  }
83
96
  /**
84
97
  * A synchronous function that executes a string of JavaScript code to perform an edit within a {@link SharedTreeSemanticAgent}.
85
- * @param context - An object that must be provided to the generated code as a variable named "context" in its top-level scope.
98
+ * @param tree - The tree to edit.
86
99
  * @param code - The JavaScript code that should be executed.
87
- * @remarks To simulate the execution of an editor outside of an {@link SharedTreeSemanticAgent | agent}, you can use {@link bindEditor | bindEditor} to bind an editor to a specific subtree.
100
+ * @throws Any error thrown by the executed code.
101
+ * @remarks The code expects a variable named `context` to be in scope, which provides access to the tree and utilities for creating and inspecting nodes.
102
+ * A context can be created for a given tree via the {@link createContext} function.
103
+ * @example
104
+ * ```ts
105
+ * // A simple editor implementation that runs the provided code via a JavaScript Function.
106
+ * new Function("context", code)(createContext(tree));
107
+ * ```
88
108
  * @alpha
89
109
  */
90
- export type SynchronousEditor = (context: Record<string, unknown>, code: string) => void;
110
+ export type SynchronousEditor<TSchema extends ImplicitFieldSchema> = (tree: ViewOrTree<TSchema>, code: string) => void;
91
111
  /**
92
112
  * An asynchronous function that executes a string of JavaScript code to perform an edit within a {@link SharedTreeSemanticAgent}.
93
- * @param context - An object that must be provided to the generated code as a variable named "context" in its top-level scope.
113
+ * @param tree - The tree to edit.
94
114
  * @param code - The JavaScript code that should be executed.
95
- * @remarks To simulate the execution of an editor outside of an {@link SharedTreeSemanticAgent | agent}, you can use {@link bindEditor | bindEditor} to bind an editor to a specific subtree.
115
+ * @throws Any error thrown by the executed code.
116
+ * @remarks The code expects a variable named `context` to be in scope, which provides access to the tree and utilities for creating and inspecting nodes.
117
+ * A context can be created for a given tree via the {@link createContext} function.
118
+ * @example
119
+ * ```ts
120
+ * // A simple editor implementation that runs the provided code via a JavaScript Function.
121
+ * await new Function("context", code)(createContext(tree));
122
+ * ```
96
123
  * @alpha
97
124
  */
98
- export type AsynchronousEditor = (context: Record<string, unknown>, code: string) => Promise<void>;
125
+ export type AsynchronousEditor<TSchema extends ImplicitFieldSchema> = (tree: ViewOrTree<TSchema>, code: string) => Promise<void>;
99
126
  /**
100
127
  * Options used to parameterize the creation of a {@link SharedTreeSemanticAgent}.
101
128
  * @alpha
102
129
  */
103
- export interface SemanticAgentOptions {
130
+ export interface SemanticAgentOptions<TSchema extends ImplicitFieldSchema> {
104
131
  /**
105
132
  * Additional information about the application domain that will be included in the context provided to the {@link SharedTreeChatModel | model}.
106
133
  */
@@ -108,12 +135,10 @@ export interface SemanticAgentOptions {
108
135
  /**
109
136
  * Executes any generated JavaScript created by the {@link SharedTreeChatModel.editToolName | model's editing tool}.
110
137
  * @remarks If an error is thrown while executing the code, it will be caught and the message will be forwarded to the {@link SharedTreeChatModel | model} for debugging.
111
- * @remarks If this function is not provided, the generated code will be executed using a {@link defaultEditor | simple default} which may not provide sufficient security guarantees for some environments.
112
- * Use a library such as SES to provide a more secure implementation - see `@fluidframework/tree-agent-ses` for a drop-in implementation.
113
- *
114
- * To simulate the execution of an editor outside of an {@link SharedTreeSemanticAgent | agent}, you can use {@link bindEditor | bindEditor} to bind an editor to a specific subtree.
138
+ * @remarks If this function is not provided, the generated code will be executed using a simple JavaScript eval which may not provide sufficient security guarantees for some environments.
139
+ * Run the code in a sandboxed environment or use a library such as SES to provide a more secure implementation - see `@fluidframework/tree-agent-ses` for a drop-in implementation.
115
140
  */
116
- editor?: SynchronousEditor | AsynchronousEditor;
141
+ editor?: SynchronousEditor<TSchema> | AsynchronousEditor<TSchema>;
117
142
  /**
118
143
  * The maximum number of sequential edits the LLM can make before we assume it's stuck in a loop.
119
144
  */
@@ -202,11 +227,4 @@ export interface SharedTreeChatModel {
202
227
  */
203
228
  query(message: SharedTreeChatQuery): Promise<string>;
204
229
  }
205
- /**
206
- * A function that edits a SharedTree.
207
- */
208
- export type EditFunction<TSchema extends ImplicitFieldSchema> = ({ root, create, }: {
209
- root: ReadableField<TSchema>;
210
- create: Record<string, (input: FactoryContentObject) => TreeNode>;
211
- }) => void | Promise<void>;
212
230
  //# sourceMappingURL=api.d.ts.map
package/dist/api.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}