@fluidframework/ai-collab 2.10.0-306579

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 (168) hide show
  1. package/.eslintrc.cjs +26 -0
  2. package/CHANGELOG.md +9 -0
  3. package/LICENSE +21 -0
  4. package/README.md +280 -0
  5. package/alpha.d.ts +11 -0
  6. package/api-extractor/api-extractor-lint-alpha.cjs.json +5 -0
  7. package/api-extractor/api-extractor-lint-alpha.esm.json +5 -0
  8. package/api-extractor/api-extractor-lint-bundle.json +5 -0
  9. package/api-extractor/api-extractor-lint-index.cjs.json +5 -0
  10. package/api-extractor/api-extractor-lint-index.esm.json +5 -0
  11. package/api-extractor/api-extractor-lint-public.cjs.json +5 -0
  12. package/api-extractor/api-extractor-lint-public.esm.json +5 -0
  13. package/api-extractor-lint.json +4 -0
  14. package/api-extractor.json +4 -0
  15. package/api-report/ai-collab.alpha.api.md +164 -0
  16. package/api-report/ai-collab.beta.api.md +7 -0
  17. package/api-report/ai-collab.public.api.md +7 -0
  18. package/biome.jsonc +4 -0
  19. package/dist/aiCollab.d.ts +65 -0
  20. package/dist/aiCollab.d.ts.map +1 -0
  21. package/dist/aiCollab.js +81 -0
  22. package/dist/aiCollab.js.map +1 -0
  23. package/dist/aiCollabApi.d.ts +173 -0
  24. package/dist/aiCollabApi.d.ts.map +1 -0
  25. package/dist/aiCollabApi.js +7 -0
  26. package/dist/aiCollabApi.js.map +1 -0
  27. package/dist/alpha.d.ts +41 -0
  28. package/dist/explicit-strategy/agentEditReducer.d.ts +12 -0
  29. package/dist/explicit-strategy/agentEditReducer.d.ts.map +1 -0
  30. package/dist/explicit-strategy/agentEditReducer.js +394 -0
  31. package/dist/explicit-strategy/agentEditReducer.js.map +1 -0
  32. package/dist/explicit-strategy/agentEditTypes.d.ts +158 -0
  33. package/dist/explicit-strategy/agentEditTypes.d.ts.map +1 -0
  34. package/dist/explicit-strategy/agentEditTypes.js +50 -0
  35. package/dist/explicit-strategy/agentEditTypes.js.map +1 -0
  36. package/dist/explicit-strategy/idGenerator.d.ts +22 -0
  37. package/dist/explicit-strategy/idGenerator.d.ts.map +1 -0
  38. package/dist/explicit-strategy/idGenerator.js +74 -0
  39. package/dist/explicit-strategy/idGenerator.js.map +1 -0
  40. package/dist/explicit-strategy/index.d.ts +51 -0
  41. package/dist/explicit-strategy/index.d.ts.map +1 -0
  42. package/dist/explicit-strategy/index.js +223 -0
  43. package/dist/explicit-strategy/index.js.map +1 -0
  44. package/dist/explicit-strategy/jsonTypes.d.ts +23 -0
  45. package/dist/explicit-strategy/jsonTypes.d.ts.map +1 -0
  46. package/dist/explicit-strategy/jsonTypes.js +7 -0
  47. package/dist/explicit-strategy/jsonTypes.js.map +1 -0
  48. package/dist/explicit-strategy/promptGeneration.d.ts +51 -0
  49. package/dist/explicit-strategy/promptGeneration.d.ts.map +1 -0
  50. package/dist/explicit-strategy/promptGeneration.js +218 -0
  51. package/dist/explicit-strategy/promptGeneration.js.map +1 -0
  52. package/dist/explicit-strategy/typeGeneration.d.ts +15 -0
  53. package/dist/explicit-strategy/typeGeneration.d.ts.map +1 -0
  54. package/dist/explicit-strategy/typeGeneration.js +264 -0
  55. package/dist/explicit-strategy/typeGeneration.js.map +1 -0
  56. package/dist/explicit-strategy/utils.d.ts +37 -0
  57. package/dist/explicit-strategy/utils.d.ts.map +1 -0
  58. package/dist/explicit-strategy/utils.js +47 -0
  59. package/dist/explicit-strategy/utils.js.map +1 -0
  60. package/dist/implicit-strategy/index.d.ts +8 -0
  61. package/dist/implicit-strategy/index.d.ts.map +1 -0
  62. package/dist/implicit-strategy/index.js +18 -0
  63. package/dist/implicit-strategy/index.js.map +1 -0
  64. package/dist/implicit-strategy/sharedTreeBranchManager.d.ts +63 -0
  65. package/dist/implicit-strategy/sharedTreeBranchManager.d.ts.map +1 -0
  66. package/dist/implicit-strategy/sharedTreeBranchManager.js +212 -0
  67. package/dist/implicit-strategy/sharedTreeBranchManager.js.map +1 -0
  68. package/dist/implicit-strategy/sharedTreeDiff.d.ts +102 -0
  69. package/dist/implicit-strategy/sharedTreeDiff.d.ts.map +1 -0
  70. package/dist/implicit-strategy/sharedTreeDiff.js +522 -0
  71. package/dist/implicit-strategy/sharedTreeDiff.js.map +1 -0
  72. package/dist/implicit-strategy/utils.d.ts +21 -0
  73. package/dist/implicit-strategy/utils.d.ts.map +1 -0
  74. package/dist/implicit-strategy/utils.js +49 -0
  75. package/dist/implicit-strategy/utils.js.map +1 -0
  76. package/dist/index.d.ts +16 -0
  77. package/dist/index.d.ts.map +1 -0
  78. package/dist/index.js +24 -0
  79. package/dist/index.js.map +1 -0
  80. package/dist/package.json +3 -0
  81. package/dist/public.d.ts +19 -0
  82. package/eslintrc.cjs +11 -0
  83. package/internal.d.ts +11 -0
  84. package/lib/aiCollab.d.ts +65 -0
  85. package/lib/aiCollab.d.ts.map +1 -0
  86. package/lib/aiCollab.js +77 -0
  87. package/lib/aiCollab.js.map +1 -0
  88. package/lib/aiCollabApi.d.ts +173 -0
  89. package/lib/aiCollabApi.d.ts.map +1 -0
  90. package/lib/aiCollabApi.js +6 -0
  91. package/lib/aiCollabApi.js.map +1 -0
  92. package/lib/alpha.d.ts +41 -0
  93. package/lib/explicit-strategy/agentEditReducer.d.ts +12 -0
  94. package/lib/explicit-strategy/agentEditReducer.d.ts.map +1 -0
  95. package/lib/explicit-strategy/agentEditReducer.js +390 -0
  96. package/lib/explicit-strategy/agentEditReducer.js.map +1 -0
  97. package/lib/explicit-strategy/agentEditTypes.d.ts +158 -0
  98. package/lib/explicit-strategy/agentEditTypes.d.ts.map +1 -0
  99. package/lib/explicit-strategy/agentEditTypes.js +47 -0
  100. package/lib/explicit-strategy/agentEditTypes.js.map +1 -0
  101. package/lib/explicit-strategy/idGenerator.d.ts +22 -0
  102. package/lib/explicit-strategy/idGenerator.d.ts.map +1 -0
  103. package/lib/explicit-strategy/idGenerator.js +70 -0
  104. package/lib/explicit-strategy/idGenerator.js.map +1 -0
  105. package/lib/explicit-strategy/index.d.ts +51 -0
  106. package/lib/explicit-strategy/index.d.ts.map +1 -0
  107. package/lib/explicit-strategy/index.js +219 -0
  108. package/lib/explicit-strategy/index.js.map +1 -0
  109. package/lib/explicit-strategy/jsonTypes.d.ts +23 -0
  110. package/lib/explicit-strategy/jsonTypes.d.ts.map +1 -0
  111. package/lib/explicit-strategy/jsonTypes.js +6 -0
  112. package/lib/explicit-strategy/jsonTypes.js.map +1 -0
  113. package/lib/explicit-strategy/promptGeneration.d.ts +51 -0
  114. package/lib/explicit-strategy/promptGeneration.d.ts.map +1 -0
  115. package/lib/explicit-strategy/promptGeneration.js +208 -0
  116. package/lib/explicit-strategy/promptGeneration.js.map +1 -0
  117. package/lib/explicit-strategy/typeGeneration.d.ts +15 -0
  118. package/lib/explicit-strategy/typeGeneration.d.ts.map +1 -0
  119. package/lib/explicit-strategy/typeGeneration.js +260 -0
  120. package/lib/explicit-strategy/typeGeneration.js.map +1 -0
  121. package/lib/explicit-strategy/utils.d.ts +37 -0
  122. package/lib/explicit-strategy/utils.d.ts.map +1 -0
  123. package/lib/explicit-strategy/utils.js +41 -0
  124. package/lib/explicit-strategy/utils.js.map +1 -0
  125. package/lib/implicit-strategy/index.d.ts +8 -0
  126. package/lib/implicit-strategy/index.d.ts.map +1 -0
  127. package/lib/implicit-strategy/index.js +8 -0
  128. package/lib/implicit-strategy/index.js.map +1 -0
  129. package/lib/implicit-strategy/sharedTreeBranchManager.d.ts +63 -0
  130. package/lib/implicit-strategy/sharedTreeBranchManager.d.ts.map +1 -0
  131. package/lib/implicit-strategy/sharedTreeBranchManager.js +213 -0
  132. package/lib/implicit-strategy/sharedTreeBranchManager.js.map +1 -0
  133. package/lib/implicit-strategy/sharedTreeDiff.d.ts +102 -0
  134. package/lib/implicit-strategy/sharedTreeDiff.d.ts.map +1 -0
  135. package/lib/implicit-strategy/sharedTreeDiff.js +515 -0
  136. package/lib/implicit-strategy/sharedTreeDiff.js.map +1 -0
  137. package/lib/implicit-strategy/utils.d.ts +21 -0
  138. package/lib/implicit-strategy/utils.d.ts.map +1 -0
  139. package/lib/implicit-strategy/utils.js +43 -0
  140. package/lib/implicit-strategy/utils.js.map +1 -0
  141. package/lib/index.d.ts +16 -0
  142. package/lib/index.d.ts.map +1 -0
  143. package/lib/index.js +15 -0
  144. package/lib/index.js.map +1 -0
  145. package/lib/public.d.ts +19 -0
  146. package/lib/tsdoc-metadata.json +11 -0
  147. package/mocharc.cjs +14 -0
  148. package/package.json +165 -0
  149. package/prettier.config.cjs +8 -0
  150. package/src/aiCollab.ts +86 -0
  151. package/src/aiCollabApi.ts +184 -0
  152. package/src/explicit-strategy/agentEditReducer.ts +498 -0
  153. package/src/explicit-strategy/agentEditTypes.ts +177 -0
  154. package/src/explicit-strategy/idGenerator.ts +90 -0
  155. package/src/explicit-strategy/index.ts +364 -0
  156. package/src/explicit-strategy/jsonTypes.ts +27 -0
  157. package/src/explicit-strategy/promptGeneration.ts +294 -0
  158. package/src/explicit-strategy/typeGeneration.ts +374 -0
  159. package/src/explicit-strategy/utils.ts +60 -0
  160. package/src/implicit-strategy/README.md +4 -0
  161. package/src/implicit-strategy/index.ts +21 -0
  162. package/src/implicit-strategy/sharedTreeBranchManager.ts +294 -0
  163. package/src/implicit-strategy/sharedTreeDiff.ts +735 -0
  164. package/src/implicit-strategy/utils.ts +54 -0
  165. package/src/index.ts +39 -0
  166. package/tsconfig.cjs.json +7 -0
  167. package/tsconfig.json +12 -0
  168. package/tsdoc.json +4 -0
