@json-layout/core 2.8.2 → 2.9.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/package.json +4 -2
- package/src/compile/index.js +3 -1
- package/src/compile/skeleton-node.js +46 -5
- package/src/compile/types.ts +1 -0
- package/src/compile/utils/resolve-refs.js +5 -8
- package/src/compile/utils/x-i18n.js +15 -6
- package/src/state/index.js +18 -1
- package/src/state/state-node.js +11 -2
- package/src/state/utils/urls.js +2 -0
- package/src/utils/json-pointer.js +29 -0
- package/src/webmcp/README.md +144 -0
- package/src/webmcp/index.js +88 -82
- package/src/webmcp/project.js +479 -111
- package/src/webmcp/resolve.js +37 -1
- package/src/webmcp/schema.js +169 -0
- package/src/webmcp/suggestions-store.js +121 -0
- package/src/webmcp/tools/describe-state.js +20 -64
- package/src/webmcp/tools/edit-array.js +51 -28
- package/src/webmcp/tools/fill-form-skill.js +17 -41
- package/src/webmcp/tools/get-data.js +66 -13
- package/src/webmcp/tools/get-field-suggestions.js +12 -23
- package/src/webmcp/tools/set-data.js +79 -28
- package/src/webmcp/tools/set-field-value.js +49 -39
- package/src/webmcp/variants-memo.js +53 -0
- package/types/compile/index.d.ts.map +1 -1
- package/types/compile/skeleton-node.d.ts +9 -2
- package/types/compile/skeleton-node.d.ts.map +1 -1
- package/types/compile/types.d.ts +1 -0
- package/types/compile/types.d.ts.map +1 -1
- package/types/compile/utils/resolve-refs.d.ts.map +1 -1
- package/types/compile/utils/x-i18n.d.ts +1 -1
- package/types/compile/utils/x-i18n.d.ts.map +1 -1
- package/types/state/index.d.ts +10 -0
- package/types/state/index.d.ts.map +1 -1
- package/types/state/state-node.d.ts.map +1 -1
- package/types/state/utils/urls.d.ts.map +1 -1
- package/types/utils/json-pointer.d.ts +22 -0
- package/types/utils/json-pointer.d.ts.map +1 -0
- package/types/webmcp/index.d.ts +23 -15
- package/types/webmcp/index.d.ts.map +1 -1
- package/types/webmcp/project.d.ts +159 -57
- package/types/webmcp/project.d.ts.map +1 -1
- package/types/webmcp/resolve.d.ts +7 -3
- package/types/webmcp/resolve.d.ts.map +1 -1
- package/types/webmcp/schema.d.ts +44 -0
- package/types/webmcp/schema.d.ts.map +1 -0
- package/types/webmcp/suggestions-store.d.ts +82 -0
- package/types/webmcp/suggestions-store.d.ts.map +1 -0
- package/types/webmcp/tools/describe-state.d.ts +5 -57
- package/types/webmcp/tools/describe-state.d.ts.map +1 -1
- package/types/webmcp/tools/edit-array.d.ts +8 -37
- package/types/webmcp/tools/edit-array.d.ts.map +1 -1
- package/types/webmcp/tools/fill-form-skill.d.ts +10 -13
- package/types/webmcp/tools/fill-form-skill.d.ts.map +1 -1
- package/types/webmcp/tools/get-data.d.ts +17 -15
- package/types/webmcp/tools/get-data.d.ts.map +1 -1
- package/types/webmcp/tools/get-field-suggestions.d.ts +4 -30
- package/types/webmcp/tools/get-field-suggestions.d.ts.map +1 -1
- package/types/webmcp/tools/set-data.d.ts +17 -34
- package/types/webmcp/tools/set-data.d.ts.map +1 -1
- package/types/webmcp/tools/set-field-value.d.ts +20 -57
- package/types/webmcp/tools/set-field-value.d.ts.map +1 -1
- package/types/webmcp/variants-memo.d.ts +42 -0
- package/types/webmcp/variants-memo.d.ts.map +1 -0
|
@@ -2,16 +2,39 @@
|
|
|
2
2
|
* @file getData tool
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
import { resolveNode } from '../resolve.js'
|
|
6
|
+
|
|
7
|
+
/** Most field paths named in a refusal before the rest are counted instead. */
|
|
8
|
+
export const NAMED_FIELDS_MAX = 12
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The paths under a layout section that do own a place in the data.
|
|
12
|
+
*
|
|
13
|
+
* A section may nest more sections — an allOf inside a oneOf branch — so this walks past
|
|
14
|
+
* every wrapper until it reaches nodes whose value is their own, which are the paths the
|
|
15
|
+
* agent can actually read. Naming them is the difference between a refusal that redirects
|
|
16
|
+
* and one that just says no: calendar's agent gave up after being refused, charts had to
|
|
17
|
+
* guess its next path.
|
|
18
|
+
* @param {import('../../state/types.js').StateNode} node
|
|
19
|
+
* @param {string[]} [into]
|
|
20
|
+
* @returns {string[]}
|
|
21
|
+
*/
|
|
22
|
+
function dataOwningFields (node, into = []) {
|
|
23
|
+
for (const child of node.children ?? []) {
|
|
24
|
+
if (into.length > NAMED_FIELDS_MAX) return into
|
|
25
|
+
if (child.dataPath === node.dataPath) dataOwningFields(child, into)
|
|
26
|
+
else into.push(child.fullKey)
|
|
27
|
+
}
|
|
28
|
+
return into
|
|
8
29
|
}
|
|
9
30
|
|
|
10
|
-
export const
|
|
31
|
+
export const inputSchema = {
|
|
11
32
|
type: 'object',
|
|
12
33
|
properties: {
|
|
13
|
-
|
|
14
|
-
|
|
34
|
+
path: {
|
|
35
|
+
type: 'string',
|
|
36
|
+
description: 'Node path as returned by describeState (e.g. "/address/city"). Omit for the whole document.'
|
|
37
|
+
}
|
|
15
38
|
}
|
|
16
39
|
}
|
|
17
40
|
|
|
@@ -20,17 +43,47 @@ export const outputSchema = {
|
|
|
20
43
|
* @returns {string}
|
|
21
44
|
*/
|
|
22
45
|
export function getDescription (dataTitle) {
|
|
23
|
-
return `Get the current "${dataTitle}" data and validity status.`
|
|
46
|
+
return `Get the current "${dataTitle}" data and validity status. The data is always returned whole and unmodified, so on a large form pass "path" to read one part of it rather than the entire document.`
|
|
24
47
|
}
|
|
25
48
|
|
|
26
49
|
/**
|
|
50
|
+
* Read the data, whole or at a path. Whatever it returns is the real value: an agent may
|
|
51
|
+
* forward it to an API, so nothing here is ever abbreviated. `path` exists so that
|
|
52
|
+
* wanting one field is not a reason to pull a document that can run to tens of kilobytes.
|
|
27
53
|
* @param {import('../../state/index.js').StatefulLayout} statefulLayout
|
|
28
|
-
* @param {{}}
|
|
29
|
-
* @returns {{ data
|
|
54
|
+
* @param {{ path?: string }} args
|
|
55
|
+
* @returns {{ data?: unknown, unset?: boolean, valid: boolean }}
|
|
30
56
|
*/
|
|
31
|
-
export function execute (statefulLayout,
|
|
32
|
-
|
|
33
|
-
data: statefulLayout.data,
|
|
34
|
-
|
|
57
|
+
export function execute (statefulLayout, args) {
|
|
58
|
+
if (!args?.path) {
|
|
59
|
+
return { data: statefulLayout.data, valid: statefulLayout.valid }
|
|
60
|
+
}
|
|
61
|
+
const node = resolveNode(statefulLayout.stateTree.root, args.path)
|
|
62
|
+
if (!node) {
|
|
63
|
+
throw new Error(`node not found at path: ${args.path}`)
|
|
64
|
+
}
|
|
65
|
+
// A section a `$allOf`, `$oneOf` or `$comp-` wrapper introduces holds no data of its
|
|
66
|
+
// own: its value IS its parent's, so asking for it returns the document the `path`
|
|
67
|
+
// argument exists to avoid. charts asked for "/$allOf-1" and got the whole thing back,
|
|
68
|
+
// 29% of that run's bytes, with nothing in the answer to say the path had bought
|
|
69
|
+
// nothing. Refusing costs one short line and names where to go instead.
|
|
70
|
+
if (node.dataPath === node.parentDataPath) {
|
|
71
|
+
const owner = node.parentDataPath === '' ? 'the whole document' : `"${node.parentDataPath}"`
|
|
72
|
+
const fields = dataOwningFields(node)
|
|
73
|
+
const named = fields.length > NAMED_FIELDS_MAX
|
|
74
|
+
? `${fields.slice(0, NAMED_FIELDS_MAX).join(', ')} and ${fields.length - NAMED_FIELDS_MAX} more`
|
|
75
|
+
: fields.join(', ')
|
|
76
|
+
const instead = fields.length
|
|
77
|
+
? ` Read one of its fields instead: ${named}.`
|
|
78
|
+
: ''
|
|
79
|
+
throw new Error(`"${args.path}" is a layout section, it holds no data of its own — its value is the data of ${owner}.${instead} Omit "path" to read the document.`)
|
|
80
|
+
}
|
|
81
|
+
// JSON.stringify drops an undefined value, so an unset field would come back as a
|
|
82
|
+
// response with no "data" key at all — indistinguishable from a malformed answer.
|
|
83
|
+
if (node.data === undefined) {
|
|
84
|
+
return { unset: true, valid: statefulLayout.valid }
|
|
35
85
|
}
|
|
86
|
+
// The form's validity, not the node's: it is what an agent is deciding on, and a
|
|
87
|
+
// subtree that validates inside a form that does not would read as done.
|
|
88
|
+
return { data: node.data, valid: statefulLayout.valid }
|
|
36
89
|
}
|
|
@@ -9,7 +9,7 @@ export const inputSchema = {
|
|
|
9
9
|
properties: {
|
|
10
10
|
path: {
|
|
11
11
|
type: 'string',
|
|
12
|
-
description: '
|
|
12
|
+
description: 'Node path as returned by describeState (e.g. "/address/city").'
|
|
13
13
|
},
|
|
14
14
|
query: {
|
|
15
15
|
type: 'string',
|
|
@@ -19,37 +19,26 @@ export const inputSchema = {
|
|
|
19
19
|
required: ['path']
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export const outputSchema = {
|
|
23
|
-
type: 'object',
|
|
24
|
-
properties: {
|
|
25
|
-
items: {
|
|
26
|
-
type: 'array',
|
|
27
|
-
items: {
|
|
28
|
-
type: 'object',
|
|
29
|
-
properties: {
|
|
30
|
-
value: {},
|
|
31
|
-
title: { type: 'string' },
|
|
32
|
-
key: { type: 'string' }
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
22
|
/**
|
|
40
23
|
* @param {string} dataTitle
|
|
41
24
|
* @returns {string}
|
|
42
25
|
*/
|
|
43
26
|
export function getDescription (dataTitle) {
|
|
44
|
-
|
|
27
|
+
// The one statement of the suggestion protocol. It used to be said here, again in
|
|
28
|
+
// setFieldValue's description, a third time in that tool's suggestionIndex parameter and
|
|
29
|
+
// a fourth in the guide — 1114 bytes of the 5941 the model is sent, and four copies that
|
|
30
|
+
// had to agree. The trigger moved in from the guide so that the whole contract sits in
|
|
31
|
+
// the description of the tool it belongs to.
|
|
32
|
+
return `Get the accepted values of a field of "${dataTitle}" that describeState marked "suggestions", optionally filtered by a query. A field whose values describeState already stated on its line as values=[...] needs no call — write one of them. Each option comes back with an index and a title; one whose value is not a short scalar is listed by title alone, exactly as a user sees it. To choose one, call setFieldValue with the same path and "suggestionIndex" set to its index, and the full original value is applied.`
|
|
45
33
|
}
|
|
46
34
|
|
|
47
35
|
/**
|
|
48
36
|
* @param {import('../../state/index.js').StatefulLayout} statefulLayout
|
|
49
37
|
* @param {{ path: string, query?: string }} args
|
|
50
|
-
* @
|
|
38
|
+
* @param {import('../suggestions-store.js').SuggestionsStore} [store] - memorizes the full items so that setFieldValue can apply one by index
|
|
39
|
+
* @returns {Promise<{items: Array<{value: unknown, title: string, key?: string}>, baseIndex: number}>}
|
|
51
40
|
*/
|
|
52
|
-
export async function execute (statefulLayout, args) {
|
|
41
|
+
export async function execute (statefulLayout, args, store) {
|
|
53
42
|
const node = resolveNode(statefulLayout.stateTree.root, args.path)
|
|
54
43
|
if (!node) {
|
|
55
44
|
throw new Error(`node not found at path: ${args.path}`)
|
|
@@ -61,7 +50,7 @@ export async function execute (statefulLayout, args) {
|
|
|
61
50
|
const items = (oneOfItems || [])
|
|
62
51
|
.filter((item) => !item.header)
|
|
63
52
|
.map((item) => ({ value: item.key, title: item.title }))
|
|
64
|
-
return { items }
|
|
53
|
+
return { items, baseIndex: store?.add(args.path, items, node.itemsCacheKey) ?? 0 }
|
|
65
54
|
}
|
|
66
55
|
|
|
67
56
|
const rawItems = await statefulLayout.getItems(node, args.query)
|
|
@@ -80,5 +69,5 @@ export async function execute (statefulLayout, args) {
|
|
|
80
69
|
return result
|
|
81
70
|
})
|
|
82
71
|
|
|
83
|
-
return { items }
|
|
72
|
+
return { items, baseIndex: store?.add(args.path, items, node.itemsCacheKey) ?? 0 }
|
|
84
73
|
}
|
|
@@ -2,57 +2,108 @@
|
|
|
2
2
|
* @file setData tool
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { collectErrors } from '../project.js'
|
|
5
|
+
import { collectErrors, visibilitySnapshot, diffVisibility } from '../project.js'
|
|
6
6
|
|
|
7
7
|
export const inputSchema = {
|
|
8
8
|
type: 'object',
|
|
9
9
|
properties: {
|
|
10
10
|
data: {
|
|
11
11
|
description: 'The form data object to set'
|
|
12
|
+
},
|
|
13
|
+
merge: {
|
|
14
|
+
type: 'boolean',
|
|
15
|
+
description: 'Merge the given keys into the existing data (default). Set false to replace the whole object, which removes every key you do not pass.'
|
|
12
16
|
}
|
|
13
17
|
},
|
|
14
18
|
required: ['data']
|
|
15
19
|
}
|
|
16
20
|
|
|
17
|
-
export const outputSchema = {
|
|
18
|
-
type: 'object',
|
|
19
|
-
properties: {
|
|
20
|
-
valid: { type: 'boolean' },
|
|
21
|
-
errors: {
|
|
22
|
-
type: 'array',
|
|
23
|
-
items: {
|
|
24
|
-
type: 'object',
|
|
25
|
-
properties: {
|
|
26
|
-
path: { type: 'string' },
|
|
27
|
-
message: { type: 'string' }
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
21
|
/**
|
|
35
22
|
* @param {string} dataTitle
|
|
36
|
-
* @param {"small"|"medium"|"large"} [complexity]
|
|
37
23
|
* @returns {string}
|
|
38
24
|
*/
|
|
39
|
-
export function getDescription (dataTitle
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
25
|
+
export function getDescription (dataTitle) {
|
|
26
|
+
return `Set all "${dataTitle}" data at once, for when you already know every value. Prefer setFieldValue to change one field. Check the errors in the response.`
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Root-level data keys the form actually carries.
|
|
31
|
+
*
|
|
32
|
+
* Read from each node's dataPath rather than from the root's children, because the
|
|
33
|
+
* children of a composed schema are synthetic ($allOf-1, $comp-1) and carry no data
|
|
34
|
+
* key of their own — the real property sits below them.
|
|
35
|
+
* @param {import('../../state/types.js').StateNode} node
|
|
36
|
+
* @param {Set<string>} [keys]
|
|
37
|
+
* @returns {Set<string>}
|
|
38
|
+
*/
|
|
39
|
+
function collectRootDataKeys (node, keys = new Set()) {
|
|
40
|
+
const segments = (node.dataPath ?? '').split('/').filter(Boolean)
|
|
41
|
+
if (segments.length === 1) keys.add(segments[0])
|
|
42
|
+
for (const child of node.children ?? []) collectRootDataKeys(child, keys)
|
|
43
|
+
return keys
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @param {unknown} value
|
|
48
|
+
* @returns {boolean}
|
|
49
|
+
*/
|
|
50
|
+
function isPlainObject (value) {
|
|
51
|
+
return !!value && typeof value === 'object' && !Array.isArray(value)
|
|
44
52
|
}
|
|
45
53
|
|
|
46
54
|
/**
|
|
47
55
|
* @param {import('../../state/index.js').StatefulLayout} statefulLayout
|
|
48
|
-
* @param {{ data: unknown }} args
|
|
49
|
-
* @returns {{ valid: boolean, errors: Array<{path: string, message: string}> }}
|
|
56
|
+
* @param {{ data: unknown, merge?: boolean }} args
|
|
57
|
+
* @returns {{ valid: boolean, written: string[], removed: string[], unknownKeys: string[], visibility?: { revealed: string[], hidden: string[] }, errors: Array<{path: string, message: string}> }}
|
|
50
58
|
*/
|
|
51
59
|
export function execute (statefulLayout, args) {
|
|
52
|
-
|
|
60
|
+
const current = statefulLayout.data
|
|
61
|
+
const mergeable = isPlainObject(current) && isPlainObject(args.data)
|
|
62
|
+
|
|
63
|
+
/** @type {string[]} */
|
|
64
|
+
let removed = []
|
|
65
|
+
let next = args.data
|
|
66
|
+
|
|
67
|
+
if (mergeable) {
|
|
68
|
+
if (args.merge === false) {
|
|
69
|
+
// Replacement stays available, but never silently: a model that means "update the
|
|
70
|
+
// sections" and wipes the dataset, the title and every setting must at least be
|
|
71
|
+
// told what it removed. The form can be valid without those keys, so validity
|
|
72
|
+
// alone would report the amputation as a success.
|
|
73
|
+
removed = Object.keys(/** @type {Record<string, unknown>} */(current))
|
|
74
|
+
.filter((key) => !(key in /** @type {Record<string, unknown>} */(args.data)))
|
|
75
|
+
} else {
|
|
76
|
+
// Merging is the default because an agent asking to set some keys means to set
|
|
77
|
+
// those keys, not to delete everything else.
|
|
78
|
+
next = { ...(/** @type {Record<string, unknown>} */(current)), ...(/** @type {Record<string, unknown>} */(args.data)) }
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Same reason as setFieldValue: a written key can turn a condition true and unhide a
|
|
83
|
+
// section that nothing else in the answer would mention.
|
|
84
|
+
const visibleBefore = visibilitySnapshot(statefulLayout.stateTree.root)
|
|
85
|
+
statefulLayout.data = next
|
|
86
|
+
|
|
87
|
+
// Computed after applying the data so the tree reflects it: a key that activates a
|
|
88
|
+
// oneOf branch is only hydrated once written, and flagging it before would cry wolf.
|
|
89
|
+
// A warning rather than a rejection — ajv accepts the key because the schema does not
|
|
90
|
+
// close additionalProperties, and the form stays valid, so nothing else would say so.
|
|
91
|
+
const knownKeys = collectRootDataKeys(statefulLayout.stateTree.root)
|
|
92
|
+
const unknownKeys = isPlainObject(args.data)
|
|
93
|
+
? Object.keys(/** @type {Record<string, unknown>} */(args.data)).filter((key) => !knownKeys.has(key))
|
|
94
|
+
: []
|
|
95
|
+
|
|
96
|
+
const visibility = diffVisibility(visibleBefore, visibilitySnapshot(statefulLayout.stateTree.root))
|
|
53
97
|
|
|
54
98
|
return {
|
|
55
99
|
valid: statefulLayout.valid,
|
|
56
|
-
errors
|
|
100
|
+
// Which keys landed. "valid, no errors" says the form is happy but nothing about what
|
|
101
|
+
// was stored, and contact's agent read that as a reason to spend a call on getData
|
|
102
|
+
// to see its own write. Keys only: the values can be a 12 KB dataset object.
|
|
103
|
+
written: isPlainObject(args.data) ? Object.keys(/** @type {Record<string, unknown>} */(args.data)) : [],
|
|
104
|
+
removed,
|
|
105
|
+
unknownKeys,
|
|
106
|
+
...(visibility.revealed.length || visibility.hidden.length ? { visibility } : {}),
|
|
107
|
+
errors: collectErrors(statefulLayout)
|
|
57
108
|
}
|
|
58
109
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @file setFieldValue tool
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { projectFieldResult,
|
|
5
|
+
import { projectFieldResult, collectScopedErrors, projectNodeToMarkdown, visibilitySnapshot, diffVisibility } from '../project.js'
|
|
6
6
|
import { resolveNode } from '../resolve.js'
|
|
7
7
|
|
|
8
8
|
export const inputSchema = {
|
|
@@ -10,39 +10,17 @@ export const inputSchema = {
|
|
|
10
10
|
properties: {
|
|
11
11
|
path: {
|
|
12
12
|
type: 'string',
|
|
13
|
-
description: '
|
|
13
|
+
description: 'Node path as returned by describeState (e.g. "/address/city").'
|
|
14
14
|
},
|
|
15
15
|
value: {
|
|
16
|
-
description: 'The value to set. For variant-selector fields, pass the variant index to switch variants.'
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
required: ['path', 'value']
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export const outputSchema = {
|
|
23
|
-
type: 'object',
|
|
24
|
-
properties: {
|
|
25
|
-
valid: { type: 'boolean' },
|
|
26
|
-
field: {
|
|
27
|
-
type: 'object',
|
|
28
|
-
properties: {
|
|
29
|
-
path: { type: 'string' },
|
|
30
|
-
type: { type: 'string' },
|
|
31
|
-
data: {},
|
|
32
|
-
error: { type: 'string' }
|
|
33
|
-
}
|
|
16
|
+
description: 'The value to set. For variant-selector fields, pass the variant index to switch variants. Exclusive with "suggestionIndex".'
|
|
34
17
|
},
|
|
35
|
-
|
|
36
|
-
type: '
|
|
37
|
-
|
|
38
|
-
type: 'object',
|
|
39
|
-
properties: {
|
|
40
|
-
path: { type: 'string' },
|
|
41
|
-
message: { type: 'string' }
|
|
42
|
-
}
|
|
43
|
-
}
|
|
18
|
+
suggestionIndex: {
|
|
19
|
+
type: 'number',
|
|
20
|
+
description: 'Index from the last getFieldSuggestions call on this same path. Exclusive with "value".'
|
|
44
21
|
}
|
|
45
|
-
}
|
|
22
|
+
},
|
|
23
|
+
required: ['path']
|
|
46
24
|
}
|
|
47
25
|
|
|
48
26
|
/**
|
|
@@ -50,34 +28,66 @@ export const outputSchema = {
|
|
|
50
28
|
* @returns {string}
|
|
51
29
|
*/
|
|
52
30
|
export function getDescription (dataTitle) {
|
|
53
|
-
return `Set the value of a specific field of "${dataTitle}" by path.
|
|
31
|
+
return `Set the value of a specific field of "${dataTitle}" by path. To switch a variant selector, set value to the desired variant index (shown in describeState); the answer then lists the fields of the branch it activated. The returned errors are scoped to the modified field.`
|
|
54
32
|
}
|
|
55
33
|
|
|
56
34
|
/**
|
|
57
35
|
* @param {import('../../state/index.js').StatefulLayout} statefulLayout
|
|
58
|
-
* @param {{ path: string, value
|
|
59
|
-
* @
|
|
36
|
+
* @param {{ path: string, value?: unknown, suggestionIndex?: number }} args
|
|
37
|
+
* @param {import('../suggestions-store.js').SuggestionsStore} [store]
|
|
38
|
+
* @param {import('../variants-memo.js').VariantsMemo} [variantsMemo] - the activated branch
|
|
39
|
+
* may nest the same union again; the memo keeps the response from printing it twice
|
|
40
|
+
* @returns {{ valid: boolean, field: ReturnType<typeof projectFieldResult>, errors: Array<{path: string, message: string}>, otherErrors: number, activatedMarkdown?: string, visibility?: { revealed: string[], hidden: string[] } }}
|
|
60
41
|
*/
|
|
61
|
-
export function execute (statefulLayout, args) {
|
|
42
|
+
export function execute (statefulLayout, args, store, variantsMemo) {
|
|
62
43
|
const node = resolveNode(statefulLayout.stateTree.root, args.path)
|
|
63
44
|
if (!node) {
|
|
64
45
|
throw new Error(`node not found at path: ${args.path}`)
|
|
65
46
|
}
|
|
66
47
|
|
|
67
|
-
|
|
68
|
-
|
|
48
|
+
let value = args.value
|
|
49
|
+
if (args.suggestionIndex !== undefined) {
|
|
50
|
+
if (args.value !== undefined) {
|
|
51
|
+
throw new Error('value and suggestionIndex are exclusive, use only one of them')
|
|
52
|
+
}
|
|
53
|
+
if (!store) {
|
|
54
|
+
throw new Error('no suggestion memorized, call getFieldSuggestions first')
|
|
55
|
+
}
|
|
56
|
+
value = store.getValue(args.path, args.suggestionIndex)
|
|
57
|
+
} else if (args.value === undefined && !('value' in args)) {
|
|
58
|
+
throw new Error('value or suggestionIndex is required')
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// A write can turn a condition true and unhide a whole section. Nothing else in the
|
|
62
|
+
// answer would say so: the node written reports itself, and the form goes on being
|
|
63
|
+
// valid, so an agent is left believing it is finished.
|
|
64
|
+
const visibleBefore = visibilitySnapshot(statefulLayout.stateTree.root)
|
|
65
|
+
|
|
66
|
+
let activating = false
|
|
67
|
+
if (node.key === '$oneOf' && typeof value === 'number') {
|
|
68
|
+
activating = true
|
|
69
|
+
statefulLayout.activateItem(node, value)
|
|
69
70
|
} else {
|
|
70
|
-
statefulLayout.input(node,
|
|
71
|
+
statefulLayout.input(node, value)
|
|
71
72
|
statefulLayout.blur(node)
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
// Re-resolve node from updated state tree
|
|
75
76
|
const updatedNode = resolveNode(statefulLayout.stateTree.root, args.path)
|
|
76
|
-
const errors =
|
|
77
|
+
const { errors, otherErrors } = collectScopedErrors(statefulLayout, updatedNode || node)
|
|
78
|
+
|
|
79
|
+
// Switching a variant replaces a whole subtree, so answering with only the value that
|
|
80
|
+
// was written leaves the agent knowing a branch appeared but not what is in it. This
|
|
81
|
+
// mirrors what editArray already does for an item it activates.
|
|
82
|
+
const activated = activating ? (updatedNode || node).children?.[0] : undefined
|
|
83
|
+
const visibility = diffVisibility(visibleBefore, visibilitySnapshot(statefulLayout.stateTree.root))
|
|
77
84
|
|
|
78
85
|
return {
|
|
79
86
|
valid: statefulLayout.valid,
|
|
80
87
|
field: projectFieldResult(updatedNode || node, statefulLayout),
|
|
81
|
-
errors
|
|
88
|
+
errors,
|
|
89
|
+
otherErrors,
|
|
90
|
+
...(visibility.revealed.length || visibility.hidden.length ? { visibility } : {}),
|
|
91
|
+
...(activated ? { activatedMarkdown: projectNodeToMarkdown(activated, statefulLayout, 0, undefined, variantsMemo) } : {})
|
|
82
92
|
}
|
|
83
93
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Remembers which variant lists have already been sent to the agent.
|
|
3
|
+
*
|
|
4
|
+
* A discriminated union is a constant: the 39 branches of a portal page element are the
|
|
5
|
+
* same 39 whether they are reached at /elements/0 or at /elements/0/.../children2/0. The
|
|
6
|
+
* markdown projection used to print all of them every time one of those nodes appeared,
|
|
7
|
+
* and on a recursive schema that is most of the response — measured on the portal-page
|
|
8
|
+
* eval case, three emissions of one list were 4.45 KB of a 10.8 KB session, and the agent
|
|
9
|
+
* read it once and used it once.
|
|
10
|
+
*
|
|
11
|
+
* The memo is keyed on the SKELETON POINTER rather than the data path, which is what makes
|
|
12
|
+
* it catch recursion: every one of those nodes resolves to
|
|
13
|
+
* `page-config-simple#/$defs/element/oneOf`. It records where the list was first printed so
|
|
14
|
+
* a later response can point the agent back at it in its own transcript.
|
|
15
|
+
*
|
|
16
|
+
* It is never cleared on a write: unlike memorized suggestions, a schema's branches cannot
|
|
17
|
+
* be invalidated by editing the data. `describeState` projects into a fresh memo and merges
|
|
18
|
+
* it in afterwards, so a full read always prints every list once and stays authoritative.
|
|
19
|
+
*/
|
|
20
|
+
export class VariantsMemo {
|
|
21
|
+
/**
|
|
22
|
+
* first path each pointer's variant list was printed at
|
|
23
|
+
* @type {Map<string, string>}
|
|
24
|
+
*/
|
|
25
|
+
_listedAt = new Map()
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @param {string} pointer - skeleton pointer of the one-of-select node
|
|
29
|
+
* @returns {string | undefined} the path it was first listed at, or undefined if never
|
|
30
|
+
*/
|
|
31
|
+
listedAt (pointer) {
|
|
32
|
+
return this._listedAt.get(pointer)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @param {string} pointer
|
|
37
|
+
* @param {string} path
|
|
38
|
+
*/
|
|
39
|
+
record (pointer, path) {
|
|
40
|
+
if (!this._listedAt.has(pointer)) this._listedAt.set(pointer, path)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @param {VariantsMemo} other
|
|
45
|
+
*/
|
|
46
|
+
merge (other) {
|
|
47
|
+
for (const [pointer, path] of other._listedAt) this.record(pointer, path)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
clear () {
|
|
51
|
+
this._listedAt.clear()
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/compile/index.js"],"names":[],"mappings":"AA4BA;;;;GAIG;AACH,iCAJW,MAAM,mBACN,qBAAqB,GACnB,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/compile/index.js"],"names":[],"mappings":"AA4BA;;;;GAIG;AACH,iCAJW,MAAM,mBACN,qBAAqB,GACnB,cAAc,CAyH1B;;;;2BAzIY,OAAO,YAAY,EAAE,YAAY;2BACjC,OAAO,YAAY,EAAE,YAAY;6BACjC,OAAO,YAAY,EAAE,cAAc;6BACnC,OAAO,YAAY,EAAE,cAAc;oCACnC,OAAO,YAAY,EAAE,qBAAqB;iCAC1C,OAAO,YAAY,EAAE,kBAAkB"}
|
|
@@ -11,11 +11,18 @@
|
|
|
11
11
|
* @param {import('@json-layout/vocabulary').Expression[]} expressions
|
|
12
12
|
* @param {string | number} key
|
|
13
13
|
* @param {string} pointer
|
|
14
|
-
* @param {boolean} required
|
|
14
|
+
* @param {boolean} required - the schema makes this node's value mandatory: omitting it is
|
|
15
|
+
* a validation error. This is what `node.required` reports and what a UI marks with an
|
|
16
|
+
* asterisk, so it must never be true for a node the schema is happy to see absent.
|
|
15
17
|
* @param {string} [condition]
|
|
16
18
|
* @param {boolean} [dependent]
|
|
17
19
|
* @param {string} [knownType]
|
|
20
|
+
* @param {boolean} [alwaysPresent] - the node's value is materialized whether or not the
|
|
21
|
+
* schema requires it, because its parent renders it as a fixed slot. Drives default and
|
|
22
|
+
* empty-container application only. Defaults to `required`, which is the same thing for
|
|
23
|
+
* every parent that builds its children from what the schema demands; tuple entries are
|
|
24
|
+
* the exception, always present but only required up to `minItems`.
|
|
18
25
|
* @returns {import('./types.js').SkeletonNode}
|
|
19
26
|
*/
|
|
20
|
-
export function makeSkeletonNode(rawSchema: any, sourceSchemaId: string, options: import("./index.js").CompileOptions, getJSONRef: (schemaId: string, ref: string) => [any, string, string], skeletonTrees: Record<string, import("./types.js").SkeletonTree>, skeletonNodes: Record<string, import("./types.js").SkeletonNode>, validatePointers: string[], validationErrors: Record<string, string[]>, normalizedLayouts: Record<string, import("@json-layout/vocabulary").NormalizedLayout>, expressions: import("@json-layout/vocabulary").Expression[], key: string | number, pointer: string, required: boolean, condition?: string, dependent?: boolean, knownType?: string): import("./types.js").SkeletonNode;
|
|
27
|
+
export function makeSkeletonNode(rawSchema: any, sourceSchemaId: string, options: import("./index.js").CompileOptions, getJSONRef: (schemaId: string, ref: string) => [any, string, string], skeletonTrees: Record<string, import("./types.js").SkeletonTree>, skeletonNodes: Record<string, import("./types.js").SkeletonNode>, validatePointers: string[], validationErrors: Record<string, string[]>, normalizedLayouts: Record<string, import("@json-layout/vocabulary").NormalizedLayout>, expressions: import("@json-layout/vocabulary").Expression[], key: string | number, pointer: string, required: boolean, condition?: string, dependent?: boolean, knownType?: string, alwaysPresent?: boolean): import("./types.js").SkeletonNode;
|
|
21
28
|
//# sourceMappingURL=skeleton-node.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skeleton-node.d.ts","sourceRoot":"","sources":["../../src/compile/skeleton-node.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"skeleton-node.d.ts","sourceRoot":"","sources":["../../src/compile/skeleton-node.js"],"names":[],"mappings":"AA8BA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,4CAzBW,GAAG,kBACH,MAAM,WACN,OAAO,YAAY,EAAE,cAAc,cACnC,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,iBACxD,MAAM,CAAC,MAAM,EAAE,OAAO,YAAY,EAAE,YAAY,CAAC,iBACjD,MAAM,CAAC,MAAM,EAAE,OAAO,YAAY,EAAE,YAAY,CAAC,oBACjD,MAAM,EAAE,oBACR,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,qBACxB,MAAM,CAAC,MAAM,EAAE,OAAO,yBAAyB,EAAE,gBAAgB,CAAC,eAClE,OAAO,yBAAyB,EAAE,UAAU,EAAE,OAC9C,MAAM,GAAG,MAAM,WACf,MAAM,YACN,OAAO,cAGP,MAAM,cACN,OAAO,cACP,MAAM,kBACN,OAAO,GAKL,OAAO,YAAY,EAAE,YAAY,CAukB7C"}
|
package/types/compile/types.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/compile/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/compile/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-refs.d.ts","sourceRoot":"","sources":["../../../src/compile/utils/resolve-refs.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"resolve-refs.d.ts","sourceRoot":"","sources":["../../../src/compile/utils/resolve-refs.js"],"names":[],"mappings":"AAsBA;;;;;;;GAOG;AACH,0CANW,OAAO,KAAK,EAAE,YAAY,OAC1B,OAAO,kBAAkB,EAAE,OAAO,WAClC,MAAM,kBACN,MAAM,GACJ,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,CASpE;AAuCD;;;;;GAKG;AACH,2CAJW,OAAO,KAAK,EAAE,YAAY,YAC1B,MAAM,cACN,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,OA+ClE"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export function resolveXI18n(schema: Record<string, any>, locale: string, defaultLocale?: string): void;
|
|
1
|
+
export function resolveXI18n(schema: Record<string, any>, locale: string, defaultLocale?: string, apply?: boolean): void;
|
|
2
2
|
//# sourceMappingURL=x-i18n.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"x-i18n.d.ts","sourceRoot":"","sources":["../../../src/compile/utils/x-i18n.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"x-i18n.d.ts","sourceRoot":"","sources":["../../../src/compile/utils/x-i18n.js"],"names":[],"mappings":"AAQO,qCALI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,UACnB,MAAM,kBACN,MAAM,UACN,OAAO,QA0BjB"}
|
package/types/state/index.d.ts
CHANGED
|
@@ -129,6 +129,16 @@ export class StatefulLayout {
|
|
|
129
129
|
* @type {CreateStateTreeContext}
|
|
130
130
|
*/
|
|
131
131
|
private _lastCreateStateTreeContext;
|
|
132
|
+
/**
|
|
133
|
+
* The raw validation errors of the last state update, each carrying the data pointer
|
|
134
|
+
* (instancePath) it applies to.
|
|
135
|
+
*
|
|
136
|
+
* A node only carries an error when it is hydrated, so an error below an unhydrated
|
|
137
|
+
* subtree — a list item shown in summary mode, say — has no node to attach to and
|
|
138
|
+
* collapses onto the nearest ancestor. These keep the precise location.
|
|
139
|
+
* @returns {import('ajv').ErrorObject[]}
|
|
140
|
+
*/
|
|
141
|
+
get validationErrors(): import("ajv").ErrorObject[];
|
|
132
142
|
/**
|
|
133
143
|
* @private
|
|
134
144
|
* @type {string | null}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/state/index.js"],"names":[],"mappings":";;AAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,mEAAmE;AACnE,wBADW,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,KAAK,IAAI,IAAI,WAAW,CACY;AAE3E,iLAAiL;AACjL,0BADW,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,yBAAyB,EAAE,aAAa,CAAC,KAAK,IAAI,IAAI,UAAU,GAAG,YAAY,GAAG,gBAAgB,CAC5E;AAOjG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/state/index.js"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state-node.d.ts","sourceRoot":"","sources":["../../src/state/state-node.js"],"names":[],"mappings":"AAkRA;;;;;;;;;;;GAWG;AACH,4CAXW,OAAO,aAAa,EAAE,kBAAkB,EAAE,cAC1C,OAAO,yBAAyB,EAAE,UAAU,QAC5C,GAAG,WACH,OAAO,YAAY,EAAE,gBAAgB,WACrC,OAAO,oBAAoB,EAAE,OAAO,UACpC,OAAO,yBAAyB,EAAE,cAAc,aAChD,MAAM,CAAC,MAAM,EAAE,OAAO,KAAK,EAAE,gBAAgB,CAAC,YAC9C,OAAO,iBACP,OAAO,qBAAqB,EAAE,uBAAuB,GAAG,IAAI,GAC1D,GAAG,CAsBf;
|
|
1
|
+
{"version":3,"file":"state-node.d.ts","sourceRoot":"","sources":["../../src/state/state-node.js"],"names":[],"mappings":"AAkRA;;;;;;;;;;;GAWG;AACH,4CAXW,OAAO,aAAa,EAAE,kBAAkB,EAAE,cAC1C,OAAO,yBAAyB,EAAE,UAAU,QAC5C,GAAG,WACH,OAAO,YAAY,EAAE,gBAAgB,WACrC,OAAO,oBAAoB,EAAE,OAAO,UACpC,OAAO,yBAAyB,EAAE,cAAc,aAChD,MAAM,CAAC,MAAM,EAAE,OAAO,KAAK,EAAE,gBAAgB,CAAC,YAC9C,OAAO,iBACP,OAAO,qBAAqB,EAAE,uBAAuB,GAAG,IAAI,GAC1D,GAAG,CAsBf;AA0CD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,yCAlBW,OAAO,YAAY,EAAE,sBAAsB,iBAC3C,OAAO,YAAY,EAAE,gBAAgB,kBACrC,OAAO,aAAa,EAAE,cAAc,OACpC,MAAM,GAAG,MAAM,WACf,MAAM,iBACN,MAAM,GAAG,IAAI,YACb,MAAM,kBACN,MAAM,GAAG,IAAI,YACb,OAAO,aAAa,EAAE,YAAY,mBAClC,OAAO,yBAAyB,EAAE,KAAK,GAAG,IAAI,iBAC9C,OAAO,oBAAoB,EAAE,OAAO,QACpC,GAAG,iBACH,OAAO,qBAAqB,EAAE,uBAAuB,GAAG,IAAI,mBAC5D,OAAO,YAAY,EAAE,eAAe,cACpC,MAAM,eACN,OAAO,YAAY,EAAE,SAAS,GAC5B,OAAO,YAAY,EAAE,SAAS,CAipB1C;AAj+BM,qCALI,OAAO,UACP,OAAO,yBAAyB,EAAE,cAAc,WAChD,OAAO,YAAY,EAAE,gBAAgB,GACnC,OAAO,CAMnB;AA+9BD,uFAAuF;AACvF,iCADW,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,KAAK,GAAG,CAgBjF;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,8BAFU,CAAC,YAAY,EAAE,GAAG,EAAE,EAAE,aAAa,EAAE,OAAO,yBAAyB,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,yBAAyB,EAAE,WAAW,EAAE,aAAa,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,OAAO,KAAK,GAAG,CAkC5M"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"urls.d.ts","sourceRoot":"","sources":["../../../src/state/utils/urls.js"],"names":[],"mappings":"AAEO,6BAA4B,MAAM,WAAoB,MAAM,
|
|
1
|
+
{"version":3,"file":"urls.d.ts","sourceRoot":"","sources":["../../../src/state/utils/urls.js"],"names":[],"mappings":"AAEO,6BAA4B,MAAM,WAAoB,MAAM,OAMlE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file JSON pointer traversal, shared by the compilation step and the webmcp tools
|
|
3
|
+
* @description Pointers are produced by concatenation in the compilation step
|
|
4
|
+
* (`${refPointerPrefix}/properties/${propertyKey}` and similar), their segments are
|
|
5
|
+
* therefore consumed raw: they are deliberately not unescaped as RFC 6901 would
|
|
6
|
+
* prescribe, so that resolution stays symmetric with the way pointers are built.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Resolve the fragment part of a JSON pointer (what follows the '#') in a schema or any object.
|
|
10
|
+
* @param {unknown} root
|
|
11
|
+
* @param {string} fragment - e.g. '/properties/address/items', leading and empty segments are ignored
|
|
12
|
+
* @returns {{found: true, value: unknown} | {found: false, path: string[]}} - the resolved value, or
|
|
13
|
+
* the segments consumed up to and including the missing one, to report where the resolution failed
|
|
14
|
+
*/
|
|
15
|
+
export function resolvePointerFragment(root: unknown, fragment: string): {
|
|
16
|
+
found: true;
|
|
17
|
+
value: unknown;
|
|
18
|
+
} | {
|
|
19
|
+
found: false;
|
|
20
|
+
path: string[];
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=json-pointer.d.ts.map
|