@fluidframework/ai-collab 2.72.0 → 2.74.0-365691
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/agentEditReducer.d.ts.map +1 -1
- package/dist/explicit-strategy/agentEditReducer.js +2 -1
- package/dist/explicit-strategy/agentEditReducer.js.map +1 -1
- package/dist/explicit-strategy/promptGeneration.js +1 -1
- package/dist/explicit-strategy/promptGeneration.js.map +1 -1
- package/dist/implicit-strategy/sharedTreeDiff.js +1 -1
- package/dist/implicit-strategy/sharedTreeDiff.js.map +1 -1
- package/lib/explicit-strategy/agentEditReducer.d.ts.map +1 -1
- package/lib/explicit-strategy/agentEditReducer.js +2 -1
- package/lib/explicit-strategy/agentEditReducer.js.map +1 -1
- package/lib/explicit-strategy/promptGeneration.js +1 -1
- package/lib/explicit-strategy/promptGeneration.js.map +1 -1
- package/lib/implicit-strategy/sharedTreeDiff.js +1 -1
- package/lib/implicit-strategy/sharedTreeDiff.js.map +1 -1
- package/package.json +10 -10
- package/src/explicit-strategy/agentEditReducer.ts +3 -2
- package/src/explicit-strategy/promptGeneration.ts +1 -1
- package/src/implicit-strategy/sharedTreeDiff.ts +1 -1
|
@@ -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\tKeyEncodingOptions,\n} from \"@fluidframework/tree/internal\";\n// eslint-disable-next-line import-x/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
|
+
{"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-x/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 = /[^.]+$/.exec(schemaName);\n\tif (matches === null) {\n\t\t// empty scope\n\t\treturn schemaName;\n\t}\n\treturn matches[0];\n}\n"]}
|
|
@@ -170,7 +170,7 @@ export function sharedTreeDiff(obj, newObj, options = DEFAULT_OPTIONS, _stack =
|
|
|
170
170
|
!(Number.isNaN(objValue) && Number.isNaN(newObjValue)) &&
|
|
171
171
|
!(areCompatibleObjects &&
|
|
172
172
|
(Number.isNaN(objValue)
|
|
173
|
-
? // eslint-disable-next-line prefer-template
|
|
173
|
+
? // eslint-disable-next-line prefer-template, @typescript-eslint/no-base-to-string
|
|
174
174
|
objValue + "" === newObjValue + ""
|
|
175
175
|
: // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
176
176
|
// @ts-ignore
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sharedTreeDiff.js","sourceRoot":"","sources":["../../src/implicit-strategy/sharedTreeDiff.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { type TreeArrayNode, NodeKind } from \"@fluidframework/tree\";\n\nimport { isTreeMapNode, sharedTreeTraverse } from \"./utils.js\";\n\n/**\n * Represents a path through a tree of objects.\n * number values represent array indices whereas string values represent object keys.\n *\n * @alpha\n */\nexport type ObjectPath = (string | number)[];\n\n/**\n * Represents a create operation between two branches of a tree.\n * Meaning that an attribute (a shared tree node) was identified as being created.\n *\n * @alpha\n */\nexport interface DifferenceCreate {\n\ttype: \"CREATE\";\n\tpath: ObjectPath;\n\tvalue: unknown;\n}\n\n/**\n * Represents a remove operation between two branches of a tree.\n * Meaning that an attribute (a shared tree node) was identified as being deleted.\n * When using object ids, removes are idenitified by an object with a given id no longer existing.\n *\n * @alpha\n */\nexport interface DifferenceRemove {\n\ttype: \"REMOVE\";\n\tpath: ObjectPath;\n\toldValue: unknown;\n\tobjectId?: string | number | undefined;\n}\n\n/**\n * Represents a change operation between two branches of a tree.\n * Meaning that an attribute (a shared tree node) was identified as being changed from one value to another.\n *\n * @alpha\n */\nexport interface DifferenceChange {\n\ttype: \"CHANGE\";\n\tpath: ObjectPath;\n\tvalue: unknown;\n\toldValue: unknown;\n\tobjectId?: string | number | undefined;\n}\n\n/**\n * Represents a move operation between two branches of a tree.\n * Meaning that an object (shared tree node) was identified as being moved from one index to another based on its unique id.\n *\n * @alpha\n */\nexport interface DifferenceMove {\n\ttype: \"MOVE\";\n\tpath: ObjectPath;\n\tnewIndex: number;\n\tvalue: unknown;\n\tobjectId?: string | number | undefined;\n}\n\n/**\n * Union for all possible difference types.\n *\n * @alpha\n */\nexport type Difference =\n\t| DifferenceCreate\n\t| DifferenceRemove\n\t| DifferenceChange\n\t| DifferenceMove;\n\n/**\n * Options for tree diffing.\n * @alpha\n */\nexport interface Options {\n\tcyclesFix: boolean;\n\tuseObjectIds?:\n\t\t| {\n\t\t\t\tidAttributeName: string;\n\t\t }\n\t\t| undefined;\n}\n\nconst richTypes = { Date: true, RegExp: true, String: true, Number: true };\n\n/**\n * By default, Object Diff supports cyclical references, but if you are sure that the object has no cycles like parsed JSON\n * you can disable cycles by setting the cyclesFix option to false\n */\nconst DEFAULT_OPTIONS: Options = { cyclesFix: true };\n\n/**\n * Compares two objects and returns an array of differences between them.\n *\n * @alpha\n */\nexport function sharedTreeDiff(\n\tobj: Record<string, unknown> | unknown[],\n\tnewObj: Record<string, unknown> | unknown[],\n\toptions: Options = DEFAULT_OPTIONS,\n\t_stack: (Record<string, unknown> | unknown[])[] = [],\n): Difference[] {\n\tconst diffs: Difference[] = [];\n\tconst isObjArray = isArrayOrTreeArrayNode(obj);\n\tconst isNewObjArray = isArrayOrTreeArrayNode(newObj);\n\n\t// If useObjectIds is set, we'll create a map of object ids to their index in the array.\n\tconst oldObjArrayItemIdsToIndex =\n\t\tisObjArray === false || options.useObjectIds === undefined\n\t\t\t? new Map<string | number, number>()\n\t\t\t: createObjectArrayItemIdsToIndexMap(obj, options.useObjectIds.idAttributeName);\n\n\tconst newObjArrayItemIdsToIndex =\n\t\tisNewObjArray === false || options.useObjectIds === undefined\n\t\t\t? new Map<string | number, number>()\n\t\t\t: createObjectArrayItemIdsToIndexMap(newObj, options.useObjectIds.idAttributeName);\n\n\tconst objectKeys = isTreeMapNode(obj) ? obj.keys() : Object.keys(obj);\n\t// We compare existence and values of all attributes within the old against new object, looking for removals or changes.\n\tfor (const key of objectKeys) {\n\t\tconst objValue: unknown = isTreeMapNode(obj) ? obj.get(key as string) : obj[key];\n\t\tconst path = isObjArray ? +key : key;\n\t\t// 1. First, check if the key within the old object, exists within the new object. If it doesn't exist this would be an attribute removal.\n\t\tif (!(key in newObj)) {\n\t\t\tif (options.useObjectIds === undefined) {\n\t\t\t\tdiffs.push({\n\t\t\t\t\ttype: \"REMOVE\",\n\t\t\t\t\tpath: [path],\n\t\t\t\t\tobjectId: undefined,\n\t\t\t\t\toldValue: objValue,\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// If we're dealing with an object in an array, we can use the object's id to check if it was moved to a new index.\n\t\t\telse if (\n\t\t\t\tisNewObjArray === true &&\n\t\t\t\tisObjArray &&\n\t\t\t\ttypeof objValue === \"object\" &&\n\t\t\t\tobjValue !== null\n\t\t\t) {\n\t\t\t\tconst objectId = objValue[options.useObjectIds.idAttributeName] as\n\t\t\t\t\t| string\n\t\t\t\t\t| number\n\t\t\t\t\t| undefined;\n\t\t\t\tif (objectId !== undefined && newObjArrayItemIdsToIndex.has(objectId)) {\n\t\t\t\t\t// The index no longer exists in the new root object array, however the object that lived at this index actually still exists at a new index.\n\t\t\t\t\t// Therefore, this node was moved to a new index.\n\t\t\t\t\tdiffs.push({\n\t\t\t\t\t\ttype: \"MOVE\",\n\t\t\t\t\t\tpath: [path],\n\t\t\t\t\t\tnewIndex: newObjArrayItemIdsToIndex.get(objectId) as number,\n\t\t\t\t\t\tvalue: objValue,\n\t\t\t\t\t\tobjectId,\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// The object with the given id cannot be found within the new array, therefore it was removed.\n\t\t\t\telse {\n\t\t\t\t\tdiffs.push({\n\t\t\t\t\t\ttype: \"REMOVE\",\n\t\t\t\t\t\tpath: [path],\n\t\t\t\t\t\tobjectId,\n\t\t\t\t\t\toldValue: objValue,\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If we're not dealing with an object in an array, we can't use id's to check for a move.\n\t\t\t// We'll assume that a missing key in the new object means that the cooresponding value was removed.\n\t\t\telse {\n\t\t\t\tdiffs.push({\n\t\t\t\t\ttype: \"REMOVE\",\n\t\t\t\t\tpath: [path],\n\t\t\t\t\tobjectId: undefined,\n\t\t\t\t\toldValue: objValue,\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tconst newObjValue: unknown = newObj[key];\n\t\tconst areCompatibleObjects =\n\t\t\ttypeof objValue === \"object\" &&\n\t\t\ttypeof newObjValue === \"object\" &&\n\t\t\tisArrayOrTreeArrayNode(objValue) === isArrayOrTreeArrayNode(newObjValue);\n\n\t\t// 2a. If the given old object key exists in the new object, and the value of said key in both objects is ANOTHER nested object, we need to run a recursive diff check on them.\n\t\tif (\n\t\t\tobjValue !== null &&\n\t\t\tnewObjValue !== null &&\n\t\t\tareCompatibleObjects &&\n\t\t\t// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/no-unsafe-member-access\n\t\t\t!richTypes[Object.getPrototypeOf(objValue)?.constructor?.name] &&\n\t\t\t(!options.cyclesFix || !_stack.includes(objValue as Record<string, unknown>))\n\t\t) {\n\t\t\tif (options.useObjectIds === undefined) {\n\t\t\t\tconst nestedDiffs = sharedTreeDiff(\n\t\t\t\t\tobjValue as Record<string, unknown> | unknown[],\n\t\t\t\t\tnewObjValue as Record<string, unknown> | unknown[],\n\t\t\t\t\toptions,\n\t\t\t\t\toptions.cyclesFix === true\n\t\t\t\t\t\t? [..._stack, objValue as Record<string, unknown> | unknown[]]\n\t\t\t\t\t\t: [],\n\t\t\t\t);\n\t\t\t\t// eslint-disable-next-line prefer-spread\n\t\t\t\tdiffs.push.apply(\n\t\t\t\t\tdiffs,\n\t\t\t\t\tnestedDiffs.map((difference) => {\n\t\t\t\t\t\tdifference.path.unshift(path);\n\t\t\t\t\t\treturn difference;\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Use Object Id strategy to determine if the objects should be compared for changes\n\t\t\telse {\n\t\t\t\tconst oldObjectId = (objValue as Record<string, unknown>)[\n\t\t\t\t\toptions.useObjectIds.idAttributeName\n\t\t\t\t] as string | number | undefined;\n\t\t\t\tconst newObjectId = (newObjValue as Record<string, unknown>)[\n\t\t\t\t\toptions.useObjectIds.idAttributeName\n\t\t\t\t] as string | number | undefined;\n\n\t\t\t\tif (oldObjectId !== undefined && newObjectId !== undefined) {\n\t\t\t\t\t// 2a.1 if the object id's are the same, we can continue a comparison between the two objects.\n\t\t\t\t\tif (oldObjectId === newObjectId) {\n\t\t\t\t\t\tconst nestedDiffs = sharedTreeDiff(\n\t\t\t\t\t\t\tobjValue as Record<string, unknown> | unknown[],\n\t\t\t\t\t\t\tnewObjValue as Record<string, unknown> | unknown[],\n\t\t\t\t\t\t\toptions,\n\t\t\t\t\t\t\toptions.cyclesFix === true\n\t\t\t\t\t\t\t\t? [..._stack, objValue as Record<string, unknown> | unknown[]]\n\t\t\t\t\t\t\t\t: [],\n\t\t\t\t\t\t);\n\t\t\t\t\t\tdiffs.push(\n\t\t\t\t\t\t\t...nestedDiffs.map((difference) => {\n\t\t\t\t\t\t\t\tdifference.path.unshift(path);\n\t\t\t\t\t\t\t\treturn difference;\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\t// 2a.2 The object id's are different, their attributes cannot be compared.\n\t\t\t\t\t// We need to find the new index of the object, if it exists in the new array and do a diff comparison.\n\t\t\t\t\telse {\n\t\t\t\t\t\tconst newIndexOfOldObject = newObjArrayItemIdsToIndex.get(oldObjectId);\n\t\t\t\t\t\t// The object no longer exists in the new array, therefore it was removed.\n\t\t\t\t\t\tif (newIndexOfOldObject === undefined) {\n\t\t\t\t\t\t\tdiffs.push({\n\t\t\t\t\t\t\t\ttype: \"REMOVE\",\n\t\t\t\t\t\t\t\tpath: [path],\n\t\t\t\t\t\t\t\toldValue: objValue,\n\t\t\t\t\t\t\t\tobjectId: oldObjectId,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// This object still exists but at a new index within the new array therefore it was moved.\n\t\t\t\t\t\t// At this point we can determine whether a new move is necessary or there is one that will place it at the desired index.\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tdiffs.push({\n\t\t\t\t\t\t\t\ttype: \"MOVE\",\n\t\t\t\t\t\t\t\tpath: [path],\n\t\t\t\t\t\t\t\tnewIndex: newIndexOfOldObject,\n\t\t\t\t\t\t\t\tvalue: objValue,\n\t\t\t\t\t\t\t\tobjectId: oldObjectId,\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t// An object could have been moved AND changed. We need to check for this.\n\t\t\t\t\t\t\tconst nestedDiffs = sharedTreeDiff(\n\t\t\t\t\t\t\t\tobj[path] as Record<string, unknown> | unknown[],\n\t\t\t\t\t\t\t\tnewObj[newIndexOfOldObject] as Record<string, unknown> | unknown[],\n\t\t\t\t\t\t\t\toptions,\n\t\t\t\t\t\t\t\toptions.cyclesFix === true\n\t\t\t\t\t\t\t\t\t? [..._stack, objValue as Record<string, unknown> | unknown[]]\n\t\t\t\t\t\t\t\t\t: [],\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tdiffs.push(\n\t\t\t\t\t\t\t\t...nestedDiffs.map((difference) => {\n\t\t\t\t\t\t\t\t\tdifference.path.unshift(path);\n\t\t\t\t\t\t\t\t\treturn difference;\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}\n\t\t\t\t} else {\n\t\t\t\t\tconst nestedDiffs = sharedTreeDiff(\n\t\t\t\t\t\tobjValue as Record<string, unknown> | unknown[],\n\t\t\t\t\t\tnewObjValue as Record<string, unknown> | unknown[],\n\t\t\t\t\t\toptions,\n\t\t\t\t\t\toptions.cyclesFix === true\n\t\t\t\t\t\t\t? [..._stack, objValue as Record<string, unknown> | unknown[]]\n\t\t\t\t\t\t\t: [],\n\t\t\t\t\t);\n\t\t\t\t\tdiffs.push(\n\t\t\t\t\t\t...nestedDiffs.map((difference) => {\n\t\t\t\t\t\t\tdifference.path.unshift(path);\n\t\t\t\t\t\t\treturn difference;\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// 2b. If the given old object key exists in the new object, and the value of said key in both objects is NOT another nested object, we need to check if the values are the same.\n\t\telse if (\n\t\t\tobjValue !== newObjValue &&\n\t\t\t// treat NaN values as equivalent\n\t\t\t!(Number.isNaN(objValue) && Number.isNaN(newObjValue)) &&\n\t\t\t!(\n\t\t\t\tareCompatibleObjects &&\n\t\t\t\t(Number.isNaN(objValue)\n\t\t\t\t\t? // eslint-disable-next-line prefer-template\n\t\t\t\t\t\tobjValue + \"\" === newObjValue + \"\"\n\t\t\t\t\t: // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n\t\t\t\t\t\t// @ts-ignore\n\t\t\t\t\t\t+objValue === +newObjValue)\n\t\t\t)\n\t\t) {\n\t\t\tdiffs.push({\n\t\t\t\tpath: [path],\n\t\t\t\ttype: \"CHANGE\",\n\t\t\t\tvalue: newObjValue,\n\t\t\t\toldValue: objValue,\n\t\t\t\tobjectId:\n\t\t\t\t\toptions.useObjectIds?.idAttributeName === undefined\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: (newObj[options.useObjectIds.idAttributeName] as string | number | undefined),\n\t\t\t});\n\t\t}\n\t}\n\n\t// 3. Finally, we check for new keys in the new object that did not exist in the old object.\n\t// The existence of new keys may signal new values or moved values.\n\tconst newObjKeys = isTreeMapNode(newObj) ? newObj.keys() : Object.keys(newObj);\n\tfor (const key of newObjKeys) {\n\t\tconst newObjValue: unknown = isTreeMapNode(newObj)\n\t\t\t? newObj.get(key as string)\n\t\t\t: newObj[key];\n\t\tconst path = isNewObjArray ? +key : key;\n\n\t\tconst isKeyInOldObject = isTreeMapNode(obj)\n\t\t\t? obj.has(key as string)\n\t\t\t: Object.keys(obj).includes(key as string);\n\t\tif (!isKeyInOldObject) {\n\t\t\tif (options.useObjectIds === undefined) {\n\t\t\t\tdiffs.push({\n\t\t\t\t\ttype: \"CREATE\",\n\t\t\t\t\tpath: [path],\n\t\t\t\t\tvalue: newObjValue,\n\t\t\t\t});\n\t\t\t}\n\t\t\t// If we're dealing with an object in an array, we can use the object's id to check if this new index actually\n\t\t\t// contains a prexisting object that was moved from an old index.\n\t\t\telse if (\n\t\t\t\tisObjArray === true &&\n\t\t\t\tisNewObjArray === true &&\n\t\t\t\ttypeof newObjValue === \"object\" &&\n\t\t\t\tnewObjValue !== null\n\t\t\t) {\n\t\t\t\tconst objectId = newObjValue[options.useObjectIds.idAttributeName] as\n\t\t\t\t\t| string\n\t\t\t\t\t| number\n\t\t\t\t\t| undefined;\n\t\t\t\tif (objectId !== undefined && oldObjArrayItemIdsToIndex.has(objectId)) {\n\t\t\t\t\t// The new root object array contains a new index, however the object that lives at this new index previously existed at an old index.\n\t\t\t\t\t// Therefore, this object was moved to a new index.\n\t\t\t\t\tdiffs.push({\n\t\t\t\t\t\ttype: \"MOVE\",\n\t\t\t\t\t\tpath: [path],\n\t\t\t\t\t\tnewIndex: newObjArrayItemIdsToIndex.get(objectId) as number,\n\t\t\t\t\t\tvalue: newObjValue,\n\t\t\t\t\t\tobjectId,\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// If either the object's id attribute does not exist or the original array does not contain an object with the given id\n\t\t\t\t// Then we assume this was a newly created object.\n\t\t\t\telse {\n\t\t\t\t\tdiffs.push({\n\t\t\t\t\t\ttype: \"CREATE\",\n\t\t\t\t\t\tpath: [path],\n\t\t\t\t\t\tvalue: newObjValue,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If we're not dealing with an object in an array, we can't use id's to check for a move.\n\t\t\t// We'll assume that a brand new key and value pair in the new object means that a new value was created.\n\t\t\telse {\n\t\t\t\tdiffs.push({\n\t\t\t\t\ttype: \"CREATE\",\n\t\t\t\t\tpath: [path],\n\t\t\t\t\tvalue: newObjValue,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (options.useObjectIds !== undefined) {\n\t\t\t// If we're dealing with an object in an array, we can use the object's id to check if this EXISTING index\n\t\t\t// houses a new object based on a newly encountered id.\n\t\t\tif (\n\t\t\t\tisObjArray === true &&\n\t\t\t\tisNewObjArray === true &&\n\t\t\t\ttypeof newObjValue === \"object\" &&\n\t\t\t\tnewObjValue !== null\n\t\t\t) {\n\t\t\t\tconst objectId = newObjValue[options.useObjectIds.idAttributeName] as\n\t\t\t\t\t| string\n\t\t\t\t\t| number\n\t\t\t\t\t| undefined;\n\t\t\t\t// If this object has an id and it does not exist in the old array, then it was created.\n\t\t\t\tif (objectId !== undefined && oldObjArrayItemIdsToIndex.has(objectId) === false) {\n\t\t\t\t\tdiffs.push({\n\t\t\t\t\t\ttype: \"CREATE\",\n\t\t\t\t\t\tpath: [path],\n\t\t\t\t\t\tvalue: newObjValue,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t}\n\treturn diffs;\n}\n\n/**\n * Type Guard that determines if a given object is an array of type unknown[] or {@link TreeArrayNode}.\n */\nfunction isArrayOrTreeArrayNode(obj: unknown): obj is unknown[] | TreeArrayNode {\n\tif (typeof obj === \"object\" && obj !== null) {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\tconst maybeNodeKind: unknown = Object.getPrototypeOf(obj)?.constructor?.kind;\n\t\tconst isTreeArrayNode = maybeNodeKind === NodeKind.Array;\n\t\treturn Array.isArray(obj) || isTreeArrayNode;\n\t}\n\treturn false;\n}\n\n/**\n * Helper that creates a map of object ids to their index in an array of objects.\n */\nfunction createObjectArrayItemIdsToIndexMap(\n\tobj: unknown[],\n\tidAttributeName: string | number,\n): Map<string | number, number> {\n\tconst objArrayItemIdsToIndex = new Map<string | number, number>();\n\tfor (let i = 0; i < obj.length; i++) {\n\t\tconst objArrayItem = obj[i];\n\t\tif (typeof objArrayItem === \"object\" && objArrayItem !== null) {\n\t\t\tconst id = (objArrayItem as Record<string, unknown>)[idAttributeName] as string | number;\n\t\t\tif (objArrayItemIdsToIndex.has(id)) {\n\t\t\t\tthrow new TypeError(`Duplicate object id found: ${id}`);\n\t\t\t} else if (id !== undefined) {\n\t\t\t\tobjArrayItemIdsToIndex.set(id, i);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn objArrayItemIdsToIndex;\n}\n\n/**\n * Creates a set of mergeable diffs from a series of diffs produced by {@link sharedTreeDiff}\n * that are using the object ID strategy. These diffs don't need any modifications to be applied to the old object.\n *\n * @alpha\n */\nexport function createMergableIdDiffSeries(\n\toldObject: unknown,\n\tdiffs: Difference[],\n\tidAttributeName: string | number,\n): Difference[] {\n\t// the final series of diffs that will be returned.\n\tconst finalDiffSeries: Difference[] = [];\n\t// Diffs that aren't of type 'CHANGE'\n\tconst nonChangeDiffs: Difference[] = [];\n\n\tfor (const diff of diffs) {\n\t\tif (diff.type === \"CHANGE\") {\n\t\t\t// Changes must be applied before any other diff, ao so they are ordered first.\n\t\t\tfinalDiffSeries.push({ ...diff });\n\t\t} else {\n\t\t\tnonChangeDiffs.push({ ...diff });\n\t\t}\n\t}\n\n\t// Create sets of array diffs grouped by the array they are applying changes to.\n\tconst diffsByArrayUuid = new Map<string, Difference[]>();\n\tfor (const diff of nonChangeDiffs) {\n\t\tif (!isDiffOnArray(diff)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst arrayUuid = arrayUuidFromPath(diff.path);\n\n\t\tif (diffsByArrayUuid.has(arrayUuid) === false) {\n\t\t\tdiffsByArrayUuid.set(arrayUuid, []);\n\t\t}\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tdiffsByArrayUuid.get(arrayUuid)!.push(diff);\n\t}\n\n\tconst shiftIndexesFromMove = (\n\t\tdiff: DifferenceMove,\n\t\ttargetArray: unknown[],\n\t\tdiffAdjustedObjectIndexes: Map<string | number, number>,\n\t\tobjectId: string | number,\n\t): void => {\n\t\tconst sourceIndex = diff.path[diff.path.length - 1] as number;\n\n\t\tif (diff.newIndex > sourceIndex) {\n\t\t\t// This move diff shifts objects it moved over to the left.\n\t\t\t// |----| |----|\n\t\t\t// e.g. - shift with no length change: [{1}, {2}, {3}, {4}] -> [{2}, {3}, {1}, {4}]\n\t\t\tconst minIndex = sourceIndex;\n\t\t\tconst maxIndex = diff.newIndex;\n\t\t\tfor (const [id, index] of diffAdjustedObjectIndexes.entries()) {\n\t\t\t\tconst shouldIndexBeShifted =\n\t\t\t\t\tid !== objectId && index <= maxIndex && index >= minIndex && index - 1 >= 0;\n\t\t\t\tif (shouldIndexBeShifted) {\n\t\t\t\t\tdiffAdjustedObjectIndexes.set(id, index - 1);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (diff.newIndex < sourceIndex) {\n\t\t\t// This move diff shifts objects it moved over to the right.\n\t\t\t// |----| |----|\n\t\t\t// e.g. - shift with no length change: [{1}, {2}, {3}, {4}] -> [{3}, {1}, {2}, {4}]\n\t\t\tconst minIndex = diff.newIndex;\n\t\t\tconst maxIndex = sourceIndex;\n\t\t\tfor (const [id, index] of diffAdjustedObjectIndexes.entries()) {\n\t\t\t\tconst shouldIndexBeShifted =\n\t\t\t\t\tid !== objectId &&\n\t\t\t\t\tindex <= maxIndex &&\n\t\t\t\t\tindex >= minIndex &&\n\t\t\t\t\tindex + 1 <= targetArray.length;\n\t\t\t\tif (shouldIndexBeShifted) {\n\t\t\t\t\tdiffAdjustedObjectIndexes.set(id, index + 1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tconst shiftIndexesFromRemove = (\n\t\tdiff: DifferenceRemove,\n\t\tdiffAdjustedObjectIndexes: Map<string | number, number>,\n\t\tobjectId: string | number,\n\t): void => {\n\t\tconst removalIndex = diff.path[diff.path.length - 1] as number;\n\t\tfor (const [id, index] of diffAdjustedObjectIndexes.entries()) {\n\t\t\tconst shouldIndexBeShifted = id !== objectId && index > removalIndex && index - 1 >= 0;\n\t\t\tif (shouldIndexBeShifted) {\n\t\t\t\tdiffAdjustedObjectIndexes.set(id, index - 1);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst diffsMarkedForRemoval = new Set<Difference>();\n\tconst arrayDiffsMarkedForEndReorder = new Map<string, Difference[]>();\n\n\tfor (const [arrayUuid, arrayDiffs] of diffsByArrayUuid.entries()) {\n\t\t// The prior grouping code ensures that each map value will have atleast 1 diff.\n\t\tconst targetArray = getTargetObjectFromPath(\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tarrayDiffs[0]!.path,\n\t\t\toldObject as TreeArrayNode,\n\t\t) as unknown[];\n\t\tconst diffAdjustedObjectIndexes: Map<string | number, number> =\n\t\t\tcreateObjectArrayItemIdsToIndexMap(targetArray, idAttributeName);\n\n\t\tfor (const diff of arrayDiffs) {\n\t\t\tif (diff.type === \"MOVE\") {\n\t\t\t\tconst objectId = (diff.value as Record<string, unknown>)[idAttributeName] as\n\t\t\t\t\t| string\n\t\t\t\t\t| number;\n\t\t\t\tconst sourceIndex = diff.path[diff.path.length - 1] as number;\n\n\t\t\t\t// 1. Prior moves may render the next move redundant.\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tconst currentAdjustedIndex = diffAdjustedObjectIndexes.get(objectId)!;\n\t\t\t\tif (currentAdjustedIndex === diff.newIndex) {\n\t\t\t\t\tdiffsMarkedForRemoval.add(diff);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (currentAdjustedIndex !== sourceIndex) {\n\t\t\t\t\t// A Prior Remove or Move Diff moved the object to a new index, so update the diff source index to point to the new index.\n\t\t\t\t\tdiff.path[diff.path.length - 1] = currentAdjustedIndex;\n\t\t\t\t}\n\n\t\t\t\t// Handle index shifts\n\t\t\t\tdiffAdjustedObjectIndexes.set(objectId, diff.newIndex);\n\n\t\t\t\t// edge case: this MOVE should be applied after some series of creates that we haven't seen.\n\t\t\t\tif (diff.newIndex > targetArray.length - 1) {\n\t\t\t\t\t// It also wont shift any indexes since its moved to the total end of the array,\n\t\t\t\t\t// after creations that produce the necessary indexes.\n\t\t\t\t\tif (arrayDiffsMarkedForEndReorder.has(arrayUuid) === false) {\n\t\t\t\t\t\tarrayDiffsMarkedForEndReorder.set(arrayUuid, []);\n\t\t\t\t\t}\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\tarrayDiffsMarkedForEndReorder.get(arrayUuid)!.push(diff);\n\t\t\t\t} else {\n\t\t\t\t\tshiftIndexesFromMove(diff, targetArray, diffAdjustedObjectIndexes, objectId);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (diff.type === \"REMOVE\") {\n\t\t\t\tconst objectId = (diff.oldValue as Record<string, unknown>)[idAttributeName] as\n\t\t\t\t\t| string\n\t\t\t\t\t| number;\n\t\t\t\tconst targetIndex = diff.path[diff.path.length - 1] as number;\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tconst currentDiffAdjustedIndex = diffAdjustedObjectIndexes.get(objectId)!;\n\t\t\t\tif (targetIndex !== diffAdjustedObjectIndexes.get(objectId)) {\n\t\t\t\t\t// A Prior Remove or Move Diff moved the object to a new index, so update the diff source index to point to the new index.\n\t\t\t\t\tdiff.path[diff.path.length - 1] = currentDiffAdjustedIndex;\n\t\t\t\t}\n\n\t\t\t\tshiftIndexesFromRemove(diff, diffAdjustedObjectIndexes, objectId);\n\t\t\t}\n\n\t\t\t// Ignoring 'CREATE' for now.\n\t\t}\n\t}\n\n\tfor (let i = 0; i < nonChangeDiffs.length; i++) {\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tconst diff = nonChangeDiffs[i]!;\n\n\t\tif (diffsMarkedForRemoval.has(diff)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst isLastDiffInArraySeries = (currentIndex: number): boolean => {\n\t\t\tif (currentIndex === nonChangeDiffs.length - 1) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tconst nextIndex = currentIndex + 1;\n\t\t\tif (nextIndex <= nonChangeDiffs.length - 1) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tconst diffAfter = nonChangeDiffs[nextIndex]!;\n\n\t\t\t\tif (diffsMarkedForRemoval.has(diffAfter)) {\n\t\t\t\t\treturn isLastDiffInArraySeries(nextIndex + 1);\n\t\t\t\t}\n\n\t\t\t\tconst arrayUuidAfter = arrayUuidFromPath(diffAfter.path);\n\t\t\t\tconst arrayUuid = arrayUuidFromPath(diff.path);\n\t\t\t\tif (arrayUuidAfter === arrayUuid) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t};\n\n\t\tif (isDiffOnArray(diff)) {\n\t\t\tconst arrayUuid = arrayUuidFromPath(diff.path);\n\t\t\tconst endReorderDiffs = arrayDiffsMarkedForEndReorder.get(arrayUuid);\n\t\t\tconst isDiffMarkedForReorder = endReorderDiffs?.includes(diff) ?? false;\n\n\t\t\tif (isDiffMarkedForReorder === false) {\n\t\t\t\tfinalDiffSeries.push(diff);\n\t\t\t}\n\n\t\t\tif (isLastDiffInArraySeries(i) && endReorderDiffs !== undefined) {\n\t\t\t\tfinalDiffSeries.push(...endReorderDiffs);\n\t\t\t}\n\n\t\t\tcontinue;\n\t\t}\n\n\t\tfinalDiffSeries.push(diff);\n\t}\n\n\treturn finalDiffSeries;\n}\n\n/**\n * Creates a set of mergeable diffs from a series of diffs produced by {@link sharedTreeDiff}\n * that AREN'T using the object ID strategy. These diffs don't need any modifications to be applied to the old object.\n *\n * @alpha\n */\nexport function createMergableDiffSeries(diffs: Difference[]): Difference[] {\n\t// the final series of diffs that will be returned.\n\tconst finalDiffSeries: Difference[] = [];\n\t// Diffs that aren't of type 'CHANGE'\n\tconst nonChangeDiffs: Difference[] = [];\n\n\tfor (const diff of diffs) {\n\t\tif (diff.type === \"CHANGE\") {\n\t\t\t// Changes must be applied before any other diff, ao so they are ordered first.\n\t\t\tfinalDiffSeries.push({ ...diff });\n\t\t} else {\n\t\t\tnonChangeDiffs.push({ ...diff });\n\t\t}\n\t}\n\n\tfinalDiffSeries.push(...nonChangeDiffs);\n\n\treturn finalDiffSeries;\n}\n\n/**\n * Creates a UUID for the target array from a {@link Difference}'s ${@link ObjectPath}\n */\nfunction arrayUuidFromPath(path: ObjectPath): string {\n\treturn path.length === 1 ? \"\" : path.slice(0, -1).join(\"\");\n}\n\n/**\n * Determines if a given difference is on an array.\n */\nexport function isDiffOnArray(diff: Difference): boolean {\n\treturn typeof diff.path[diff.path.length - 1] === \"number\";\n}\n\n/**\n * Returns the target object that the given diff should be applied to.\n */\nfunction getTargetObjectFromPath(\n\tpath: ObjectPath,\n\tobject: Record<string, unknown> | TreeArrayNode,\n): unknown {\n\tlet targetObject: unknown = object;\n\tif (path.length > 1) {\n\t\ttargetObject = sharedTreeTraverse(object, path.slice(0, -1));\n\t}\n\treturn targetObject;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sharedTreeDiff.js","sourceRoot":"","sources":["../../src/implicit-strategy/sharedTreeDiff.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { type TreeArrayNode, NodeKind } from \"@fluidframework/tree\";\n\nimport { isTreeMapNode, sharedTreeTraverse } from \"./utils.js\";\n\n/**\n * Represents a path through a tree of objects.\n * number values represent array indices whereas string values represent object keys.\n *\n * @alpha\n */\nexport type ObjectPath = (string | number)[];\n\n/**\n * Represents a create operation between two branches of a tree.\n * Meaning that an attribute (a shared tree node) was identified as being created.\n *\n * @alpha\n */\nexport interface DifferenceCreate {\n\ttype: \"CREATE\";\n\tpath: ObjectPath;\n\tvalue: unknown;\n}\n\n/**\n * Represents a remove operation between two branches of a tree.\n * Meaning that an attribute (a shared tree node) was identified as being deleted.\n * When using object ids, removes are idenitified by an object with a given id no longer existing.\n *\n * @alpha\n */\nexport interface DifferenceRemove {\n\ttype: \"REMOVE\";\n\tpath: ObjectPath;\n\toldValue: unknown;\n\tobjectId?: string | number | undefined;\n}\n\n/**\n * Represents a change operation between two branches of a tree.\n * Meaning that an attribute (a shared tree node) was identified as being changed from one value to another.\n *\n * @alpha\n */\nexport interface DifferenceChange {\n\ttype: \"CHANGE\";\n\tpath: ObjectPath;\n\tvalue: unknown;\n\toldValue: unknown;\n\tobjectId?: string | number | undefined;\n}\n\n/**\n * Represents a move operation between two branches of a tree.\n * Meaning that an object (shared tree node) was identified as being moved from one index to another based on its unique id.\n *\n * @alpha\n */\nexport interface DifferenceMove {\n\ttype: \"MOVE\";\n\tpath: ObjectPath;\n\tnewIndex: number;\n\tvalue: unknown;\n\tobjectId?: string | number | undefined;\n}\n\n/**\n * Union for all possible difference types.\n *\n * @alpha\n */\nexport type Difference =\n\t| DifferenceCreate\n\t| DifferenceRemove\n\t| DifferenceChange\n\t| DifferenceMove;\n\n/**\n * Options for tree diffing.\n * @alpha\n */\nexport interface Options {\n\tcyclesFix: boolean;\n\tuseObjectIds?:\n\t\t| {\n\t\t\t\tidAttributeName: string;\n\t\t }\n\t\t| undefined;\n}\n\nconst richTypes = { Date: true, RegExp: true, String: true, Number: true };\n\n/**\n * By default, Object Diff supports cyclical references, but if you are sure that the object has no cycles like parsed JSON\n * you can disable cycles by setting the cyclesFix option to false\n */\nconst DEFAULT_OPTIONS: Options = { cyclesFix: true };\n\n/**\n * Compares two objects and returns an array of differences between them.\n *\n * @alpha\n */\nexport function sharedTreeDiff(\n\tobj: Record<string, unknown> | unknown[],\n\tnewObj: Record<string, unknown> | unknown[],\n\toptions: Options = DEFAULT_OPTIONS,\n\t_stack: (Record<string, unknown> | unknown[])[] = [],\n): Difference[] {\n\tconst diffs: Difference[] = [];\n\tconst isObjArray = isArrayOrTreeArrayNode(obj);\n\tconst isNewObjArray = isArrayOrTreeArrayNode(newObj);\n\n\t// If useObjectIds is set, we'll create a map of object ids to their index in the array.\n\tconst oldObjArrayItemIdsToIndex =\n\t\tisObjArray === false || options.useObjectIds === undefined\n\t\t\t? new Map<string | number, number>()\n\t\t\t: createObjectArrayItemIdsToIndexMap(obj, options.useObjectIds.idAttributeName);\n\n\tconst newObjArrayItemIdsToIndex =\n\t\tisNewObjArray === false || options.useObjectIds === undefined\n\t\t\t? new Map<string | number, number>()\n\t\t\t: createObjectArrayItemIdsToIndexMap(newObj, options.useObjectIds.idAttributeName);\n\n\tconst objectKeys = isTreeMapNode(obj) ? obj.keys() : Object.keys(obj);\n\t// We compare existence and values of all attributes within the old against new object, looking for removals or changes.\n\tfor (const key of objectKeys) {\n\t\tconst objValue: unknown = isTreeMapNode(obj) ? obj.get(key as string) : obj[key];\n\t\tconst path = isObjArray ? +key : key;\n\t\t// 1. First, check if the key within the old object, exists within the new object. If it doesn't exist this would be an attribute removal.\n\t\tif (!(key in newObj)) {\n\t\t\tif (options.useObjectIds === undefined) {\n\t\t\t\tdiffs.push({\n\t\t\t\t\ttype: \"REMOVE\",\n\t\t\t\t\tpath: [path],\n\t\t\t\t\tobjectId: undefined,\n\t\t\t\t\toldValue: objValue,\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// If we're dealing with an object in an array, we can use the object's id to check if it was moved to a new index.\n\t\t\telse if (\n\t\t\t\tisNewObjArray === true &&\n\t\t\t\tisObjArray &&\n\t\t\t\ttypeof objValue === \"object\" &&\n\t\t\t\tobjValue !== null\n\t\t\t) {\n\t\t\t\tconst objectId = objValue[options.useObjectIds.idAttributeName] as\n\t\t\t\t\t| string\n\t\t\t\t\t| number\n\t\t\t\t\t| undefined;\n\t\t\t\tif (objectId !== undefined && newObjArrayItemIdsToIndex.has(objectId)) {\n\t\t\t\t\t// The index no longer exists in the new root object array, however the object that lived at this index actually still exists at a new index.\n\t\t\t\t\t// Therefore, this node was moved to a new index.\n\t\t\t\t\tdiffs.push({\n\t\t\t\t\t\ttype: \"MOVE\",\n\t\t\t\t\t\tpath: [path],\n\t\t\t\t\t\tnewIndex: newObjArrayItemIdsToIndex.get(objectId) as number,\n\t\t\t\t\t\tvalue: objValue,\n\t\t\t\t\t\tobjectId,\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// The object with the given id cannot be found within the new array, therefore it was removed.\n\t\t\t\telse {\n\t\t\t\t\tdiffs.push({\n\t\t\t\t\t\ttype: \"REMOVE\",\n\t\t\t\t\t\tpath: [path],\n\t\t\t\t\t\tobjectId,\n\t\t\t\t\t\toldValue: objValue,\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If we're not dealing with an object in an array, we can't use id's to check for a move.\n\t\t\t// We'll assume that a missing key in the new object means that the cooresponding value was removed.\n\t\t\telse {\n\t\t\t\tdiffs.push({\n\t\t\t\t\ttype: \"REMOVE\",\n\t\t\t\t\tpath: [path],\n\t\t\t\t\tobjectId: undefined,\n\t\t\t\t\toldValue: objValue,\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tconst newObjValue: unknown = newObj[key];\n\t\tconst areCompatibleObjects =\n\t\t\ttypeof objValue === \"object\" &&\n\t\t\ttypeof newObjValue === \"object\" &&\n\t\t\tisArrayOrTreeArrayNode(objValue) === isArrayOrTreeArrayNode(newObjValue);\n\n\t\t// 2a. If the given old object key exists in the new object, and the value of said key in both objects is ANOTHER nested object, we need to run a recursive diff check on them.\n\t\tif (\n\t\t\tobjValue !== null &&\n\t\t\tnewObjValue !== null &&\n\t\t\tareCompatibleObjects &&\n\t\t\t// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/no-unsafe-member-access\n\t\t\t!richTypes[Object.getPrototypeOf(objValue)?.constructor?.name] &&\n\t\t\t(!options.cyclesFix || !_stack.includes(objValue as Record<string, unknown>))\n\t\t) {\n\t\t\tif (options.useObjectIds === undefined) {\n\t\t\t\tconst nestedDiffs = sharedTreeDiff(\n\t\t\t\t\tobjValue as Record<string, unknown> | unknown[],\n\t\t\t\t\tnewObjValue as Record<string, unknown> | unknown[],\n\t\t\t\t\toptions,\n\t\t\t\t\toptions.cyclesFix === true\n\t\t\t\t\t\t? [..._stack, objValue as Record<string, unknown> | unknown[]]\n\t\t\t\t\t\t: [],\n\t\t\t\t);\n\t\t\t\t// eslint-disable-next-line prefer-spread\n\t\t\t\tdiffs.push.apply(\n\t\t\t\t\tdiffs,\n\t\t\t\t\tnestedDiffs.map((difference) => {\n\t\t\t\t\t\tdifference.path.unshift(path);\n\t\t\t\t\t\treturn difference;\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Use Object Id strategy to determine if the objects should be compared for changes\n\t\t\telse {\n\t\t\t\tconst oldObjectId = (objValue as Record<string, unknown>)[\n\t\t\t\t\toptions.useObjectIds.idAttributeName\n\t\t\t\t] as string | number | undefined;\n\t\t\t\tconst newObjectId = (newObjValue as Record<string, unknown>)[\n\t\t\t\t\toptions.useObjectIds.idAttributeName\n\t\t\t\t] as string | number | undefined;\n\n\t\t\t\tif (oldObjectId !== undefined && newObjectId !== undefined) {\n\t\t\t\t\t// 2a.1 if the object id's are the same, we can continue a comparison between the two objects.\n\t\t\t\t\tif (oldObjectId === newObjectId) {\n\t\t\t\t\t\tconst nestedDiffs = sharedTreeDiff(\n\t\t\t\t\t\t\tobjValue as Record<string, unknown> | unknown[],\n\t\t\t\t\t\t\tnewObjValue as Record<string, unknown> | unknown[],\n\t\t\t\t\t\t\toptions,\n\t\t\t\t\t\t\toptions.cyclesFix === true\n\t\t\t\t\t\t\t\t? [..._stack, objValue as Record<string, unknown> | unknown[]]\n\t\t\t\t\t\t\t\t: [],\n\t\t\t\t\t\t);\n\t\t\t\t\t\tdiffs.push(\n\t\t\t\t\t\t\t...nestedDiffs.map((difference) => {\n\t\t\t\t\t\t\t\tdifference.path.unshift(path);\n\t\t\t\t\t\t\t\treturn difference;\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\t// 2a.2 The object id's are different, their attributes cannot be compared.\n\t\t\t\t\t// We need to find the new index of the object, if it exists in the new array and do a diff comparison.\n\t\t\t\t\telse {\n\t\t\t\t\t\tconst newIndexOfOldObject = newObjArrayItemIdsToIndex.get(oldObjectId);\n\t\t\t\t\t\t// The object no longer exists in the new array, therefore it was removed.\n\t\t\t\t\t\tif (newIndexOfOldObject === undefined) {\n\t\t\t\t\t\t\tdiffs.push({\n\t\t\t\t\t\t\t\ttype: \"REMOVE\",\n\t\t\t\t\t\t\t\tpath: [path],\n\t\t\t\t\t\t\t\toldValue: objValue,\n\t\t\t\t\t\t\t\tobjectId: oldObjectId,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// This object still exists but at a new index within the new array therefore it was moved.\n\t\t\t\t\t\t// At this point we can determine whether a new move is necessary or there is one that will place it at the desired index.\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tdiffs.push({\n\t\t\t\t\t\t\t\ttype: \"MOVE\",\n\t\t\t\t\t\t\t\tpath: [path],\n\t\t\t\t\t\t\t\tnewIndex: newIndexOfOldObject,\n\t\t\t\t\t\t\t\tvalue: objValue,\n\t\t\t\t\t\t\t\tobjectId: oldObjectId,\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t// An object could have been moved AND changed. We need to check for this.\n\t\t\t\t\t\t\tconst nestedDiffs = sharedTreeDiff(\n\t\t\t\t\t\t\t\tobj[path] as Record<string, unknown> | unknown[],\n\t\t\t\t\t\t\t\tnewObj[newIndexOfOldObject] as Record<string, unknown> | unknown[],\n\t\t\t\t\t\t\t\toptions,\n\t\t\t\t\t\t\t\toptions.cyclesFix === true\n\t\t\t\t\t\t\t\t\t? [..._stack, objValue as Record<string, unknown> | unknown[]]\n\t\t\t\t\t\t\t\t\t: [],\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tdiffs.push(\n\t\t\t\t\t\t\t\t...nestedDiffs.map((difference) => {\n\t\t\t\t\t\t\t\t\tdifference.path.unshift(path);\n\t\t\t\t\t\t\t\t\treturn difference;\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}\n\t\t\t\t} else {\n\t\t\t\t\tconst nestedDiffs = sharedTreeDiff(\n\t\t\t\t\t\tobjValue as Record<string, unknown> | unknown[],\n\t\t\t\t\t\tnewObjValue as Record<string, unknown> | unknown[],\n\t\t\t\t\t\toptions,\n\t\t\t\t\t\toptions.cyclesFix === true\n\t\t\t\t\t\t\t? [..._stack, objValue as Record<string, unknown> | unknown[]]\n\t\t\t\t\t\t\t: [],\n\t\t\t\t\t);\n\t\t\t\t\tdiffs.push(\n\t\t\t\t\t\t...nestedDiffs.map((difference) => {\n\t\t\t\t\t\t\tdifference.path.unshift(path);\n\t\t\t\t\t\t\treturn difference;\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// 2b. If the given old object key exists in the new object, and the value of said key in both objects is NOT another nested object, we need to check if the values are the same.\n\t\telse if (\n\t\t\tobjValue !== newObjValue &&\n\t\t\t// treat NaN values as equivalent\n\t\t\t!(Number.isNaN(objValue) && Number.isNaN(newObjValue)) &&\n\t\t\t!(\n\t\t\t\tareCompatibleObjects &&\n\t\t\t\t(Number.isNaN(objValue)\n\t\t\t\t\t? // eslint-disable-next-line prefer-template, @typescript-eslint/no-base-to-string\n\t\t\t\t\t\tobjValue + \"\" === newObjValue + \"\"\n\t\t\t\t\t: // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n\t\t\t\t\t\t// @ts-ignore\n\t\t\t\t\t\t+objValue === +newObjValue)\n\t\t\t)\n\t\t) {\n\t\t\tdiffs.push({\n\t\t\t\tpath: [path],\n\t\t\t\ttype: \"CHANGE\",\n\t\t\t\tvalue: newObjValue,\n\t\t\t\toldValue: objValue,\n\t\t\t\tobjectId:\n\t\t\t\t\toptions.useObjectIds?.idAttributeName === undefined\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: (newObj[options.useObjectIds.idAttributeName] as string | number | undefined),\n\t\t\t});\n\t\t}\n\t}\n\n\t// 3. Finally, we check for new keys in the new object that did not exist in the old object.\n\t// The existence of new keys may signal new values or moved values.\n\tconst newObjKeys = isTreeMapNode(newObj) ? newObj.keys() : Object.keys(newObj);\n\tfor (const key of newObjKeys) {\n\t\tconst newObjValue: unknown = isTreeMapNode(newObj)\n\t\t\t? newObj.get(key as string)\n\t\t\t: newObj[key];\n\t\tconst path = isNewObjArray ? +key : key;\n\n\t\tconst isKeyInOldObject = isTreeMapNode(obj)\n\t\t\t? obj.has(key as string)\n\t\t\t: Object.keys(obj).includes(key as string);\n\t\tif (!isKeyInOldObject) {\n\t\t\tif (options.useObjectIds === undefined) {\n\t\t\t\tdiffs.push({\n\t\t\t\t\ttype: \"CREATE\",\n\t\t\t\t\tpath: [path],\n\t\t\t\t\tvalue: newObjValue,\n\t\t\t\t});\n\t\t\t}\n\t\t\t// If we're dealing with an object in an array, we can use the object's id to check if this new index actually\n\t\t\t// contains a prexisting object that was moved from an old index.\n\t\t\telse if (\n\t\t\t\tisObjArray === true &&\n\t\t\t\tisNewObjArray === true &&\n\t\t\t\ttypeof newObjValue === \"object\" &&\n\t\t\t\tnewObjValue !== null\n\t\t\t) {\n\t\t\t\tconst objectId = newObjValue[options.useObjectIds.idAttributeName] as\n\t\t\t\t\t| string\n\t\t\t\t\t| number\n\t\t\t\t\t| undefined;\n\t\t\t\tif (objectId !== undefined && oldObjArrayItemIdsToIndex.has(objectId)) {\n\t\t\t\t\t// The new root object array contains a new index, however the object that lives at this new index previously existed at an old index.\n\t\t\t\t\t// Therefore, this object was moved to a new index.\n\t\t\t\t\tdiffs.push({\n\t\t\t\t\t\ttype: \"MOVE\",\n\t\t\t\t\t\tpath: [path],\n\t\t\t\t\t\tnewIndex: newObjArrayItemIdsToIndex.get(objectId) as number,\n\t\t\t\t\t\tvalue: newObjValue,\n\t\t\t\t\t\tobjectId,\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// If either the object's id attribute does not exist or the original array does not contain an object with the given id\n\t\t\t\t// Then we assume this was a newly created object.\n\t\t\t\telse {\n\t\t\t\t\tdiffs.push({\n\t\t\t\t\t\ttype: \"CREATE\",\n\t\t\t\t\t\tpath: [path],\n\t\t\t\t\t\tvalue: newObjValue,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If we're not dealing with an object in an array, we can't use id's to check for a move.\n\t\t\t// We'll assume that a brand new key and value pair in the new object means that a new value was created.\n\t\t\telse {\n\t\t\t\tdiffs.push({\n\t\t\t\t\ttype: \"CREATE\",\n\t\t\t\t\tpath: [path],\n\t\t\t\t\tvalue: newObjValue,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (options.useObjectIds !== undefined) {\n\t\t\t// If we're dealing with an object in an array, we can use the object's id to check if this EXISTING index\n\t\t\t// houses a new object based on a newly encountered id.\n\t\t\tif (\n\t\t\t\tisObjArray === true &&\n\t\t\t\tisNewObjArray === true &&\n\t\t\t\ttypeof newObjValue === \"object\" &&\n\t\t\t\tnewObjValue !== null\n\t\t\t) {\n\t\t\t\tconst objectId = newObjValue[options.useObjectIds.idAttributeName] as\n\t\t\t\t\t| string\n\t\t\t\t\t| number\n\t\t\t\t\t| undefined;\n\t\t\t\t// If this object has an id and it does not exist in the old array, then it was created.\n\t\t\t\tif (objectId !== undefined && oldObjArrayItemIdsToIndex.has(objectId) === false) {\n\t\t\t\t\tdiffs.push({\n\t\t\t\t\t\ttype: \"CREATE\",\n\t\t\t\t\t\tpath: [path],\n\t\t\t\t\t\tvalue: newObjValue,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t}\n\treturn diffs;\n}\n\n/**\n * Type Guard that determines if a given object is an array of type unknown[] or {@link TreeArrayNode}.\n */\nfunction isArrayOrTreeArrayNode(obj: unknown): obj is unknown[] | TreeArrayNode {\n\tif (typeof obj === \"object\" && obj !== null) {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\tconst maybeNodeKind: unknown = Object.getPrototypeOf(obj)?.constructor?.kind;\n\t\tconst isTreeArrayNode = maybeNodeKind === NodeKind.Array;\n\t\treturn Array.isArray(obj) || isTreeArrayNode;\n\t}\n\treturn false;\n}\n\n/**\n * Helper that creates a map of object ids to their index in an array of objects.\n */\nfunction createObjectArrayItemIdsToIndexMap(\n\tobj: unknown[],\n\tidAttributeName: string | number,\n): Map<string | number, number> {\n\tconst objArrayItemIdsToIndex = new Map<string | number, number>();\n\tfor (let i = 0; i < obj.length; i++) {\n\t\tconst objArrayItem = obj[i];\n\t\tif (typeof objArrayItem === \"object\" && objArrayItem !== null) {\n\t\t\tconst id = (objArrayItem as Record<string, unknown>)[idAttributeName] as string | number;\n\t\t\tif (objArrayItemIdsToIndex.has(id)) {\n\t\t\t\tthrow new TypeError(`Duplicate object id found: ${id}`);\n\t\t\t} else if (id !== undefined) {\n\t\t\t\tobjArrayItemIdsToIndex.set(id, i);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn objArrayItemIdsToIndex;\n}\n\n/**\n * Creates a set of mergeable diffs from a series of diffs produced by {@link sharedTreeDiff}\n * that are using the object ID strategy. These diffs don't need any modifications to be applied to the old object.\n *\n * @alpha\n */\nexport function createMergableIdDiffSeries(\n\toldObject: unknown,\n\tdiffs: Difference[],\n\tidAttributeName: string | number,\n): Difference[] {\n\t// the final series of diffs that will be returned.\n\tconst finalDiffSeries: Difference[] = [];\n\t// Diffs that aren't of type 'CHANGE'\n\tconst nonChangeDiffs: Difference[] = [];\n\n\tfor (const diff of diffs) {\n\t\tif (diff.type === \"CHANGE\") {\n\t\t\t// Changes must be applied before any other diff, ao so they are ordered first.\n\t\t\tfinalDiffSeries.push({ ...diff });\n\t\t} else {\n\t\t\tnonChangeDiffs.push({ ...diff });\n\t\t}\n\t}\n\n\t// Create sets of array diffs grouped by the array they are applying changes to.\n\tconst diffsByArrayUuid = new Map<string, Difference[]>();\n\tfor (const diff of nonChangeDiffs) {\n\t\tif (!isDiffOnArray(diff)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst arrayUuid = arrayUuidFromPath(diff.path);\n\n\t\tif (diffsByArrayUuid.has(arrayUuid) === false) {\n\t\t\tdiffsByArrayUuid.set(arrayUuid, []);\n\t\t}\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tdiffsByArrayUuid.get(arrayUuid)!.push(diff);\n\t}\n\n\tconst shiftIndexesFromMove = (\n\t\tdiff: DifferenceMove,\n\t\ttargetArray: unknown[],\n\t\tdiffAdjustedObjectIndexes: Map<string | number, number>,\n\t\tobjectId: string | number,\n\t): void => {\n\t\tconst sourceIndex = diff.path[diff.path.length - 1] as number;\n\n\t\tif (diff.newIndex > sourceIndex) {\n\t\t\t// This move diff shifts objects it moved over to the left.\n\t\t\t// |----| |----|\n\t\t\t// e.g. - shift with no length change: [{1}, {2}, {3}, {4}] -> [{2}, {3}, {1}, {4}]\n\t\t\tconst minIndex = sourceIndex;\n\t\t\tconst maxIndex = diff.newIndex;\n\t\t\tfor (const [id, index] of diffAdjustedObjectIndexes.entries()) {\n\t\t\t\tconst shouldIndexBeShifted =\n\t\t\t\t\tid !== objectId && index <= maxIndex && index >= minIndex && index - 1 >= 0;\n\t\t\t\tif (shouldIndexBeShifted) {\n\t\t\t\t\tdiffAdjustedObjectIndexes.set(id, index - 1);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (diff.newIndex < sourceIndex) {\n\t\t\t// This move diff shifts objects it moved over to the right.\n\t\t\t// |----| |----|\n\t\t\t// e.g. - shift with no length change: [{1}, {2}, {3}, {4}] -> [{3}, {1}, {2}, {4}]\n\t\t\tconst minIndex = diff.newIndex;\n\t\t\tconst maxIndex = sourceIndex;\n\t\t\tfor (const [id, index] of diffAdjustedObjectIndexes.entries()) {\n\t\t\t\tconst shouldIndexBeShifted =\n\t\t\t\t\tid !== objectId &&\n\t\t\t\t\tindex <= maxIndex &&\n\t\t\t\t\tindex >= minIndex &&\n\t\t\t\t\tindex + 1 <= targetArray.length;\n\t\t\t\tif (shouldIndexBeShifted) {\n\t\t\t\t\tdiffAdjustedObjectIndexes.set(id, index + 1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tconst shiftIndexesFromRemove = (\n\t\tdiff: DifferenceRemove,\n\t\tdiffAdjustedObjectIndexes: Map<string | number, number>,\n\t\tobjectId: string | number,\n\t): void => {\n\t\tconst removalIndex = diff.path[diff.path.length - 1] as number;\n\t\tfor (const [id, index] of diffAdjustedObjectIndexes.entries()) {\n\t\t\tconst shouldIndexBeShifted = id !== objectId && index > removalIndex && index - 1 >= 0;\n\t\t\tif (shouldIndexBeShifted) {\n\t\t\t\tdiffAdjustedObjectIndexes.set(id, index - 1);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst diffsMarkedForRemoval = new Set<Difference>();\n\tconst arrayDiffsMarkedForEndReorder = new Map<string, Difference[]>();\n\n\tfor (const [arrayUuid, arrayDiffs] of diffsByArrayUuid.entries()) {\n\t\t// The prior grouping code ensures that each map value will have atleast 1 diff.\n\t\tconst targetArray = getTargetObjectFromPath(\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tarrayDiffs[0]!.path,\n\t\t\toldObject as TreeArrayNode,\n\t\t) as unknown[];\n\t\tconst diffAdjustedObjectIndexes: Map<string | number, number> =\n\t\t\tcreateObjectArrayItemIdsToIndexMap(targetArray, idAttributeName);\n\n\t\tfor (const diff of arrayDiffs) {\n\t\t\tif (diff.type === \"MOVE\") {\n\t\t\t\tconst objectId = (diff.value as Record<string, unknown>)[idAttributeName] as\n\t\t\t\t\t| string\n\t\t\t\t\t| number;\n\t\t\t\tconst sourceIndex = diff.path[diff.path.length - 1] as number;\n\n\t\t\t\t// 1. Prior moves may render the next move redundant.\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tconst currentAdjustedIndex = diffAdjustedObjectIndexes.get(objectId)!;\n\t\t\t\tif (currentAdjustedIndex === diff.newIndex) {\n\t\t\t\t\tdiffsMarkedForRemoval.add(diff);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (currentAdjustedIndex !== sourceIndex) {\n\t\t\t\t\t// A Prior Remove or Move Diff moved the object to a new index, so update the diff source index to point to the new index.\n\t\t\t\t\tdiff.path[diff.path.length - 1] = currentAdjustedIndex;\n\t\t\t\t}\n\n\t\t\t\t// Handle index shifts\n\t\t\t\tdiffAdjustedObjectIndexes.set(objectId, diff.newIndex);\n\n\t\t\t\t// edge case: this MOVE should be applied after some series of creates that we haven't seen.\n\t\t\t\tif (diff.newIndex > targetArray.length - 1) {\n\t\t\t\t\t// It also wont shift any indexes since its moved to the total end of the array,\n\t\t\t\t\t// after creations that produce the necessary indexes.\n\t\t\t\t\tif (arrayDiffsMarkedForEndReorder.has(arrayUuid) === false) {\n\t\t\t\t\t\tarrayDiffsMarkedForEndReorder.set(arrayUuid, []);\n\t\t\t\t\t}\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\tarrayDiffsMarkedForEndReorder.get(arrayUuid)!.push(diff);\n\t\t\t\t} else {\n\t\t\t\t\tshiftIndexesFromMove(diff, targetArray, diffAdjustedObjectIndexes, objectId);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (diff.type === \"REMOVE\") {\n\t\t\t\tconst objectId = (diff.oldValue as Record<string, unknown>)[idAttributeName] as\n\t\t\t\t\t| string\n\t\t\t\t\t| number;\n\t\t\t\tconst targetIndex = diff.path[diff.path.length - 1] as number;\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tconst currentDiffAdjustedIndex = diffAdjustedObjectIndexes.get(objectId)!;\n\t\t\t\tif (targetIndex !== diffAdjustedObjectIndexes.get(objectId)) {\n\t\t\t\t\t// A Prior Remove or Move Diff moved the object to a new index, so update the diff source index to point to the new index.\n\t\t\t\t\tdiff.path[diff.path.length - 1] = currentDiffAdjustedIndex;\n\t\t\t\t}\n\n\t\t\t\tshiftIndexesFromRemove(diff, diffAdjustedObjectIndexes, objectId);\n\t\t\t}\n\n\t\t\t// Ignoring 'CREATE' for now.\n\t\t}\n\t}\n\n\tfor (let i = 0; i < nonChangeDiffs.length; i++) {\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tconst diff = nonChangeDiffs[i]!;\n\n\t\tif (diffsMarkedForRemoval.has(diff)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst isLastDiffInArraySeries = (currentIndex: number): boolean => {\n\t\t\tif (currentIndex === nonChangeDiffs.length - 1) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tconst nextIndex = currentIndex + 1;\n\t\t\tif (nextIndex <= nonChangeDiffs.length - 1) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tconst diffAfter = nonChangeDiffs[nextIndex]!;\n\n\t\t\t\tif (diffsMarkedForRemoval.has(diffAfter)) {\n\t\t\t\t\treturn isLastDiffInArraySeries(nextIndex + 1);\n\t\t\t\t}\n\n\t\t\t\tconst arrayUuidAfter = arrayUuidFromPath(diffAfter.path);\n\t\t\t\tconst arrayUuid = arrayUuidFromPath(diff.path);\n\t\t\t\tif (arrayUuidAfter === arrayUuid) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t};\n\n\t\tif (isDiffOnArray(diff)) {\n\t\t\tconst arrayUuid = arrayUuidFromPath(diff.path);\n\t\t\tconst endReorderDiffs = arrayDiffsMarkedForEndReorder.get(arrayUuid);\n\t\t\tconst isDiffMarkedForReorder = endReorderDiffs?.includes(diff) ?? false;\n\n\t\t\tif (isDiffMarkedForReorder === false) {\n\t\t\t\tfinalDiffSeries.push(diff);\n\t\t\t}\n\n\t\t\tif (isLastDiffInArraySeries(i) && endReorderDiffs !== undefined) {\n\t\t\t\tfinalDiffSeries.push(...endReorderDiffs);\n\t\t\t}\n\n\t\t\tcontinue;\n\t\t}\n\n\t\tfinalDiffSeries.push(diff);\n\t}\n\n\treturn finalDiffSeries;\n}\n\n/**\n * Creates a set of mergeable diffs from a series of diffs produced by {@link sharedTreeDiff}\n * that AREN'T using the object ID strategy. These diffs don't need any modifications to be applied to the old object.\n *\n * @alpha\n */\nexport function createMergableDiffSeries(diffs: Difference[]): Difference[] {\n\t// the final series of diffs that will be returned.\n\tconst finalDiffSeries: Difference[] = [];\n\t// Diffs that aren't of type 'CHANGE'\n\tconst nonChangeDiffs: Difference[] = [];\n\n\tfor (const diff of diffs) {\n\t\tif (diff.type === \"CHANGE\") {\n\t\t\t// Changes must be applied before any other diff, ao so they are ordered first.\n\t\t\tfinalDiffSeries.push({ ...diff });\n\t\t} else {\n\t\t\tnonChangeDiffs.push({ ...diff });\n\t\t}\n\t}\n\n\tfinalDiffSeries.push(...nonChangeDiffs);\n\n\treturn finalDiffSeries;\n}\n\n/**\n * Creates a UUID for the target array from a {@link Difference}'s ${@link ObjectPath}\n */\nfunction arrayUuidFromPath(path: ObjectPath): string {\n\treturn path.length === 1 ? \"\" : path.slice(0, -1).join(\"\");\n}\n\n/**\n * Determines if a given difference is on an array.\n */\nexport function isDiffOnArray(diff: Difference): boolean {\n\treturn typeof diff.path[diff.path.length - 1] === \"number\";\n}\n\n/**\n * Returns the target object that the given diff should be applied to.\n */\nfunction getTargetObjectFromPath(\n\tpath: ObjectPath,\n\tobject: Record<string, unknown> | TreeArrayNode,\n): unknown {\n\tlet targetObject: unknown = object;\n\tif (path.length > 1) {\n\t\ttargetObject = sharedTreeTraverse(object, path.slice(0, -1));\n\t}\n\treturn targetObject;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/ai-collab",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.74.0-365691",
|
|
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": "
|
|
73
|
-
"@fluidframework/runtime-utils": "
|
|
74
|
-
"@fluidframework/telemetry-utils": "
|
|
75
|
-
"@fluidframework/tree": "
|
|
72
|
+
"@fluidframework/core-utils": "2.74.0-365691",
|
|
73
|
+
"@fluidframework/runtime-utils": "2.74.0-365691",
|
|
74
|
+
"@fluidframework/telemetry-utils": "2.74.0-365691",
|
|
75
|
+
"@fluidframework/tree": "2.74.0-365691",
|
|
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": "
|
|
85
|
+
"@fluid-internal/mocha-test-setup": "2.74.0-365691",
|
|
86
86
|
"@fluid-tools/build-cli": "^0.60.0",
|
|
87
87
|
"@fluidframework/build-common": "^2.0.3",
|
|
88
88
|
"@fluidframework/build-tools": "^0.60.0",
|
|
89
|
-
"@fluidframework/eslint-config-fluid": "
|
|
90
|
-
"@fluidframework/id-compressor": "
|
|
91
|
-
"@fluidframework/runtime-utils": "
|
|
92
|
-
"@fluidframework/test-runtime-utils": "
|
|
89
|
+
"@fluidframework/eslint-config-fluid": "2.74.0-365691",
|
|
90
|
+
"@fluidframework/id-compressor": "2.74.0-365691",
|
|
91
|
+
"@fluidframework/runtime-utils": "2.74.0-365691",
|
|
92
|
+
"@fluidframework/test-runtime-utils": "2.74.0-365691",
|
|
93
93
|
"@microsoft/api-extractor": "7.52.11",
|
|
94
94
|
"@types/mocha": "^10.0.10",
|
|
95
95
|
"@types/node": "^18.19.0",
|
|
@@ -239,8 +239,8 @@ export function applyAgentEdit(
|
|
|
239
239
|
}
|
|
240
240
|
// If the LLM attempts to use the wrong type for a field, we generate a useful error message that can be used as part of the feedback loop.
|
|
241
241
|
const isInvalidTypeError =
|
|
242
|
-
|
|
243
|
-
|
|
242
|
+
/The provided data is incompatible with all of the types allowed by the schema./.exec(
|
|
243
|
+
error.message,
|
|
244
244
|
) !== null;
|
|
245
245
|
if (isInvalidTypeError === true) {
|
|
246
246
|
const errorMessage = createInvalidModifyFeedbackMsg(
|
|
@@ -409,6 +409,7 @@ function createInvalidModifyFeedbackMsg(
|
|
|
409
409
|
} else if (errorType === "INVALID_TYPE") {
|
|
410
410
|
const allowedTypeIdentifiers = getAllowedTypeIdentifiers(modifyEdit.field);
|
|
411
411
|
// TODO: If the invalid modification is a new object, it won't be clear what part of the object is invalid for the given type. If we could give some more detailed guidance on what was wrong with the object it would be ideal.
|
|
412
|
+
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
412
413
|
messageSuffix = ` You cannot set the node's field \`${modifyEdit.field}\` to the value \`${modifyEdit.modification}\` with type \`${typeof modifyEdit.modification}\` because this type is incompatible with all of the types allowed by the field's schema. The set of allowed types are \`[${allowedTypeIdentifiers.map((id) => `'${id}'`).join(", ")}]\`.`;
|
|
413
414
|
}
|
|
414
415
|
|
|
@@ -308,7 +308,7 @@ function getDef(defs: Record<string, JsonNodeSchema>, ref: string): JsonNodeSche
|
|
|
308
308
|
* TBD
|
|
309
309
|
*/
|
|
310
310
|
export function getFriendlySchemaName(schemaName: string): string {
|
|
311
|
-
const matches =
|
|
311
|
+
const matches = /[^.]+$/.exec(schemaName);
|
|
312
312
|
if (matches === null) {
|
|
313
313
|
// empty scope
|
|
314
314
|
return schemaName;
|
|
@@ -317,7 +317,7 @@ export function sharedTreeDiff(
|
|
|
317
317
|
!(
|
|
318
318
|
areCompatibleObjects &&
|
|
319
319
|
(Number.isNaN(objValue)
|
|
320
|
-
? // eslint-disable-next-line prefer-template
|
|
320
|
+
? // eslint-disable-next-line prefer-template, @typescript-eslint/no-base-to-string
|
|
321
321
|
objValue + "" === newObjValue + ""
|
|
322
322
|
: // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
323
323
|
// @ts-ignore
|