@@ -0,0 +1,208 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { assert } from "@fluidframework/core-utils/internal";
6
+ import { NodeKind, getJsonSchema, getSimpleSchema, Tree, } from "@fluidframework/tree/internal";
7
+ // eslint-disable-next-line import/no-internal-modules
8
+ import { createZodJsonValidator } from "typechat/zod";
9
+ import { objectIdKey } from "./agentEditTypes.js";
10
+ import { generateGenericEditTypes } from "./typeGeneration.js";
11
+ import { fail } from "./utils.js";
12
+ /**
13
+ * TBD
14
+ */
15
+ export function toDecoratedJson(idGenerator, root) {
16
+ idGenerator.assignIds(root);
17
+ const stringified = JSON.stringify(root, (_, value) => {
18
+ if (typeof value === "object" && !Array.isArray(value) && value !== null) {
19
+ // TODO: SharedTree Team needs to either publish TreeNode as a class to use .instanceof() or a typeguard.
20
+ // Uncomment this assertion back once we have a typeguard ready.
21
+ // assert(isTreeNode(node), "Non-TreeNode value in tree.");
22
+ const objId =
23
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
24
+ idGenerator.getId(value) ?? fail("ID of new node should have been assigned.");
25
+ assert(!Object.prototype.hasOwnProperty.call(value, objectIdKey), `Collision of object id property.`);
26
+ return {
27
+ [objectIdKey]: objId,
28
+ ...value,
29
+ };
30
+ }
31
+ return value;
32
+ });
33
+ return stringified;
34
+ }
35
+ /**
36
+ * Generates a prompt designed to make an LLM produce a plan to edit the SharedTree to accomplish a user-specified goal.
37
+ */
38
+ export function getPlanningSystemPrompt(treeNode, userPrompt, systemRoleContext) {
39
+ const schema = Tree.schema(treeNode);
40
+ const promptFriendlySchema = getPromptFriendlyTreeSchema(getJsonSchema(schema));
41
+ const role = `I'm an agent who makes plans for another agent to achieve a user-specified goal to update the state of an application.${systemRoleContext === undefined
42
+ ? ""
43
+ : `
44
+ The other agent follows this guidance: ${systemRoleContext}`}`;
45
+ const systemPrompt = `
46
+ ${role}
47
+ The application state tree is a JSON object with the following schema: ${promptFriendlySchema}
48
+ The current state is: ${JSON.stringify(treeNode)}.
49
+ The user requested that I accomplish the following goal:
50
+ "${userPrompt}"
51
+ I've made a plan to accomplish this goal by doing a sequence of edits to the tree.
52
+ Edits can include setting the root, inserting, modifying, removing, or moving elements in the tree.
53
+ Here is my plan:`;
54
+ return systemPrompt;
55
+ }
56
+ /**
57
+ * Generates a prompt that provides a history of the edits an LLM has made to a SharedTree as well as any errors that occured from attemping to apply each respsecitve edit to the tree.
58
+ */
59
+ export function createEditListHistoryPrompt(edits) {
60
+ return edits
61
+ .map((edit, index) => {
62
+ const error = edit.error === undefined
63
+ ? ""
64
+ : ` This edit produced an error, and was discarded. The error message was: "${edit.error}"`;
65
+ return `${index + 1}. ${JSON.stringify(edit.edit)}${error}`;
66
+ })
67
+ .join("\n");
68
+ }
69
+ /**
70
+ * Generates the main prompt of this explicit strategy.
71
+ * This prompt is designed to give an LLM instructions on how it can modify a SharedTree using specific types of {@link TreeEdit}'s
72
+ * and provides with both a serialized version of the current state of the provided tree node as well as the interfaces that compromise said tree nodes data.
73
+ */
74
+ export function getEditingSystemPrompt(userPrompt, idGenerator, treeNode, log, appGuidance, plan) {
75
+ const schema = Tree.schema(treeNode);
76
+ const promptFriendlySchema = getPromptFriendlyTreeSchema(getJsonSchema(schema));
77
+ const decoratedTreeJson = toDecoratedJson(idGenerator, treeNode);
78
+ const role = `You are a collaborative agent who interacts with a JSON tree by performing edits to achieve a user-specified goal.${appGuidance === undefined
79
+ ? ""
80
+ : `
81
+ The application that owns the JSON tree has the following guidance about your role: ${appGuidance}`}`;
82
+ const treeSchemaString = createZodJsonValidator(...generateGenericEditTypes(getSimpleSchema(schema), false)).getSchemaText();
83
+ // TODO: security: user prompt in system prompt
84
+ const systemPrompt = `
85
+ ${role}
86
+ Edits are JSON objects that conform to the following schema.
87
+ The top level object you produce is an "EditWrapper" object which contains one of "Insert", "Modify", "Remove", "Move", or null.
88
+ ${treeSchemaString}
89
+ The tree is a JSON object with the following schema: ${promptFriendlySchema}
90
+ ${plan === undefined ? "" : `You have made a plan to accomplish the user's goal. The plan is: "${plan}". You will perform one or more edits that correspond to that plan to accomplish the goal.`}
91
+ ${log.length === 0
92
+ ? ""
93
+ : `You have already performed the following edits:
94
+ ${createEditListHistoryPrompt(log)}
95
+ This means that the current state of the tree reflects these changes.`}
96
+ The current state of the tree is: ${decoratedTreeJson}.
97
+ ${log.length > 0 ? "Before you made the above edits t" : "T"}he user requested you accomplish the following goal:
98
+ "${userPrompt}"
99
+ If the goal is now completed or is impossible, you should return null.
100
+ Otherwise, you should create an edit that makes progress towards the goal. It should have an English description ("explanation") of which edit to perform (specifying one of the allowed edit types).`;
101
+ return systemPrompt;
102
+ }
103
+ /**
104
+ * Generates a prompt designed to make an LLM review the edits it created and applied to a SharedTree based
105
+ * on a user-specified goal. This prompt is designed to give the LLM's ability to correct for mistakes and improve the accuracy/fidelity of its final set of tree edits
106
+ */
107
+ export function getReviewSystemPrompt(userPrompt, idGenerator, treeNode, originalDecoratedJson, appGuidance) {
108
+ const schema = Tree.schema(treeNode);
109
+ const promptFriendlySchema = getPromptFriendlyTreeSchema(getJsonSchema(schema));
110
+ const decoratedTreeJson = toDecoratedJson(idGenerator, treeNode);
111
+ const role = `You are a collaborative agent who interacts with a JSON tree by performing edits to achieve a user-specified goal.${appGuidance === undefined
112
+ ? ""
113
+ : `
114
+ The application that owns the JSON tree has the following guidance: ${appGuidance}`}`;
115
+ // TODO: security: user prompt in system prompt
116
+ const systemPrompt = `
117
+ ${role}
118
+ You have performed a number of actions already to accomplish a user request.
119
+ You must review the resulting state to determine if the actions you performed successfully accomplished the user's goal.
120
+ The tree is a JSON object with the following schema: ${promptFriendlySchema}
121
+ The state of the tree BEFORE changes was: ${originalDecoratedJson}.
122
+ The state of the tree AFTER changes is: ${decoratedTreeJson}.
123
+ The user requested that the following goal should be accomplished:
124
+ ${userPrompt}
125
+ Was the goal accomplished?`;
126
+ return systemPrompt;
127
+ }
128
+ /**
129
+ * Converts a fully-qualified SharedTree schema name to a single-word name for use in textual TypeScript-style types.
130
+ *
131
+ * @remarks
132
+ * - TODO: Determine what to do with user-provided names that include periods (e.g. "Foo.Bar").
133
+ * - TODO: Should probably ensure name starts with an uppercase character.
134
+ */
135
+ export function getPromptFriendlyTreeSchema(jsonSchema) {
136
+ let stringifiedSchema = "";
137
+ for (const [name, def] of Object.entries(jsonSchema.$defs)) {
138
+ if (def.type !== "object" || def._treeNodeSchemaKind === NodeKind.Map) {
139
+ continue;
140
+ }
141
+ let stringifiedEntry = `interface ${getFriendlySchemaName(name)} {`;
142
+ for (const [fieldName, fieldSchema] of Object.entries(def.properties)) {
143
+ let typeString;
144
+ if (isJsonSchemaRef(fieldSchema)) {
145
+ const nextFieldName = fieldSchema.$ref;
146
+ const nextDef = getDef(jsonSchema.$defs, nextFieldName);
147
+ typeString = `${getTypeString(jsonSchema.$defs, [nextFieldName, nextDef])}`;
148
+ }
149
+ else {
150
+ typeString = `${getAnyOfTypeString(jsonSchema.$defs, fieldSchema.anyOf, true)}`;
151
+ }
152
+ if (def.required && !def.required.includes(fieldName)) {
153
+ typeString = `${typeString} | undefined`;
154
+ }
155
+ stringifiedEntry += ` ${fieldName}: ${typeString};`;
156
+ }
157
+ stringifiedEntry += " }";
158
+ stringifiedSchema += (stringifiedSchema === "" ? "" : " ") + stringifiedEntry;
159
+ }
160
+ return stringifiedSchema;
161
+ }
162
+ function getTypeString(defs, [name, currentDef]) {
163
+ const { _treeNodeSchemaKind } = currentDef;
164
+ if (_treeNodeSchemaKind === NodeKind.Leaf) {
165
+ return currentDef.type;
166
+ }
167
+ if (_treeNodeSchemaKind === NodeKind.Object) {
168
+ return getFriendlySchemaName(name);
169
+ }
170
+ if (_treeNodeSchemaKind === NodeKind.Array) {
171
+ const items = currentDef.items;
172
+ const innerType = isJsonSchemaRef(items)
173
+ ? getTypeString(defs, [items.$ref, getDef(defs, items.$ref)])
174
+ : getAnyOfTypeString(defs, items.anyOf);
175
+ return `${innerType}[]`;
176
+ }
177
+ fail("Non-object, non-leaf, non-array schema type.");
178
+ }
179
+ function getAnyOfTypeString(defs, refList, topLevel = false) {
180
+ const typeNames = [];
181
+ for (const ref of refList) {
182
+ typeNames.push(getTypeString(defs, [ref.$ref, getDef(defs, ref.$ref)]));
183
+ }
184
+ const typeString = typeNames.join(" | ");
185
+ return topLevel ? typeString : `(${typeString})`;
186
+ }
187
+ function isJsonSchemaRef(field) {
188
+ return field.$ref !== undefined;
189
+ }
190
+ function getDef(defs, ref) {
191
+ // strip the "#/$defs/" prefix
192
+ const strippedRef = ref.slice(8);
193
+ const nextDef = defs[strippedRef];
194
+ assert(nextDef !== undefined, "Ref not found.");
195
+ return nextDef;
196
+ }
197
+ /**
198
+ * TBD
199
+ */
200
+ export function getFriendlySchemaName(schemaName) {
201
+ const matches = schemaName.match(/[^.]+$/);
202
+ if (matches === null) {
203
+ // empty scope
204
+ return schemaName;
205
+ }
206
+ return matches[0];
207
+ }
208
+ //# sourceMappingURL=promptGeneration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promptGeneration.js","sourceRoot":"","sources":["../../src/explicit-strategy/promptGeneration.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 { assert } from \"@fluidframework/core-utils/internal\";\nimport {\n\tNodeKind,\n\ttype ImplicitFieldSchema,\n\ttype TreeFieldFromImplicitField,\n\tgetJsonSchema,\n\ttype JsonFieldSchema,\n\ttype JsonNodeSchema,\n\ttype JsonSchemaRef,\n\ttype JsonTreeSchema,\n\tgetSimpleSchema,\n\tTree,\n\ttype TreeNode,\n} from \"@fluidframework/tree/internal\";\n// eslint-disable-next-line import/no-internal-modules\nimport { createZodJsonValidator } from \"typechat/zod\";\n\nimport { objectIdKey, type TreeEdit } from \"./agentEditTypes.js\";\nimport type { IdGenerator } from \"./idGenerator.js\";\nimport { generateGenericEditTypes } from \"./typeGeneration.js\";\nimport { fail } from \"./utils.js\";\n\n/**\n * A log of edits that have been made to a tree.\n * @remarks This is primarily used to help an LLM keep track of the active changes it has made.\n */\nexport type EditLog = {\n\tedit: TreeEdit;\n\terror?: string;\n}[];\n\n/**\n * TBD\n */\nexport function toDecoratedJson(\n\tidGenerator: IdGenerator,\n\troot: TreeFieldFromImplicitField<ImplicitFieldSchema>,\n): string {\n\tidGenerator.assignIds(root);\n\tconst stringified: string = JSON.stringify(root, (_, value) => {\n\t\tif (typeof value === \"object\" && !Array.isArray(value) && value !== null) {\n\t\t\t// TODO: SharedTree Team needs to either publish TreeNode as a class to use .instanceof() or a typeguard.\n\t\t\t// Uncomment this assertion back once we have a typeguard ready.\n\t\t\t// assert(isTreeNode(node), \"Non-TreeNode value in tree.\");\n\t\t\tconst objId =\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\t\tidGenerator.getId(value) ?? fail(\"ID of new node should have been assigned.\");\n\t\t\tassert(\n\t\t\t\t!Object.prototype.hasOwnProperty.call(value, objectIdKey),\n\t\t\t\t`Collision of object id property.`,\n\t\t\t);\n\t\t\treturn {\n\t\t\t\t[objectIdKey]: objId,\n\t\t\t\t...value,\n\t\t\t} as unknown;\n\t\t}\n\t\treturn value as unknown;\n\t});\n\treturn stringified;\n}\n\n/**\n * Generates a prompt designed to make an LLM produce a plan to edit the SharedTree to accomplish a user-specified goal.\n */\nexport function getPlanningSystemPrompt(\n\ttreeNode: TreeNode,\n\tuserPrompt: string,\n\tsystemRoleContext?: string,\n): string {\n\tconst schema = Tree.schema(treeNode);\n\n\tconst promptFriendlySchema = getPromptFriendlyTreeSchema(getJsonSchema(schema));\n\tconst role = `I'm an agent who makes plans for another agent to achieve a user-specified goal to update the state of an application.${\n\t\tsystemRoleContext === undefined\n\t\t\t? \"\"\n\t\t\t: `\n\t\t\tThe other agent follows this guidance: ${systemRoleContext}`\n\t}`;\n\n\tconst systemPrompt = `\n\t${role}\n\tThe application state tree is a JSON object with the following schema: ${promptFriendlySchema}\n\tThe current state is: ${JSON.stringify(treeNode)}.\n\tThe user requested that I accomplish the following goal:\n\t\"${userPrompt}\"\n\tI've made a plan to accomplish this goal by doing a sequence of edits to the tree.\n\tEdits can include setting the root, inserting, modifying, removing, or moving elements in the tree.\n\tHere is my plan:`;\n\n\treturn systemPrompt;\n}\n\n/**\n * Generates a prompt that provides a history of the edits an LLM has made to a SharedTree as well as any errors that occured from attemping to apply each respsecitve edit to the tree.\n */\nexport function createEditListHistoryPrompt(edits: EditLog): string {\n\treturn edits\n\t\t.map((edit, index) => {\n\t\t\tconst error =\n\t\t\t\tedit.error === undefined\n\t\t\t\t\t? \"\"\n\t\t\t\t\t: ` This edit produced an error, and was discarded. The error message was: \"${edit.error}\"`;\n\t\t\treturn `${index + 1}. ${JSON.stringify(edit.edit)}${error}`;\n\t\t})\n\t\t.join(\"\\n\");\n}\n\n/**\n * Generates the main prompt of this explicit strategy.\n * This prompt is designed to give an LLM instructions on how it can modify a SharedTree using specific types of {@link TreeEdit}'s\n * and provides with both a serialized version of the current state of the provided tree node as well as the interfaces that compromise said tree nodes data.\n */\nexport function getEditingSystemPrompt(\n\tuserPrompt: string,\n\tidGenerator: IdGenerator,\n\ttreeNode: TreeNode,\n\tlog: EditLog,\n\tappGuidance?: string,\n\tplan?: string,\n): string {\n\tconst schema = Tree.schema(treeNode);\n\tconst promptFriendlySchema = getPromptFriendlyTreeSchema(getJsonSchema(schema));\n\tconst decoratedTreeJson = toDecoratedJson(idGenerator, treeNode);\n\n\tconst role = `You are a collaborative agent who interacts with a JSON tree by performing edits to achieve a user-specified goal.${\n\t\tappGuidance === undefined\n\t\t\t? \"\"\n\t\t\t: `\n\t\t\tThe application that owns the JSON tree has the following guidance about your role: ${appGuidance}`\n\t}`;\n\n\tconst treeSchemaString = createZodJsonValidator(\n\t\t...generateGenericEditTypes(getSimpleSchema(schema), false),\n\t).getSchemaText();\n\n\t// TODO: security: user prompt in system prompt\n\tconst systemPrompt = `\n\t${role}\n\tEdits are JSON objects that conform to the following schema.\n\tThe top level object you produce is an \"EditWrapper\" object which contains one of \"Insert\", \"Modify\", \"Remove\", \"Move\", or null.\n\t${treeSchemaString}\n\tThe tree is a JSON object with the following schema: ${promptFriendlySchema}\n\t${plan === undefined ? \"\" : `You have made a plan to accomplish the user's goal. The plan is: \"${plan}\". You will perform one or more edits that correspond to that plan to accomplish the goal.`}\n\t${\n\t\tlog.length === 0\n\t\t\t? \"\"\n\t\t\t: `You have already performed the following edits:\n\t\t\t${createEditListHistoryPrompt(log)}\n\t\t\tThis means that the current state of the tree reflects these changes.`\n\t}\n\tThe current state of the tree is: ${decoratedTreeJson}.\n\t${log.length > 0 ? \"Before you made the above edits t\" : \"T\"}he user requested you accomplish the following goal:\n\t\"${userPrompt}\"\n\tIf the goal is now completed or is impossible, you should return null.\n\tOtherwise, you should create an edit that makes progress towards the goal. It should have an English description (\"explanation\") of which edit to perform (specifying one of the allowed edit types).`;\n\treturn systemPrompt;\n}\n\n/**\n * Generates a prompt designed to make an LLM review the edits it created and applied to a SharedTree based\n * on a user-specified goal. This prompt is designed to give the LLM's ability to correct for mistakes and improve the accuracy/fidelity of its final set of tree edits\n */\nexport function getReviewSystemPrompt(\n\tuserPrompt: string,\n\tidGenerator: IdGenerator,\n\ttreeNode: TreeNode,\n\toriginalDecoratedJson: string,\n\tappGuidance?: string,\n): string {\n\tconst schema = Tree.schema(treeNode);\n\tconst promptFriendlySchema = getPromptFriendlyTreeSchema(getJsonSchema(schema));\n\tconst decoratedTreeJson = toDecoratedJson(idGenerator, treeNode);\n\n\tconst role = `You are a collaborative agent who interacts with a JSON tree by performing edits to achieve a user-specified goal.${\n\t\tappGuidance === undefined\n\t\t\t? \"\"\n\t\t\t: `\n\t\t\tThe application that owns the JSON tree has the following guidance: ${appGuidance}`\n\t}`;\n\n\t// TODO: security: user prompt in system prompt\n\tconst systemPrompt = `\n\t${role}\n\tYou have performed a number of actions already to accomplish a user request.\n\tYou must review the resulting state to determine if the actions you performed successfully accomplished the user's goal.\n\tThe tree is a JSON object with the following schema: ${promptFriendlySchema}\n\tThe state of the tree BEFORE changes was: ${originalDecoratedJson}.\n\tThe state of the tree AFTER changes is: ${decoratedTreeJson}.\n\tThe user requested that the following goal should be accomplished:\n\t${userPrompt}\n\tWas the goal accomplished?`;\n\treturn systemPrompt;\n}\n\n/**\n * Converts a fully-qualified SharedTree schema name to a single-word name for use in textual TypeScript-style types.\n *\n * @remarks\n * - TODO: Determine what to do with user-provided names that include periods (e.g. \"Foo.Bar\").\n * - TODO: Should probably ensure name starts with an uppercase character.\n */\nexport function getPromptFriendlyTreeSchema(jsonSchema: JsonTreeSchema): string {\n\tlet stringifiedSchema = \"\";\n\tfor (const [name, def] of Object.entries(jsonSchema.$defs)) {\n\t\tif (def.type !== \"object\" || def._treeNodeSchemaKind === NodeKind.Map) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tlet stringifiedEntry = `interface ${getFriendlySchemaName(name)} {`;\n\n\t\tfor (const [fieldName, fieldSchema] of Object.entries(def.properties)) {\n\t\t\tlet typeString: string;\n\t\t\tif (isJsonSchemaRef(fieldSchema)) {\n\t\t\t\tconst nextFieldName = fieldSchema.$ref;\n\t\t\t\tconst nextDef = getDef(jsonSchema.$defs, nextFieldName);\n\t\t\t\ttypeString = `${getTypeString(jsonSchema.$defs, [nextFieldName, nextDef])}`;\n\t\t\t} else {\n\t\t\t\ttypeString = `${getAnyOfTypeString(jsonSchema.$defs, fieldSchema.anyOf, true)}`;\n\t\t\t}\n\t\t\tif (def.required && !def.required.includes(fieldName)) {\n\t\t\t\ttypeString = `${typeString} | undefined`;\n\t\t\t}\n\t\t\tstringifiedEntry += ` ${fieldName}: ${typeString};`;\n\t\t}\n\n\t\tstringifiedEntry += \" }\";\n\n\t\tstringifiedSchema += (stringifiedSchema === \"\" ? \"\" : \" \") + stringifiedEntry;\n\t}\n\treturn stringifiedSchema;\n}\n\nfunction getTypeString(\n\tdefs: Record<string, JsonNodeSchema>,\n\t[name, currentDef]: [string, JsonNodeSchema],\n): string {\n\tconst { _treeNodeSchemaKind } = currentDef;\n\tif (_treeNodeSchemaKind === NodeKind.Leaf) {\n\t\treturn currentDef.type;\n\t}\n\tif (_treeNodeSchemaKind === NodeKind.Object) {\n\t\treturn getFriendlySchemaName(name);\n\t}\n\tif (_treeNodeSchemaKind === NodeKind.Array) {\n\t\tconst items = currentDef.items;\n\t\tconst innerType = isJsonSchemaRef(items)\n\t\t\t? getTypeString(defs, [items.$ref, getDef(defs, items.$ref)])\n\t\t\t: getAnyOfTypeString(defs, items.anyOf);\n\t\treturn `${innerType}[]`;\n\t}\n\tfail(\"Non-object, non-leaf, non-array schema type.\");\n}\n\nfunction getAnyOfTypeString(\n\tdefs: Record<string, JsonNodeSchema>,\n\trefList: JsonSchemaRef[],\n\ttopLevel = false,\n): string {\n\tconst typeNames: string[] = [];\n\tfor (const ref of refList) {\n\t\ttypeNames.push(getTypeString(defs, [ref.$ref, getDef(defs, ref.$ref)]));\n\t}\n\tconst typeString = typeNames.join(\" | \");\n\treturn topLevel ? typeString : `(${typeString})`;\n}\n\nfunction isJsonSchemaRef(field: JsonFieldSchema): field is JsonSchemaRef {\n\treturn (field as JsonSchemaRef).$ref !== undefined;\n}\n\nfunction getDef(defs: Record<string, JsonNodeSchema>, ref: string): JsonNodeSchema {\n\t// strip the \"#/$defs/\" prefix\n\tconst strippedRef = ref.slice(8);\n\tconst nextDef = defs[strippedRef];\n\tassert(nextDef !== undefined, \"Ref not found.\");\n\treturn nextDef;\n}\n\n/**\n * TBD\n */\nexport function getFriendlySchemaName(schemaName: string): string {\n\tconst matches = schemaName.match(/[^.]+$/);\n\tif (matches === null) {\n\t\t// empty scope\n\t\treturn schemaName;\n\t}\n\treturn matches[0];\n}\n"]}
@@ -0,0 +1,15 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import type { SimpleTreeSchema } from "@fluidframework/tree/internal";
6
+ /**
7
+ * Generates a set of ZOD validation objects for the various types of data that can be put into the provided {@link SimpleTreeSchema}
8
+ * and then uses those sets to generate an all-encompassing ZOD object for each type of {@link TreeEdit} that can validate any of the types of data that can be put into the tree.
9
+ *
10
+ * @returns a Record of schema names to Zod validation objects, and the name of the root schema used to encompass all of the other schemas.
11
+ *
12
+ * @remarks The return type of this function is designed to work with Typechat's createZodJsonValidator as well as be used as the JSON schema for OpenAi's structured output response format.
13
+ */
14
+ export declare function generateGenericEditTypes(schema: SimpleTreeSchema, generateDomainTypes: boolean): [Record<string, Zod.ZodTypeAny>, root: string];
15
+ //# sourceMappingURL=typeGeneration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typeGeneration.d.ts","sourceRoot":"","sources":["../../src/explicit-strategy/typeGeneration.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAGX,gBAAgB,EAChB,MAAM,+BAA+B,CAAC;AA2EvC;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACvC,MAAM,EAAE,gBAAgB,EACxB,mBAAmB,EAAE,OAAO,GAC1B,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CA4FhD"}
@@ -0,0 +1,260 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { assert } from "@fluidframework/core-utils/internal";
6
+ import { FieldKind, NodeKind, ValueSchema } from "@fluidframework/tree/internal";
7
+ import { z } from "zod";
8
+ import { objectIdKey, typeField } from "./agentEditTypes.js";
9
+ import { fail, getOrCreate, mapIterable } from "./utils.js";
10
+ /**
11
+ * Zod Object type used to represent & validate the ObjectTarget type within a {@link TreeEdit}.
12
+ * @remarks this is used as a component with {@link generateGenericEditTypes} to produce the final zod validation objects.
13
+ */
14
+ const objectTarget = z.object({
15
+ target: z
16
+ .string()
17
+ .describe(`The id of the object (as specified by the object's ${objectIdKey} property) that is being referenced`),
18
+ });
19
+ /**
20
+ * Zod Object type used to represent & validate the ObjectPlace type within a {@link TreeEdit}.
21
+ * @remarks this is used as a component with {@link generateGenericEditTypes} to produce the final zod validation objects.
22
+ */
23
+ const objectPlace = z
24
+ .object({
25
+ type: z.enum(["objectPlace"]),
26
+ target: z
27
+ .string()
28
+ .describe(`The id (${objectIdKey}) of the object that the new/moved object should be placed relative to. This must be the id of an object that already existed in the tree content that was originally supplied.`),
29
+ place: z
30
+ .enum(["before", "after"])
31
+ .describe("Where the new/moved object will be relative to the target object - either just before or just after"),
32
+ })
33
+ .describe("A pointer to a location either just before or just after an object that is in an array");
34
+ /**
35
+ * Zod Object type used to represent & validate the ArrayPlace type within a {@link TreeEdit}.
36
+ * @remarks this is used as a component with {@link generateGenericEditTypes} to produce the final zod validation objects.
37
+ */
38
+ const arrayPlace = z
39
+ .object({
40
+ type: z.enum(["arrayPlace"]),
41
+ parentId: z
42
+ .string()
43
+ .describe(`The id (${objectIdKey}) of the parent object of the array. This must be the id of an object that already existed in the tree content that was originally supplied.`),
44
+ field: z.string().describe("The key of the array to insert into"),
45
+ location: z
46
+ .enum(["start", "end"])
47
+ .describe("Where to insert into the array - either the start or the end"),
48
+ })
49
+ .describe(`either the "start" or "end" of an array, as specified by a "parent" ObjectTarget and a "field" name under which the array is stored (useful for prepending or appending)`);
50
+ /**
51
+ * Zod Object type used to represent & validate the Range type within a {@link TreeEdit}.
52
+ * @remarks this is used as a component with {@link generateGenericEditTypes} to produce the final zod validation objects.
53
+ */
54
+ const range = z
55
+ .object({
56
+ from: objectPlace,
57
+ to: objectPlace,
58
+ })
59
+ .describe('A range of objects in the same array specified by a "from" and "to" Place. The "to" and "from" objects MUST be in the same array.');
60
+ /**
61
+ * Cache used to prevent repeatedly generating the same Zod validation objects for the same {@link SimpleTreeSchema} as generate propts for repeated calls to an LLM
62
+ */
63
+ const cache = new WeakMap();
64
+ /**
65
+ * Generates a set of ZOD validation objects for the various types of data that can be put into the provided {@link SimpleTreeSchema}
66
+ * and then uses those sets to generate an all-encompassing ZOD object for each type of {@link TreeEdit} that can validate any of the types of data that can be put into the tree.
67
+ *
68
+ * @returns a Record of schema names to Zod validation objects, and the name of the root schema used to encompass all of the other schemas.
69
+ *
70
+ * @remarks The return type of this function is designed to work with Typechat's createZodJsonValidator as well as be used as the JSON schema for OpenAi's structured output response format.
71
+ */
72
+ export function generateGenericEditTypes(schema, generateDomainTypes) {
73
+ return getOrCreate(cache, schema, () => {
74
+ const insertSet = new Set();
75
+ const modifyFieldSet = new Set();
76
+ const modifyTypeSet = new Set();
77
+ const typeMap = new Map();
78
+ for (const name of schema.definitions.keys()) {
79
+ getOrCreateType(schema.definitions, typeMap, insertSet, modifyFieldSet, modifyTypeSet, name);
80
+ }
81
+ function getType(allowedTypes) {
82
+ switch (allowedTypes.size) {
83
+ case 0: {
84
+ return z.never();
85
+ }
86
+ case 1: {
87
+ return (typeMap.get(tryGetSingleton(allowedTypes) ?? fail("Expected singleton")) ??
88
+ fail("Unknown type"));
89
+ }
90
+ default: {
91
+ const types = Array.from(allowedTypes, (name) => typeMap.get(name) ?? fail("Unknown type"));
92
+ assert(hasAtLeastTwo(types), "Expected at least two types");
93
+ return z.union(types);
94
+ }
95
+ }
96
+ }
97
+ const insert = z
98
+ .object({
99
+ type: z.literal("insert"),
100
+ explanation: z.string().describe(editDescription),
101
+ content: generateDomainTypes
102
+ ? getType(insertSet)
103
+ : z.any().describe("Domain-specific content here"),
104
+ destination: z.union([arrayPlace, objectPlace]),
105
+ })
106
+ .describe("Inserts a new object at a specific Place or ArrayPlace.");
107
+ const remove = z
108
+ .object({
109
+ type: z.literal("remove"),
110
+ explanation: z.string().describe(editDescription),
111
+ source: z.union([objectTarget, range]),
112
+ })
113
+ .describe("Deletes an object or Range of objects from the tree.");
114
+ const move = z
115
+ .object({
116
+ type: z.literal("move"),
117
+ explanation: z.string().describe(editDescription),
118
+ source: z.union([objectTarget, range]),
119
+ destination: z.union([arrayPlace, objectPlace]),
120
+ })
121
+ .describe("Moves an object or Range of objects to a new Place or ArrayPlace.");
122
+ const modify = z
123
+ .object({
124
+ type: z.enum(["modify"]),
125
+ explanation: z.string().describe(editDescription),
126
+ target: objectTarget,
127
+ field: z.enum([...modifyFieldSet]), // Modify with appropriate fields
128
+ modification: generateDomainTypes
129
+ ? getType(modifyTypeSet)
130
+ : z.any().describe("Domain-specific content here"),
131
+ })
132
+ .describe("Sets a field on a specific ObjectTarget.");
133
+ const editTypes = [insert, remove, move, modify, z.null()];
134
+ const editWrapper = z.object({
135
+ edit: z
136
+ .union(editTypes)
137
+ .describe("The next edit to apply to the tree, or null if the task is complete."),
138
+ });
139
+ const typeRecord = {
140
+ ObjectTarget: objectTarget,
141
+ ObjectPlace: objectPlace,
142
+ ArrayPlace: arrayPlace,
143
+ Range: range,
144
+ Insert: insert,
145
+ Remove: remove,
146
+ Move: move,
147
+ Modify: modify,
148
+ EditWrapper: editWrapper,
149
+ };
150
+ return [typeRecord, "EditWrapper"];
151
+ });
152
+ }
153
+ const editDescription = "A description of what this edit is meant to accomplish in human readable English";
154
+ function getOrCreateType(definitionMap, typeMap, insertSet, modifyFieldSet, modifyTypeSet, definition) {
155
+ return getOrCreate(typeMap, definition, () => {
156
+ const nodeSchema = definitionMap.get(definition) ?? fail("Unexpected definition");
157
+ switch (nodeSchema.kind) {
158
+ case NodeKind.Object: {
159
+ for (const [key, field] of Object.entries(nodeSchema.fields)) {
160
+ // TODO: Remove when AI better
161
+ if (Array.from(field.allowedTypes, (n) => definitionMap.get(n) ?? fail("Unknown definition")).some((n) => n.kind === NodeKind.Array)) {
162
+ continue;
163
+ }
164
+ modifyFieldSet.add(key);
165
+ for (const type of field.allowedTypes) {
166
+ modifyTypeSet.add(type);
167
+ }
168
+ }
169
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
170
+ const properties = Object.fromEntries(Object.entries(nodeSchema.fields)
171
+ .map(([key, field]) => {
172
+ return [
173
+ key,
174
+ getOrCreateTypeForField(definitionMap, typeMap, insertSet, modifyFieldSet, modifyTypeSet, field),
175
+ ];
176
+ })
177
+ .filter(([, value]) => value !== undefined));
178
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
179
+ properties[typeField] = z.enum([definition]);
180
+ return z.object(properties);
181
+ }
182
+ case NodeKind.Array: {
183
+ for (const [name] of Array.from(nodeSchema.allowedTypes, (n) => [
184
+ n,
185
+ definitionMap.get(n) ?? fail("Unknown definition"),
186
+ ]).filter(([_, schema]) => schema.kind === NodeKind.Object || schema.kind === NodeKind.Leaf)) {
187
+ insertSet.add(name);
188
+ }
189
+ return z.array(getTypeForAllowedTypes(definitionMap, typeMap, insertSet, modifyFieldSet, modifyTypeSet, nodeSchema.allowedTypes));
190
+ }
191
+ case NodeKind.Leaf: {
192
+ switch (nodeSchema.leafKind) {
193
+ case ValueSchema.Boolean: {
194
+ return z.boolean();
195
+ }
196
+ case ValueSchema.Number: {
197
+ return z.number();
198
+ }
199
+ case ValueSchema.String: {
200
+ return z.string();
201
+ }
202
+ case ValueSchema.Null: {
203
+ return z.null();
204
+ }
205
+ default: {
206
+ throw new Error(`Unsupported leaf kind ${NodeKind[nodeSchema.leafKind]}.`);
207
+ }
208
+ }
209
+ }
210
+ default: {
211
+ throw new Error(`Unsupported node kind ${NodeKind[nodeSchema.kind]}.`);
212
+ }
213
+ }
214
+ });
215
+ }
216
+ function getOrCreateTypeForField(definitionMap, typeMap, insertSet, modifyFieldSet, modifyTypeSet, fieldSchema) {
217
+ switch (fieldSchema.kind) {
218
+ case FieldKind.Required: {
219
+ return getTypeForAllowedTypes(definitionMap, typeMap, insertSet, modifyFieldSet, modifyTypeSet, fieldSchema.allowedTypes);
220
+ }
221
+ case FieldKind.Optional: {
222
+ return z.union([
223
+ z.null(),
224
+ getTypeForAllowedTypes(definitionMap, typeMap, insertSet, modifyFieldSet, modifyTypeSet, fieldSchema.allowedTypes),
225
+ ]);
226
+ }
227
+ case FieldKind.Identifier: {
228
+ return undefined;
229
+ }
230
+ default: {
231
+ throw new Error(`Unsupported field kind ${NodeKind[fieldSchema.kind]}.`);
232
+ }
233
+ }
234
+ }
235
+ function getTypeForAllowedTypes(definitionMap, typeMap, insertSet, modifyFieldSet, modifyTypeSet, allowedTypes) {
236
+ const single = tryGetSingleton(allowedTypes);
237
+ if (single === undefined) {
238
+ const types = [
239
+ ...mapIterable(allowedTypes, (name) => {
240
+ return getOrCreateType(definitionMap, typeMap, insertSet, modifyFieldSet, modifyTypeSet, name);
241
+ }),
242
+ ];
243
+ assert(hasAtLeastTwo(types), "Expected at least two types");
244
+ return z.union(types);
245
+ }
246
+ else {
247
+ return getOrCreateType(definitionMap, typeMap, insertSet, modifyFieldSet, modifyTypeSet, single);
248
+ }
249
+ }
250
+ function tryGetSingleton(set) {
251
+ if (set.size === 1) {
252
+ for (const item of set) {
253
+ return item;
254
+ }
255
+ }
256
+ }
257
+ function hasAtLeastTwo(array) {
258
+ return array.length >= 2;
259
+ }
260
+ //# sourceMappingURL=typeGeneration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typeGeneration.js","sourceRoot":"","sources":["../../src/explicit-strategy/typeGeneration.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 { assert } from \"@fluidframework/core-utils/internal\";\nimport { FieldKind, NodeKind, ValueSchema } from \"@fluidframework/tree/internal\";\nimport type {\n\tSimpleFieldSchema,\n\tSimpleNodeSchema,\n\tSimpleTreeSchema,\n} from \"@fluidframework/tree/internal\";\nimport { z } from \"zod\";\n\nimport { objectIdKey, typeField } from \"./agentEditTypes.js\";\nimport { fail, getOrCreate, mapIterable } from \"./utils.js\";\n\n/**\n * Zod Object type used to represent & validate the ObjectTarget type within a {@link TreeEdit}.\n * @remarks this is used as a component with {@link generateGenericEditTypes} to produce the final zod validation objects.\n */\nconst objectTarget = z.object({\n\ttarget: z\n\t\t.string()\n\t\t.describe(\n\t\t\t`The id of the object (as specified by the object's ${objectIdKey} property) that is being referenced`,\n\t\t),\n});\n/**\n * Zod Object type used to represent & validate the ObjectPlace type within a {@link TreeEdit}.\n * @remarks this is used as a component with {@link generateGenericEditTypes} to produce the final zod validation objects.\n */\nconst objectPlace = z\n\t.object({\n\t\ttype: z.enum([\"objectPlace\"]),\n\t\ttarget: z\n\t\t\t.string()\n\t\t\t.describe(\n\t\t\t\t`The id (${objectIdKey}) of the object that the new/moved object should be placed relative to. This must be the id of an object that already existed in the tree content that was originally supplied.`,\n\t\t\t),\n\t\tplace: z\n\t\t\t.enum([\"before\", \"after\"])\n\t\t\t.describe(\n\t\t\t\t\"Where the new/moved object will be relative to the target object - either just before or just after\",\n\t\t\t),\n\t})\n\t.describe(\n\t\t\"A pointer to a location either just before or just after an object that is in an array\",\n\t);\n/**\n * Zod Object type used to represent & validate the ArrayPlace type within a {@link TreeEdit}.\n * @remarks this is used as a component with {@link generateGenericEditTypes} to produce the final zod validation objects.\n */\nconst arrayPlace = z\n\t.object({\n\t\ttype: z.enum([\"arrayPlace\"]),\n\t\tparentId: z\n\t\t\t.string()\n\t\t\t.describe(\n\t\t\t\t`The id (${objectIdKey}) of the parent object of the array. This must be the id of an object that already existed in the tree content that was originally supplied.`,\n\t\t\t),\n\t\tfield: z.string().describe(\"The key of the array to insert into\"),\n\t\tlocation: z\n\t\t\t.enum([\"start\", \"end\"])\n\t\t\t.describe(\"Where to insert into the array - either the start or the end\"),\n\t})\n\t.describe(\n\t\t`either the \"start\" or \"end\" of an array, as specified by a \"parent\" ObjectTarget and a \"field\" name under which the array is stored (useful for prepending or appending)`,\n\t);\n/**\n * Zod Object type used to represent & validate the Range type within a {@link TreeEdit}.\n * @remarks this is used as a component with {@link generateGenericEditTypes} to produce the final zod validation objects.\n */\nconst range = z\n\t.object({\n\t\tfrom: objectPlace,\n\t\tto: objectPlace,\n\t})\n\t.describe(\n\t\t'A range of objects in the same array specified by a \"from\" and \"to\" Place. The \"to\" and \"from\" objects MUST be in the same array.',\n\t);\n/**\n * Cache used to prevent repeatedly generating the same Zod validation objects for the same {@link SimpleTreeSchema} as generate propts for repeated calls to an LLM\n */\nconst cache = new WeakMap<SimpleTreeSchema, ReturnType<typeof generateGenericEditTypes>>();\n\n/**\n * Generates a set of ZOD validation objects for the various types of data that can be put into the provided {@link SimpleTreeSchema}\n * and then uses those sets to generate an all-encompassing ZOD object for each type of {@link TreeEdit} that can validate any of the types of data that can be put into the tree.\n *\n * @returns a Record of schema names to Zod validation objects, and the name of the root schema used to encompass all of the other schemas.\n *\n * @remarks The return type of this function is designed to work with Typechat's createZodJsonValidator as well as be used as the JSON schema for OpenAi's structured output response format.\n */\nexport function generateGenericEditTypes(\n\tschema: SimpleTreeSchema,\n\tgenerateDomainTypes: boolean,\n): [Record<string, Zod.ZodTypeAny>, root: string] {\n\treturn getOrCreate(cache, schema, () => {\n\t\tconst insertSet = new Set<string>();\n\t\tconst modifyFieldSet = new Set<string>();\n\t\tconst modifyTypeSet = new Set<string>();\n\t\tconst typeMap = new Map<string, Zod.ZodTypeAny>();\n\t\tfor (const name of schema.definitions.keys()) {\n\t\t\tgetOrCreateType(\n\t\t\t\tschema.definitions,\n\t\t\t\ttypeMap,\n\t\t\t\tinsertSet,\n\t\t\t\tmodifyFieldSet,\n\t\t\t\tmodifyTypeSet,\n\t\t\t\tname,\n\t\t\t);\n\t\t}\n\t\tfunction getType(allowedTypes: ReadonlySet<string>): Zod.ZodTypeAny {\n\t\t\tswitch (allowedTypes.size) {\n\t\t\t\tcase 0: {\n\t\t\t\t\treturn z.never();\n\t\t\t\t}\n\t\t\t\tcase 1: {\n\t\t\t\t\treturn (\n\t\t\t\t\t\ttypeMap.get(tryGetSingleton(allowedTypes) ?? fail(\"Expected singleton\")) ??\n\t\t\t\t\t\tfail(\"Unknown type\")\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst types = Array.from(\n\t\t\t\t\t\tallowedTypes,\n\t\t\t\t\t\t(name) => typeMap.get(name) ?? fail(\"Unknown type\"),\n\t\t\t\t\t);\n\t\t\t\t\tassert(hasAtLeastTwo(types), \"Expected at least two types\");\n\t\t\t\t\treturn z.union(types);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst insert = z\n\t\t\t.object({\n\t\t\t\ttype: z.literal(\"insert\"),\n\t\t\t\texplanation: z.string().describe(editDescription),\n\t\t\t\tcontent: generateDomainTypes\n\t\t\t\t\t? getType(insertSet)\n\t\t\t\t\t: z.any().describe(\"Domain-specific content here\"),\n\t\t\t\tdestination: z.union([arrayPlace, objectPlace]),\n\t\t\t})\n\t\t\t.describe(\"Inserts a new object at a specific Place or ArrayPlace.\");\n\t\tconst remove = z\n\t\t\t.object({\n\t\t\t\ttype: z.literal(\"remove\"),\n\t\t\t\texplanation: z.string().describe(editDescription),\n\t\t\t\tsource: z.union([objectTarget, range]),\n\t\t\t})\n\t\t\t.describe(\"Deletes an object or Range of objects from the tree.\");\n\t\tconst move = z\n\t\t\t.object({\n\t\t\t\ttype: z.literal(\"move\"),\n\t\t\t\texplanation: z.string().describe(editDescription),\n\t\t\t\tsource: z.union([objectTarget, range]),\n\t\t\t\tdestination: z.union([arrayPlace, objectPlace]),\n\t\t\t})\n\t\t\t.describe(\"Moves an object or Range of objects to a new Place or ArrayPlace.\");\n\t\tconst modify = z\n\t\t\t.object({\n\t\t\t\ttype: z.enum([\"modify\"]),\n\t\t\t\texplanation: z.string().describe(editDescription),\n\t\t\t\ttarget: objectTarget,\n\t\t\t\tfield: z.enum([...modifyFieldSet] as [string, ...string[]]), // Modify with appropriate fields\n\t\t\t\tmodification: generateDomainTypes\n\t\t\t\t\t? getType(modifyTypeSet)\n\t\t\t\t\t: z.any().describe(\"Domain-specific content here\"),\n\t\t\t})\n\t\t\t.describe(\"Sets a field on a specific ObjectTarget.\");\n\t\tconst editTypes = [insert, remove, move, modify, z.null()] as const;\n\t\tconst editWrapper = z.object({\n\t\t\tedit: z\n\t\t\t\t.union(editTypes)\n\t\t\t\t.describe(\"The next edit to apply to the tree, or null if the task is complete.\"),\n\t\t});\n\t\tconst typeRecord: Record<string, Zod.ZodTypeAny> = {\n\t\t\tObjectTarget: objectTarget,\n\t\t\tObjectPlace: objectPlace,\n\t\t\tArrayPlace: arrayPlace,\n\t\t\tRange: range,\n\t\t\tInsert: insert,\n\t\t\tRemove: remove,\n\t\t\tMove: move,\n\t\t\tModify: modify,\n\t\t\tEditWrapper: editWrapper,\n\t\t};\n\t\treturn [typeRecord, \"EditWrapper\"];\n\t});\n}\nconst editDescription =\n\t\"A description of what this edit is meant to accomplish in human readable English\";\nfunction getOrCreateType(\n\tdefinitionMap: ReadonlyMap<string, SimpleNodeSchema>,\n\ttypeMap: Map<string, Zod.ZodTypeAny>,\n\tinsertSet: Set<string>,\n\tmodifyFieldSet: Set<string>,\n\tmodifyTypeSet: Set<string>,\n\tdefinition: string,\n): Zod.ZodTypeAny {\n\treturn getOrCreate(typeMap, definition, () => {\n\t\tconst nodeSchema = definitionMap.get(definition) ?? fail(\"Unexpected definition\");\n\t\tswitch (nodeSchema.kind) {\n\t\t\tcase NodeKind.Object: {\n\t\t\t\tfor (const [key, field] of Object.entries(nodeSchema.fields)) {\n\t\t\t\t\t// TODO: Remove when AI better\n\t\t\t\t\tif (\n\t\t\t\t\t\tArray.from(\n\t\t\t\t\t\t\tfield.allowedTypes,\n\t\t\t\t\t\t\t(n) => definitionMap.get(n) ?? fail(\"Unknown definition\"),\n\t\t\t\t\t\t).some((n) => n.kind === NodeKind.Array)\n\t\t\t\t\t) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tmodifyFieldSet.add(key);\n\t\t\t\t\tfor (const type of field.allowedTypes) {\n\t\t\t\t\t\tmodifyTypeSet.add(type);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\t\tconst properties = Object.fromEntries(\n\t\t\t\t\tObject.entries(nodeSchema.fields)\n\t\t\t\t\t\t.map(([key, field]) => {\n\t\t\t\t\t\t\treturn [\n\t\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\t\tgetOrCreateTypeForField(\n\t\t\t\t\t\t\t\t\tdefinitionMap,\n\t\t\t\t\t\t\t\t\ttypeMap,\n\t\t\t\t\t\t\t\t\tinsertSet,\n\t\t\t\t\t\t\t\t\tmodifyFieldSet,\n\t\t\t\t\t\t\t\t\tmodifyTypeSet,\n\t\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t];\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.filter(([, value]) => value !== undefined),\n\t\t\t\t);\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\tproperties[typeField] = z.enum([definition]);\n\t\t\t\treturn z.object(properties);\n\t\t\t}\n\t\t\tcase NodeKind.Array: {\n\t\t\t\tfor (const [name] of Array.from(\n\t\t\t\t\tnodeSchema.allowedTypes,\n\t\t\t\t\t(n): [string, SimpleNodeSchema] => [\n\t\t\t\t\t\tn,\n\t\t\t\t\t\tdefinitionMap.get(n) ?? fail(\"Unknown definition\"),\n\t\t\t\t\t],\n\t\t\t\t).filter(\n\t\t\t\t\t([_, schema]) => schema.kind === NodeKind.Object || schema.kind === NodeKind.Leaf,\n\t\t\t\t)) {\n\t\t\t\t\tinsertSet.add(name);\n\t\t\t\t}\n\t\t\t\treturn z.array(\n\t\t\t\t\tgetTypeForAllowedTypes(\n\t\t\t\t\t\tdefinitionMap,\n\t\t\t\t\t\ttypeMap,\n\t\t\t\t\t\tinsertSet,\n\t\t\t\t\t\tmodifyFieldSet,\n\t\t\t\t\t\tmodifyTypeSet,\n\t\t\t\t\t\tnodeSchema.allowedTypes,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase NodeKind.Leaf: {\n\t\t\t\tswitch (nodeSchema.leafKind) {\n\t\t\t\t\tcase ValueSchema.Boolean: {\n\t\t\t\t\t\treturn z.boolean();\n\t\t\t\t\t}\n\t\t\t\t\tcase ValueSchema.Number: {\n\t\t\t\t\t\treturn z.number();\n\t\t\t\t\t}\n\t\t\t\t\tcase ValueSchema.String: {\n\t\t\t\t\t\treturn z.string();\n\t\t\t\t\t}\n\t\t\t\t\tcase ValueSchema.Null: {\n\t\t\t\t\t\treturn z.null();\n\t\t\t\t\t}\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tthrow new Error(`Unsupported leaf kind ${NodeKind[nodeSchema.leafKind]}.`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow new Error(`Unsupported node kind ${NodeKind[nodeSchema.kind]}.`);\n\t\t\t}\n\t\t}\n\t});\n}\nfunction getOrCreateTypeForField(\n\tdefinitionMap: ReadonlyMap<string, SimpleNodeSchema>,\n\ttypeMap: Map<string, Zod.ZodTypeAny>,\n\tinsertSet: Set<string>,\n\tmodifyFieldSet: Set<string>,\n\tmodifyTypeSet: Set<string>,\n\tfieldSchema: SimpleFieldSchema,\n): Zod.ZodTypeAny | undefined {\n\tswitch (fieldSchema.kind) {\n\t\tcase FieldKind.Required: {\n\t\t\treturn getTypeForAllowedTypes(\n\t\t\t\tdefinitionMap,\n\t\t\t\ttypeMap,\n\t\t\t\tinsertSet,\n\t\t\t\tmodifyFieldSet,\n\t\t\t\tmodifyTypeSet,\n\t\t\t\tfieldSchema.allowedTypes,\n\t\t\t);\n\t\t}\n\t\tcase FieldKind.Optional: {\n\t\t\treturn z.union([\n\t\t\t\tz.null(),\n\t\t\t\tgetTypeForAllowedTypes(\n\t\t\t\t\tdefinitionMap,\n\t\t\t\t\ttypeMap,\n\t\t\t\t\tinsertSet,\n\t\t\t\t\tmodifyFieldSet,\n\t\t\t\t\tmodifyTypeSet,\n\t\t\t\t\tfieldSchema.allowedTypes,\n\t\t\t\t),\n\t\t\t]);\n\t\t}\n\t\tcase FieldKind.Identifier: {\n\t\t\treturn undefined;\n\t\t}\n\t\tdefault: {\n\t\t\tthrow new Error(`Unsupported field kind ${NodeKind[fieldSchema.kind]}.`);\n\t\t}\n\t}\n}\nfunction getTypeForAllowedTypes(\n\tdefinitionMap: ReadonlyMap<string, SimpleNodeSchema>,\n\ttypeMap: Map<string, Zod.ZodTypeAny>,\n\tinsertSet: Set<string>,\n\tmodifyFieldSet: Set<string>,\n\tmodifyTypeSet: Set<string>,\n\tallowedTypes: ReadonlySet<string>,\n): Zod.ZodTypeAny {\n\tconst single = tryGetSingleton(allowedTypes);\n\tif (single === undefined) {\n\t\tconst types = [\n\t\t\t...mapIterable(allowedTypes, (name) => {\n\t\t\t\treturn getOrCreateType(\n\t\t\t\t\tdefinitionMap,\n\t\t\t\t\ttypeMap,\n\t\t\t\t\tinsertSet,\n\t\t\t\t\tmodifyFieldSet,\n\t\t\t\t\tmodifyTypeSet,\n\t\t\t\t\tname,\n\t\t\t\t);\n\t\t\t}),\n\t\t];\n\t\tassert(hasAtLeastTwo(types), \"Expected at least two types\");\n\t\treturn z.union(types);\n\t} else {\n\t\treturn getOrCreateType(\n\t\t\tdefinitionMap,\n\t\t\ttypeMap,\n\t\t\tinsertSet,\n\t\t\tmodifyFieldSet,\n\t\t\tmodifyTypeSet,\n\t\t\tsingle,\n\t\t);\n\t}\n}\nfunction tryGetSingleton<T>(set: ReadonlySet<T>): T | undefined {\n\tif (set.size === 1) {\n\t\tfor (const item of set) {\n\t\t\treturn item;\n\t\t}\n\t}\n}\nfunction hasAtLeastTwo<T>(array: T[]): array is [T, T, ...T[]] {\n\treturn array.length >= 2;\n}\n"]}
@@ -0,0 +1,37 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ /**
6
+ * Subset of Map interface.
7
+ *
8
+ * @remarks originally from tree/src/util/utils.ts
9
+ */
10
+ export interface MapGetSet<K, V> {
11
+ get(key: K): V | undefined;
12
+ set(key: K, value: V): void;
13
+ }
14
+ /**
15
+ * TBD
16
+ */
17
+ export declare function fail(message: string): never;
18
+ /**
19
+ * Map one iterable to another by transforming each element one at a time
20
+ * @param iterable - the iterable to transform
21
+ * @param map - the transformation function to run on each element of the iterable
22
+ * @returns a new iterable of elements which have been transformed by the `map` function
23
+ *
24
+ * @remarks originally from tree/src/util/utils.ts
25
+ */
26
+ export declare function mapIterable<T, U>(iterable: Iterable<T>, map: (t: T) => U): IterableIterator<U>;
27
+ /**
28
+ * Retrieve a value from a map with the given key, or create a new entry if the key is not in the map.
29
+ * @param map - The map to query/update
30
+ * @param key - The key to lookup in the map
31
+ * @param defaultValue - a function which returns a default value. This is called and used to set an initial value for the given key in the map if none exists
32
+ * @returns either the existing value for the given key, or the newly-created value (the result of `defaultValue`)
33
+ *
34
+ * @remarks originally from tree/src/util/utils.ts
35
+ */
36
+ export declare function getOrCreate<K, V>(map: MapGetSet<K, V>, key: K, defaultValue: (key: K) => V): V;
37
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/explicit-strategy/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC,EAAE,CAAC;IAC9B,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IAC3B,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAE3C;AAED;;;;;;;GAOG;AACH,wBAAiB,WAAW,CAAC,CAAC,EAAE,CAAC,EAChC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,EACrB,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GACd,gBAAgB,CAAC,CAAC,CAAC,CAIrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,CAAC,EAC/B,GAAG,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EACpB,GAAG,EAAE,CAAC,EACN,YAAY,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GACzB,CAAC,CAOH"}