@fluidframework/ai-collab 2.53.1 → 2.60.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.
- package/CHANGELOG.md +4 -0
- package/dist/explicit-strategy/promptGeneration.d.ts.map +1 -1
- package/dist/explicit-strategy/promptGeneration.js +12 -3
- package/dist/explicit-strategy/promptGeneration.js.map +1 -1
- package/lib/explicit-strategy/promptGeneration.d.ts.map +1 -1
- package/lib/explicit-strategy/promptGeneration.js +13 -4
- package/lib/explicit-strategy/promptGeneration.js.map +1 -1
- package/package.json +10 -10
- package/src/explicit-strategy/promptGeneration.ts +13 -3
package/CHANGELOG.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"promptGeneration.d.ts","sourceRoot":"","sources":["../../src/explicit-strategy/promptGeneration.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAEN,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAK/B,KAAK,cAAc,EAGnB,KAAK,QAAQ,
|
|
1
|
+
{"version":3,"file":"promptGeneration.d.ts","sourceRoot":"","sources":["../../src/explicit-strategy/promptGeneration.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAEN,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAK/B,KAAK,cAAc,EAGnB,KAAK,QAAQ,EAEb,MAAM,+BAA+B,CAAC;AAIvC,OAAO,EAAe,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAIpD;;;GAGG;AACH,MAAM,MAAM,OAAO,GAAG;IACrB,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CACf,EAAE,CAAC;AAEJ;;GAEG;AACH,wBAAgB,eAAe,CAC9B,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,0BAA0B,CAAC,mBAAmB,CAAC,GACnD,MAAM,CAsBR;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACtC,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,MAAM,EAClB,iBAAiB,CAAC,EAAE,MAAM,GACxB,MAAM,CA6BR;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAUlE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACrC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,OAAO,EACZ,WAAW,CAAC,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,MAAM,GACX,MAAM,CA2CR;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACpC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,QAAQ,EAClB,qBAAqB,EAAE,MAAM,EAC7B,WAAW,CAAC,EAAE,MAAM,GAClB,MAAM,CA6BR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,cAAc,GAAG,MAAM,CA6B9E;AAgDD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAOhE"}
|
|
@@ -41,7 +41,10 @@ exports.toDecoratedJson = toDecoratedJson;
|
|
|
41
41
|
*/
|
|
42
42
|
function getPlanningSystemPrompt(treeNode, userPrompt, systemRoleContext) {
|
|
43
43
|
const schema = internal_2.Tree.schema(treeNode);
|
|
44
|
-
const promptFriendlySchema = getPromptFriendlyTreeSchema((0, internal_2.getJsonSchema)(schema, {
|
|
44
|
+
const promptFriendlySchema = getPromptFriendlyTreeSchema((0, internal_2.getJsonSchema)(schema, {
|
|
45
|
+
requireFieldsWithDefaults: false,
|
|
46
|
+
keys: internal_2.KeyEncodingOptions.usePropertyKeys,
|
|
47
|
+
}));
|
|
45
48
|
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
|
|
46
49
|
? ""
|
|
47
50
|
: `
|
|
@@ -80,7 +83,10 @@ exports.createEditListHistoryPrompt = createEditListHistoryPrompt;
|
|
|
80
83
|
*/
|
|
81
84
|
function getEditingSystemPrompt(userPrompt, idGenerator, treeNode, log, appGuidance, plan) {
|
|
82
85
|
const schema = internal_2.Tree.schema(treeNode);
|
|
83
|
-
const promptFriendlySchema = getPromptFriendlyTreeSchema((0, internal_2.getJsonSchema)(schema, {
|
|
86
|
+
const promptFriendlySchema = getPromptFriendlyTreeSchema((0, internal_2.getJsonSchema)(schema, {
|
|
87
|
+
keys: internal_2.KeyEncodingOptions.usePropertyKeys,
|
|
88
|
+
requireFieldsWithDefaults: false,
|
|
89
|
+
}));
|
|
84
90
|
const decoratedTreeJson = toDecoratedJson(idGenerator, treeNode);
|
|
85
91
|
const role = `You are a collaborative agent who interacts with a JSON tree by performing edits to achieve a user-specified goal.${appGuidance === undefined
|
|
86
92
|
? ""
|
|
@@ -114,7 +120,10 @@ exports.getEditingSystemPrompt = getEditingSystemPrompt;
|
|
|
114
120
|
*/
|
|
115
121
|
function getReviewSystemPrompt(userPrompt, idGenerator, treeNode, originalDecoratedJson, appGuidance) {
|
|
116
122
|
const schema = internal_2.Tree.schema(treeNode);
|
|
117
|
-
const promptFriendlySchema = getPromptFriendlyTreeSchema((0, internal_2.getJsonSchema)(schema, {
|
|
123
|
+
const promptFriendlySchema = getPromptFriendlyTreeSchema((0, internal_2.getJsonSchema)(schema, {
|
|
124
|
+
keys: internal_2.KeyEncodingOptions.usePropertyKeys,
|
|
125
|
+
requireFieldsWithDefaults: false,
|
|
126
|
+
}));
|
|
118
127
|
const decoratedTreeJson = toDecoratedJson(idGenerator, treeNode);
|
|
119
128
|
const role = `You are a collaborative agent who interacts with a JSON tree by performing edits to achieve a user-specified goal.${appGuidance === undefined
|
|
120
129
|
? ""
|
|
@@ -1 +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 { doesNodeContainArraySchema, 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\t0xa7b /* 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(\n\t\tgetJsonSchema(schema, { requireFieldsWithDefaults: false, useStoredKeys: false }),\n\t);\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 editOptions = `modifying ${doesNodeContainArraySchema(treeNode) ? \"as well as inserting, removing, or moving\" : \"\"} elements in the tree`;\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 ${editOptions}.\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(\n\t\tgetJsonSchema(schema, { useStoredKeys: false, requireFieldsWithDefaults: false }),\n\t);\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: `\\nThe 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\tconst topLevelEditWrapperDescription = doesNodeContainArraySchema(treeNode)\n\t\t? `contains one of the following interfaces: \"Modify\", null or an array node only edit: \"Insert\", \"Remove\", \"Move\"`\n\t\t: `contains the interface \"Modify\" or null`;\n\n\t// TODO: security: user prompt in system prompt\n\tconst systemPrompt = `\n\t${role}\\nEdits are JSON objects that conform to the schema described below. The top-level object you produce for a given edit is an \"EditWrapper\" object which ${topLevelEditWrapperDescription}.\n\t\\nHere are the schema definitions for an edit:\\n${treeSchemaString}\\n\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(\n\t\tgetJsonSchema(schema, { useStoredKeys: false, requireFieldsWithDefaults: false }),\n\t);\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 * - TODO: Should probably ensure name is a valid TypeScript identifier.\n * - TODO: Should probably ensure name is unique.\n * - TODO: Should probably take in a TreeNodeSchema or SimpleNodeSchema.\n * Note: For explicitly subclassed TreeNodeSchema, the developer/code facing name of the class can be recovered using `.name`: this might be useful.\n */\nexport function getPromptFriendlyTreeSchema(jsonSchema: JsonTreeSchema): string {\n\tlet stringifiedSchema = \"\";\n\tfor (const [name, def] of Object.entries(jsonSchema.$defs)) {\n\t\tif (def._treeNodeSchemaKind !== NodeKind.Object) {\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, 0xa7c /* 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"]}
|
|
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\tKeyEncodingOptions,\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 { doesNodeContainArraySchema, 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\t0xa7b /* 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(\n\t\tgetJsonSchema(schema, {\n\t\t\trequireFieldsWithDefaults: false,\n\t\t\tkeys: KeyEncodingOptions.usePropertyKeys,\n\t\t}),\n\t);\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 editOptions = `modifying ${doesNodeContainArraySchema(treeNode) ? \"as well as inserting, removing, or moving\" : \"\"} elements in the tree`;\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 ${editOptions}.\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(\n\t\tgetJsonSchema(schema, {\n\t\t\tkeys: KeyEncodingOptions.usePropertyKeys,\n\t\t\trequireFieldsWithDefaults: false,\n\t\t}),\n\t);\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: `\\nThe 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\tconst topLevelEditWrapperDescription = doesNodeContainArraySchema(treeNode)\n\t\t? `contains one of the following interfaces: \"Modify\", null or an array node only edit: \"Insert\", \"Remove\", \"Move\"`\n\t\t: `contains the interface \"Modify\" or null`;\n\n\t// TODO: security: user prompt in system prompt\n\tconst systemPrompt = `\n\t${role}\\nEdits are JSON objects that conform to the schema described below. The top-level object you produce for a given edit is an \"EditWrapper\" object which ${topLevelEditWrapperDescription}.\n\t\\nHere are the schema definitions for an edit:\\n${treeSchemaString}\\n\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(\n\t\tgetJsonSchema(schema, {\n\t\t\tkeys: KeyEncodingOptions.usePropertyKeys,\n\t\t\trequireFieldsWithDefaults: false,\n\t\t}),\n\t);\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 * - TODO: Should probably ensure name is a valid TypeScript identifier.\n * - TODO: Should probably ensure name is unique.\n * - TODO: Should probably take in a TreeNodeSchema or SimpleNodeSchema.\n * Note: For explicitly subclassed TreeNodeSchema, the developer/code facing name of the class can be recovered using `.name`: this might be useful.\n */\nexport function getPromptFriendlyTreeSchema(jsonSchema: JsonTreeSchema): string {\n\tlet stringifiedSchema = \"\";\n\tfor (const [name, def] of Object.entries(jsonSchema.$defs)) {\n\t\tif (def._treeNodeSchemaKind !== NodeKind.Object) {\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, 0xa7c /* 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"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"promptGeneration.d.ts","sourceRoot":"","sources":["../../src/explicit-strategy/promptGeneration.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAEN,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAK/B,KAAK,cAAc,EAGnB,KAAK,QAAQ,
|
|
1
|
+
{"version":3,"file":"promptGeneration.d.ts","sourceRoot":"","sources":["../../src/explicit-strategy/promptGeneration.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAEN,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAK/B,KAAK,cAAc,EAGnB,KAAK,QAAQ,EAEb,MAAM,+BAA+B,CAAC;AAIvC,OAAO,EAAe,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAIpD;;;GAGG;AACH,MAAM,MAAM,OAAO,GAAG;IACrB,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CACf,EAAE,CAAC;AAEJ;;GAEG;AACH,wBAAgB,eAAe,CAC9B,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,0BAA0B,CAAC,mBAAmB,CAAC,GACnD,MAAM,CAsBR;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACtC,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,MAAM,EAClB,iBAAiB,CAAC,EAAE,MAAM,GACxB,MAAM,CA6BR;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAUlE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACrC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,OAAO,EACZ,WAAW,CAAC,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,MAAM,GACX,MAAM,CA2CR;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACpC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,QAAQ,EAClB,qBAAqB,EAAE,MAAM,EAC7B,WAAW,CAAC,EAAE,MAAM,GAClB,MAAM,CA6BR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,cAAc,GAAG,MAAM,CA6B9E;AAgDD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAOhE"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import { assert } from "@fluidframework/core-utils/internal";
|
|
6
|
-
import { NodeKind, getJsonSchema, getSimpleSchema, Tree, } from "@fluidframework/tree/internal";
|
|
6
|
+
import { NodeKind, getJsonSchema, getSimpleSchema, Tree, KeyEncodingOptions, } from "@fluidframework/tree/internal";
|
|
7
7
|
// eslint-disable-next-line import/no-internal-modules
|
|
8
8
|
import { createZodJsonValidator } from "typechat/zod";
|
|
9
9
|
import { objectIdKey } from "./agentEditTypes.js";
|
|
@@ -37,7 +37,10 @@ export function toDecoratedJson(idGenerator, root) {
|
|
|
37
37
|
*/
|
|
38
38
|
export function getPlanningSystemPrompt(treeNode, userPrompt, systemRoleContext) {
|
|
39
39
|
const schema = Tree.schema(treeNode);
|
|
40
|
-
const promptFriendlySchema = getPromptFriendlyTreeSchema(getJsonSchema(schema, {
|
|
40
|
+
const promptFriendlySchema = getPromptFriendlyTreeSchema(getJsonSchema(schema, {
|
|
41
|
+
requireFieldsWithDefaults: false,
|
|
42
|
+
keys: KeyEncodingOptions.usePropertyKeys,
|
|
43
|
+
}));
|
|
41
44
|
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
45
|
? ""
|
|
43
46
|
: `
|
|
@@ -74,7 +77,10 @@ export function createEditListHistoryPrompt(edits) {
|
|
|
74
77
|
*/
|
|
75
78
|
export function getEditingSystemPrompt(userPrompt, idGenerator, treeNode, log, appGuidance, plan) {
|
|
76
79
|
const schema = Tree.schema(treeNode);
|
|
77
|
-
const promptFriendlySchema = getPromptFriendlyTreeSchema(getJsonSchema(schema, {
|
|
80
|
+
const promptFriendlySchema = getPromptFriendlyTreeSchema(getJsonSchema(schema, {
|
|
81
|
+
keys: KeyEncodingOptions.usePropertyKeys,
|
|
82
|
+
requireFieldsWithDefaults: false,
|
|
83
|
+
}));
|
|
78
84
|
const decoratedTreeJson = toDecoratedJson(idGenerator, treeNode);
|
|
79
85
|
const role = `You are a collaborative agent who interacts with a JSON tree by performing edits to achieve a user-specified goal.${appGuidance === undefined
|
|
80
86
|
? ""
|
|
@@ -107,7 +113,10 @@ export function getEditingSystemPrompt(userPrompt, idGenerator, treeNode, log, a
|
|
|
107
113
|
*/
|
|
108
114
|
export function getReviewSystemPrompt(userPrompt, idGenerator, treeNode, originalDecoratedJson, appGuidance) {
|
|
109
115
|
const schema = Tree.schema(treeNode);
|
|
110
|
-
const promptFriendlySchema = getPromptFriendlyTreeSchema(getJsonSchema(schema, {
|
|
116
|
+
const promptFriendlySchema = getPromptFriendlyTreeSchema(getJsonSchema(schema, {
|
|
117
|
+
keys: KeyEncodingOptions.usePropertyKeys,
|
|
118
|
+
requireFieldsWithDefaults: false,
|
|
119
|
+
}));
|
|
111
120
|
const decoratedTreeJson = toDecoratedJson(idGenerator, treeNode);
|
|
112
121
|
const role = `You are a collaborative agent who interacts with a JSON tree by performing edits to achieve a user-specified goal.${appGuidance === undefined
|
|
113
122
|
? ""
|
|
@@ -1 +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 { doesNodeContainArraySchema, 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\t0xa7b /* 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(\n\t\tgetJsonSchema(schema, { requireFieldsWithDefaults: false, useStoredKeys: false }),\n\t);\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 editOptions = `modifying ${doesNodeContainArraySchema(treeNode) ? \"as well as inserting, removing, or moving\" : \"\"} elements in the tree`;\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 ${editOptions}.\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(\n\t\tgetJsonSchema(schema, { useStoredKeys: false, requireFieldsWithDefaults: false }),\n\t);\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: `\\nThe 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\tconst topLevelEditWrapperDescription = doesNodeContainArraySchema(treeNode)\n\t\t? `contains one of the following interfaces: \"Modify\", null or an array node only edit: \"Insert\", \"Remove\", \"Move\"`\n\t\t: `contains the interface \"Modify\" or null`;\n\n\t// TODO: security: user prompt in system prompt\n\tconst systemPrompt = `\n\t${role}\\nEdits are JSON objects that conform to the schema described below. The top-level object you produce for a given edit is an \"EditWrapper\" object which ${topLevelEditWrapperDescription}.\n\t\\nHere are the schema definitions for an edit:\\n${treeSchemaString}\\n\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(\n\t\tgetJsonSchema(schema, { useStoredKeys: false, requireFieldsWithDefaults: false }),\n\t);\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 * - TODO: Should probably ensure name is a valid TypeScript identifier.\n * - TODO: Should probably ensure name is unique.\n * - TODO: Should probably take in a TreeNodeSchema or SimpleNodeSchema.\n * Note: For explicitly subclassed TreeNodeSchema, the developer/code facing name of the class can be recovered using `.name`: this might be useful.\n */\nexport function getPromptFriendlyTreeSchema(jsonSchema: JsonTreeSchema): string {\n\tlet stringifiedSchema = \"\";\n\tfor (const [name, def] of Object.entries(jsonSchema.$defs)) {\n\t\tif (def._treeNodeSchemaKind !== NodeKind.Object) {\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, 0xa7c /* 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"]}
|
|
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\tKeyEncodingOptions,\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 { doesNodeContainArraySchema, 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\t0xa7b /* 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(\n\t\tgetJsonSchema(schema, {\n\t\t\trequireFieldsWithDefaults: false,\n\t\t\tkeys: KeyEncodingOptions.usePropertyKeys,\n\t\t}),\n\t);\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 editOptions = `modifying ${doesNodeContainArraySchema(treeNode) ? \"as well as inserting, removing, or moving\" : \"\"} elements in the tree`;\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 ${editOptions}.\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(\n\t\tgetJsonSchema(schema, {\n\t\t\tkeys: KeyEncodingOptions.usePropertyKeys,\n\t\t\trequireFieldsWithDefaults: false,\n\t\t}),\n\t);\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: `\\nThe 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\tconst topLevelEditWrapperDescription = doesNodeContainArraySchema(treeNode)\n\t\t? `contains one of the following interfaces: \"Modify\", null or an array node only edit: \"Insert\", \"Remove\", \"Move\"`\n\t\t: `contains the interface \"Modify\" or null`;\n\n\t// TODO: security: user prompt in system prompt\n\tconst systemPrompt = `\n\t${role}\\nEdits are JSON objects that conform to the schema described below. The top-level object you produce for a given edit is an \"EditWrapper\" object which ${topLevelEditWrapperDescription}.\n\t\\nHere are the schema definitions for an edit:\\n${treeSchemaString}\\n\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(\n\t\tgetJsonSchema(schema, {\n\t\t\tkeys: KeyEncodingOptions.usePropertyKeys,\n\t\t\trequireFieldsWithDefaults: false,\n\t\t}),\n\t);\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 * - TODO: Should probably ensure name is a valid TypeScript identifier.\n * - TODO: Should probably ensure name is unique.\n * - TODO: Should probably take in a TreeNodeSchema or SimpleNodeSchema.\n * Note: For explicitly subclassed TreeNodeSchema, the developer/code facing name of the class can be recovered using `.name`: this might be useful.\n */\nexport function getPromptFriendlyTreeSchema(jsonSchema: JsonTreeSchema): string {\n\tlet stringifiedSchema = \"\";\n\tfor (const [name, def] of Object.entries(jsonSchema.$defs)) {\n\t\tif (def._treeNodeSchemaKind !== NodeKind.Object) {\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, 0xa7c /* 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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/ai-collab",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.60.0",
|
|
4
4
|
"description": "Experimental package to simplify integrating AI into Fluid-based applications",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -69,10 +69,10 @@
|
|
|
69
69
|
"temp-directory": "nyc/.nyc_output"
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"@fluidframework/core-utils": "~2.
|
|
73
|
-
"@fluidframework/runtime-utils": "~2.
|
|
74
|
-
"@fluidframework/telemetry-utils": "~2.
|
|
75
|
-
"@fluidframework/tree": "~2.
|
|
72
|
+
"@fluidframework/core-utils": "~2.60.0",
|
|
73
|
+
"@fluidframework/runtime-utils": "~2.60.0",
|
|
74
|
+
"@fluidframework/telemetry-utils": "~2.60.0",
|
|
75
|
+
"@fluidframework/tree": "~2.60.0",
|
|
76
76
|
"fastest-levenshtein": "^1.0.16",
|
|
77
77
|
"openai": "^4.67.3",
|
|
78
78
|
"typechat": "^0.1.1",
|
|
@@ -82,14 +82,14 @@
|
|
|
82
82
|
"devDependencies": {
|
|
83
83
|
"@arethetypeswrong/cli": "^0.17.1",
|
|
84
84
|
"@biomejs/biome": "~1.9.3",
|
|
85
|
-
"@fluid-internal/mocha-test-setup": "~2.
|
|
85
|
+
"@fluid-internal/mocha-test-setup": "~2.60.0",
|
|
86
86
|
"@fluid-tools/build-cli": "^0.57.0",
|
|
87
87
|
"@fluidframework/build-common": "^2.0.3",
|
|
88
88
|
"@fluidframework/build-tools": "^0.57.0",
|
|
89
|
-
"@fluidframework/eslint-config-fluid": "^
|
|
90
|
-
"@fluidframework/id-compressor": "~2.
|
|
91
|
-
"@fluidframework/runtime-utils": "~2.
|
|
92
|
-
"@fluidframework/test-runtime-utils": "~2.
|
|
89
|
+
"@fluidframework/eslint-config-fluid": "^6.0.0",
|
|
90
|
+
"@fluidframework/id-compressor": "~2.60.0",
|
|
91
|
+
"@fluidframework/runtime-utils": "~2.60.0",
|
|
92
|
+
"@fluidframework/test-runtime-utils": "~2.60.0",
|
|
93
93
|
"@microsoft/api-extractor": "7.52.8",
|
|
94
94
|
"@types/mocha": "^10.0.10",
|
|
95
95
|
"@types/node": "^18.19.0",
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
getSimpleSchema,
|
|
17
17
|
Tree,
|
|
18
18
|
type TreeNode,
|
|
19
|
+
KeyEncodingOptions,
|
|
19
20
|
} from "@fluidframework/tree/internal";
|
|
20
21
|
// eslint-disable-next-line import/no-internal-modules
|
|
21
22
|
import { createZodJsonValidator } from "typechat/zod";
|
|
@@ -75,7 +76,10 @@ export function getPlanningSystemPrompt(
|
|
|
75
76
|
const schema = Tree.schema(treeNode);
|
|
76
77
|
|
|
77
78
|
const promptFriendlySchema = getPromptFriendlyTreeSchema(
|
|
78
|
-
getJsonSchema(schema, {
|
|
79
|
+
getJsonSchema(schema, {
|
|
80
|
+
requireFieldsWithDefaults: false,
|
|
81
|
+
keys: KeyEncodingOptions.usePropertyKeys,
|
|
82
|
+
}),
|
|
79
83
|
);
|
|
80
84
|
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.${
|
|
81
85
|
systemRoleContext === undefined
|
|
@@ -129,7 +133,10 @@ export function getEditingSystemPrompt(
|
|
|
129
133
|
): string {
|
|
130
134
|
const schema = Tree.schema(treeNode);
|
|
131
135
|
const promptFriendlySchema = getPromptFriendlyTreeSchema(
|
|
132
|
-
getJsonSchema(schema, {
|
|
136
|
+
getJsonSchema(schema, {
|
|
137
|
+
keys: KeyEncodingOptions.usePropertyKeys,
|
|
138
|
+
requireFieldsWithDefaults: false,
|
|
139
|
+
}),
|
|
133
140
|
);
|
|
134
141
|
const decoratedTreeJson = toDecoratedJson(idGenerator, treeNode);
|
|
135
142
|
|
|
@@ -181,7 +188,10 @@ export function getReviewSystemPrompt(
|
|
|
181
188
|
): string {
|
|
182
189
|
const schema = Tree.schema(treeNode);
|
|
183
190
|
const promptFriendlySchema = getPromptFriendlyTreeSchema(
|
|
184
|
-
getJsonSchema(schema, {
|
|
191
|
+
getJsonSchema(schema, {
|
|
192
|
+
keys: KeyEncodingOptions.usePropertyKeys,
|
|
193
|
+
requireFieldsWithDefaults: false,
|
|
194
|
+
}),
|
|
185
195
|
);
|
|
186
196
|
const decoratedTreeJson = toDecoratedJson(idGenerator, treeNode);
|
|
187
197
|
|