@jini-ai/agentic 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/a2ui/agent-to-renderer.d.ts +579 -0
  2. package/dist/a2ui/agent-to-renderer.d.ts.map +1 -0
  3. package/dist/a2ui/agent-to-renderer.js +169 -0
  4. package/dist/a2ui/agent-to-renderer.js.map +1 -0
  5. package/dist/a2ui/catalog.d.ts +73 -0
  6. package/dist/a2ui/catalog.d.ts.map +1 -0
  7. package/dist/a2ui/catalog.js +304 -0
  8. package/dist/a2ui/catalog.js.map +1 -0
  9. package/dist/a2ui/common-types.d.ts +401 -0
  10. package/dist/a2ui/common-types.d.ts.map +1 -0
  11. package/dist/a2ui/common-types.js +130 -0
  12. package/dist/a2ui/common-types.js.map +1 -0
  13. package/dist/a2ui/index.d.ts +16 -0
  14. package/dist/a2ui/index.d.ts.map +1 -0
  15. package/dist/a2ui/index.js +16 -0
  16. package/dist/a2ui/index.js.map +1 -0
  17. package/dist/a2ui/interpreter.d.ts +48 -0
  18. package/dist/a2ui/interpreter.d.ts.map +1 -0
  19. package/dist/a2ui/interpreter.js +287 -0
  20. package/dist/a2ui/interpreter.js.map +1 -0
  21. package/dist/a2ui/json-pointer.d.ts +48 -0
  22. package/dist/a2ui/json-pointer.d.ts.map +1 -0
  23. package/dist/a2ui/json-pointer.js +149 -0
  24. package/dist/a2ui/json-pointer.js.map +1 -0
  25. package/dist/a2ui/renderer-to-agent.d.ts +318 -0
  26. package/dist/a2ui/renderer-to-agent.d.ts.map +1 -0
  27. package/dist/a2ui/renderer-to-agent.js +98 -0
  28. package/dist/a2ui/renderer-to-agent.js.map +1 -0
  29. package/dist/a2ui/resolve.d.ts +28 -0
  30. package/dist/a2ui/resolve.d.ts.map +1 -0
  31. package/dist/a2ui/resolve.js +118 -0
  32. package/dist/a2ui/resolve.js.map +1 -0
  33. package/dist/a2ui/tree.d.ts +41 -0
  34. package/dist/a2ui/tree.d.ts.map +1 -0
  35. package/dist/a2ui/tree.js +35 -0
  36. package/dist/a2ui/tree.js.map +1 -0
  37. package/dist/dom/model-context.d.ts +15 -0
  38. package/dist/dom/model-context.d.ts.map +1 -1
  39. package/dist/dom/model-context.js +8 -0
  40. package/dist/dom/model-context.js.map +1 -1
  41. package/dist/index.d.ts +2 -2
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +2 -2
  44. package/dist/index.js.map +1 -1
  45. package/dist/mcp-ui-apps.d.ts +81 -10
  46. package/dist/mcp-ui-apps.d.ts.map +1 -1
  47. package/dist/mcp-ui-apps.js +84 -11
  48. package/dist/mcp-ui-apps.js.map +1 -1
  49. package/dist/webmcp.d.ts +126 -5
  50. package/dist/webmcp.d.ts.map +1 -1
  51. package/dist/webmcp.js +110 -4
  52. package/dist/webmcp.js.map +1 -1
  53. package/package.json +16 -5
@@ -0,0 +1,287 @@
1
+ /**
2
+ * @module interpreter
3
+ *
4
+ * The minimal A2UI client-side interpreter: client state (a component map + a JSON-Pointer-
5
+ * addressed data model, per surface) that processes agent→renderer messages
6
+ * (`createSurface -> updateComponents -> updateDataModel -> ...`) and produces renderer→agent
7
+ * messages (`action`/`functionResponse`/`error`) in return. This is the piece GenUI/AG-UI
8
+ * (`packages/agentic/src/gen-ui/`, this repo's existing, much smaller GenUI surface-request shim)
9
+ * has no equivalent of — AG-UI streams
10
+ * opaque `ui.surface_requested`/`ui.surface_responded` events with no component tree, no catalog,
11
+ * no data binding; A2UI's interpreter has to actually hold and mutate structured state.
12
+ *
13
+ * **Design decisions made where the spec text (fetched from
14
+ * https://github.com/a2ui-project/a2ui, `main` branch, this session) is silent, documented here
15
+ * rather than left implicit:**
16
+ *
17
+ * 1. **Per-component, not per-message, validation granularity.** `updateComponents`'s own spec
18
+ * text says forward-referenced children/bindings should be handled gracefully — the spirit of
19
+ * that is "don't be brittle about partial/out-of-order information." This interpreter extends
20
+ * that spirit to catalog violations: one bad component in a 5-component `updateComponents`
21
+ * message produces one `VALIDATION_FAILED` error for that component and is skipped, while the
22
+ * other 4 valid components are still applied. The alternative (reject the whole message
23
+ * atomically) was considered and rejected as more brittle than the spec's own examples call for,
24
+ * not as spec-mandated either way.
25
+ * 2. **`callFunction`/`actionResponse` are not surface-scoped on the wire** (verified directly
26
+ * against the fetched JSON Schemas — neither message type has a `surfaceId` field). Functions
27
+ * are catalog-global (one active catalog per interpreter instance); `actionResponse` is
28
+ * correlated by `actionId` searched across every open surface's own pending-action table.
29
+ * 3. **`callFunction`'s `args` may contain `DataBinding` paths** (`FunctionCall.args` is typed
30
+ * against `DynamicValue` in `common_types.json`, which includes `DataBinding`) **but
31
+ * `callFunction` has no data model to bind against** (see point 2) — a real spec ambiguity, not
32
+ * an oversight in this port. Resolved pragmatically: such args resolve against an empty/absent
33
+ * data model, so any `DataBinding`-typed arg simply fails to resolve (`PATH_NOT_FOUND`,
34
+ * degrading sanely per `resolve.ts`'s contract) rather than crashing or guessing which surface's
35
+ * data model was "meant."
36
+ * 4. **An envelope malformed enough to have no attributable `surfaceId`/`functionCallId` at all**
37
+ * (missing `version`, no/ambiguous message-type key) cannot be turned into a spec-shaped
38
+ * `error` message — `renderer_to_agent.json`'s own generic-error schema *requires* one of those
39
+ * two identifiers. Rather than fabricate one, `applyAgentMessage` surfaces this case out-of-band
40
+ * via `unattributedViolation` (a string, not sent over the wire) instead of forcing a fake
41
+ * identifier into a wire-conformant shape.
42
+ */
43
+ import { AGENT_TO_RENDERER_MESSAGE_KEYS, parseAgentToRendererMessage } from './agent-to-renderer.js';
44
+ import { WireComponentSchema } from './agent-to-renderer.js';
45
+ import { buildActionMessage, buildFunctionResponseMessage, buildGenericErrorMessage, buildValidationFailedMessage, } from './renderer-to-agent.js';
46
+ import { setAtPointer } from './json-pointer.js';
47
+ import { isComponentAllowed } from './catalog.js';
48
+ import { resolveDynamicValue } from './resolve.js';
49
+ import { isLocalFunctionAction } from './common-types.js';
50
+ let actionIdCounter = 0;
51
+ function nextActionId() {
52
+ actionIdCounter += 1;
53
+ return `a2ui-action-${actionIdCounter}-${Date.now().toString(36)}`;
54
+ }
55
+ export function createA2uiInterpreter(catalog) {
56
+ const surfaces = new Map();
57
+ const listeners = new Set();
58
+ function notify() {
59
+ for (const listener of listeners)
60
+ listener();
61
+ }
62
+ function bestEffortSurfaceId(raw, key) {
63
+ if (typeof raw !== 'object' || raw === null)
64
+ return undefined;
65
+ const body = raw[key];
66
+ if (typeof body !== 'object' || body === null)
67
+ return undefined;
68
+ const surfaceId = body.surfaceId;
69
+ return typeof surfaceId === 'string' ? surfaceId : undefined;
70
+ }
71
+ function applyComponentsList(surface, wireComponents) {
72
+ const errors = [];
73
+ wireComponents.forEach((wireComponent, index) => {
74
+ const { id, component: type, ...rest } = wireComponent;
75
+ if (!isComponentAllowed(catalog, type)) {
76
+ errors.push(buildValidationFailedMessage(surface.surfaceId, `/components/${index}/component`, `Component type "${type}" is not in catalog "${catalog.catalogId}" — refused, not rendered.`));
77
+ return;
78
+ }
79
+ const spec = catalog.components.get(type);
80
+ const parsed = spec.propsSchema.safeParse(rest);
81
+ if (!parsed.success) {
82
+ // zod guarantees a non-empty `issues` array on failure — see agent-to-renderer.ts's
83
+ // parseAgentToRendererMessage for the same asserted (not defensively branched) invariant.
84
+ const issue = parsed.error.issues[0];
85
+ errors.push(buildValidationFailedMessage(surface.surfaceId, `/components/${index}/${issue.path.join('/')}`, `Component "${id}" (${type}) failed catalog validation: ${issue.message}`));
86
+ return;
87
+ }
88
+ surface.components.set(id, { id, component: type, props: parsed.data });
89
+ });
90
+ return errors;
91
+ }
92
+ function handleCreateSurface(message) {
93
+ const { surfaceId, catalogId, components, dataModel } = message.createSurface;
94
+ if (catalogId !== catalog.catalogId) {
95
+ return [buildValidationFailedMessage(surfaceId, '/createSurface/catalogId', `Unknown catalogId "${catalogId}" — this renderer only has "${catalog.catalogId}" loaded.`)];
96
+ }
97
+ if (surfaces.has(surfaceId)) {
98
+ return [buildValidationFailedMessage(surfaceId, '/createSurface/surfaceId', `Surface "${surfaceId}" already exists — delete it before recreating (per spec).`)];
99
+ }
100
+ const surface = {
101
+ surfaceId,
102
+ catalogId,
103
+ components: new Map(),
104
+ dataModel: dataModel ?? {},
105
+ sendDataModel: message.createSurface.sendDataModel ?? false,
106
+ pendingActions: new Map(),
107
+ };
108
+ surfaces.set(surfaceId, surface);
109
+ return components ? applyComponentsList(surface, components) : [];
110
+ }
111
+ function handleUpdateComponents(message) {
112
+ const { surfaceId, components } = message.updateComponents;
113
+ const surface = surfaces.get(surfaceId);
114
+ if (!surface) {
115
+ return [buildValidationFailedMessage(surfaceId, '/updateComponents/surfaceId', `Unknown surfaceId "${surfaceId}" — createSurface must be sent first.`)];
116
+ }
117
+ return applyComponentsList(surface, components);
118
+ }
119
+ function handleUpdateDataModel(message) {
120
+ const { surfaceId, path, value } = message.updateDataModel;
121
+ const surface = surfaces.get(surfaceId);
122
+ if (!surface) {
123
+ return [buildValidationFailedMessage(surfaceId, '/updateDataModel/surfaceId', `Unknown surfaceId "${surfaceId}" — createSurface must be sent first.`)];
124
+ }
125
+ surface.dataModel = setAtPointer(surface.dataModel, path ?? '/', value);
126
+ return [];
127
+ }
128
+ function handleDeleteSurface(message) {
129
+ const { surfaceId } = message.deleteSurface;
130
+ if (!surfaces.has(surfaceId)) {
131
+ return [buildValidationFailedMessage(surfaceId, '/deleteSurface/surfaceId', `Unknown surfaceId "${surfaceId}" — nothing to delete.`)];
132
+ }
133
+ // Dropping the whole SurfaceState also drops its pendingActions map — any actionResponse that
134
+ // arrives afterward for an actionId that lived here simply won't be found (handled gracefully
135
+ // in handleActionResponse below), which is exactly the "deleteSurface mid-flight" adversarial
136
+ // case this is designed to answer.
137
+ surfaces.delete(surfaceId);
138
+ return [];
139
+ }
140
+ function handleCallFunction(message) {
141
+ const { functionCallId, callFunction, wantResponse } = message;
142
+ const result = resolveDynamicValue(callFunction, { dataModel: undefined, catalog, side: 'agent' });
143
+ if (!result.ok) {
144
+ const code = result.reason === 'FUNCTION_NOT_CALLABLE_FROM_SIDE' || result.reason === 'FUNCTION_NOT_REGISTERED' ? 'INVALID_FUNCTION_CALL' : result.reason;
145
+ return [buildGenericErrorMessage(code, result.detail, { functionCallId })];
146
+ }
147
+ if (!wantResponse)
148
+ return [];
149
+ return [buildFunctionResponseMessage({ functionCallId, call: callFunction.call, value: result.value })];
150
+ }
151
+ function handleActionResponse(message) {
152
+ const { actionId, actionResponse } = message;
153
+ for (const surface of surfaces.values()) {
154
+ const pending = surface.pendingActions.get(actionId);
155
+ if (!pending)
156
+ continue;
157
+ surface.pendingActions.delete(actionId);
158
+ if ('value' in actionResponse && pending.responsePath) {
159
+ surface.dataModel = setAtPointer(surface.dataModel, pending.responsePath, actionResponse.value);
160
+ }
161
+ return [];
162
+ }
163
+ // No surface has a pending action under this id — already resolved, never existed, or its
164
+ // surface was deleted while the action was in flight. Graceful no-op, not an error: the agent
165
+ // sent a well-formed message, it just arrived too late (or was mistaken) to mean anything now.
166
+ return [];
167
+ }
168
+ function applyAgentMessage(raw) {
169
+ const parsed = parseAgentToRendererMessage(raw);
170
+ if (!parsed.ok) {
171
+ if (parsed.code === 'MISSING_VERSION' || parsed.code === 'UNSUPPORTED_VERSION' || parsed.code === 'NO_MESSAGE_KEY' || parsed.code === 'AMBIGUOUS_MESSAGE') {
172
+ return { rendererMessages: [], unattributedViolation: parsed.message };
173
+ }
174
+ // VALIDATION_FAILED from the dispatcher: either `raw` wasn't even an object (`bestEffortSurfaceId`
175
+ // safely returns `undefined` for that, same as every other shape it doesn't recognize — no
176
+ // separate guard needed here), or exactly one of the six known message-type keys was present
177
+ // and its body failed schema validation. Checked against the *known* keys specifically
178
+ // (`AGENT_TO_RENDERER_MESSAGE_KEYS`), not "whatever the first non-version object key happens to
179
+ // be" — an envelope could carry unrelated extra top-level junk ahead of the real message key in
180
+ // insertion order, and grabbing that first would attribute the error to the wrong place. Best-
181
+ // effort surfaceId extraction so this can still be a spec-shaped error where possible
182
+ // (createSurface/updateComponents/updateDataModel/deleteSurface all carry surfaceId at the top
183
+ // of their body even when some other field is what actually failed validation); callFunction/
184
+ // actionResponse have no surfaceId at all, so those fall back to the out-of-band channel too.
185
+ const surfaceId = AGENT_TO_RENDERER_MESSAGE_KEYS.map((key) => bestEffortSurfaceId(raw, key)).find((id) => id !== undefined);
186
+ if (surfaceId) {
187
+ // `parsed.path` is guaranteed set here: `ParseFailure.path` is only ever omitted for the
188
+ // "raw input wasn't even an object" case (`agent-to-renderer.ts`'s very first guard), and
189
+ // `surfaceId` above could only have resolved to a truthy value if `raw` *was* an object
190
+ // (`bestEffortSurfaceId` requires that) — so this specific combination (object-shaped raw,
191
+ // yet no `path`) cannot occur. Asserted, not defensively branched, per this package's
192
+ // testing discipline (see the zod-issues-array comments elsewhere in this file).
193
+ return { rendererMessages: [buildValidationFailedMessage(surfaceId, parsed.path, parsed.message)] };
194
+ }
195
+ return { rendererMessages: [], unattributedViolation: parsed.message };
196
+ }
197
+ const message = parsed.message;
198
+ let rendererMessages;
199
+ if ('createSurface' in message)
200
+ rendererMessages = handleCreateSurface(message);
201
+ else if ('updateComponents' in message)
202
+ rendererMessages = handleUpdateComponents(message);
203
+ else if ('updateDataModel' in message)
204
+ rendererMessages = handleUpdateDataModel(message);
205
+ else if ('deleteSurface' in message)
206
+ rendererMessages = handleDeleteSurface(message);
207
+ else if ('callFunction' in message)
208
+ rendererMessages = handleCallFunction(message);
209
+ else
210
+ rendererMessages = handleActionResponse(message);
211
+ notify();
212
+ return { rendererMessages };
213
+ }
214
+ function getSurface(surfaceId) {
215
+ const surface = surfaces.get(surfaceId);
216
+ if (!surface)
217
+ return undefined;
218
+ return { surfaceId: surface.surfaceId, catalogId: surface.catalogId, components: surface.components, dataModel: surface.dataModel };
219
+ }
220
+ function getRoot(surfaceId) {
221
+ return surfaces.get(surfaceId)?.components.get('root');
222
+ }
223
+ function resolve(surfaceId, value, itemBasePath, itemIndex) {
224
+ const surface = surfaces.get(surfaceId);
225
+ const itemScope = itemBasePath !== undefined && itemIndex !== undefined ? { basePath: itemBasePath, index: itemIndex } : undefined;
226
+ return resolveDynamicValue(value, { dataModel: surface?.dataModel, catalog, side: 'renderer', ...(itemScope ? { itemScope } : {}) });
227
+ }
228
+ function resolveActionContext(context, surfaceId) {
229
+ const resolved = {};
230
+ for (const [key, value] of Object.entries(context ?? {})) {
231
+ const result = resolve(surfaceId, value);
232
+ resolved[key] = result.ok ? result.value : null;
233
+ }
234
+ return resolved;
235
+ }
236
+ function buildAction(surfaceId, componentId, now = Date.now) {
237
+ const surface = surfaces.get(surfaceId);
238
+ if (!surface)
239
+ return { ok: false, reason: `unknown surfaceId "${surfaceId}"` };
240
+ const component = surface.components.get(componentId);
241
+ if (!component)
242
+ return { ok: false, reason: `unknown componentId "${componentId}" on surface "${surfaceId}"` };
243
+ const action = component.props.action;
244
+ if (!action)
245
+ return { ok: false, reason: `component "${componentId}" has no action` };
246
+ if (isLocalFunctionAction(action)) {
247
+ const result = resolveDynamicValue(action.functionCall, { dataModel: surface.dataModel, catalog, side: 'renderer' });
248
+ return result.ok ? { ok: true, kind: 'local', result: result.value } : { ok: false, reason: result.detail };
249
+ }
250
+ // `ActionSchema` (validated when this component's props were ingested — see
251
+ // `applyComponentsList`) is a closed 2-branch union: `{event}` | `{functionCall}`. Having
252
+ // already eliminated the `functionCall` branch above, TypeScript itself narrows `action` to
253
+ // the `event` branch here — no runtime `isAgentEventAction` re-check is reachable to fail; a
254
+ // malformed third shape could never have made it into `component.props.action` in the first
255
+ // place. (Not defensively branched-and-left-untested, per this package's own testing
256
+ // discipline — see the zod-issues-array comments above for the same principle.)
257
+ const { name, context, wantResponse, responsePath } = action.event;
258
+ const actionId = wantResponse ? nextActionId() : undefined;
259
+ if (actionId) {
260
+ surface.pendingActions.set(actionId, { name, sourceComponentId: componentId, responsePath });
261
+ }
262
+ const payload = {
263
+ name,
264
+ surfaceId,
265
+ sourceComponentId: componentId,
266
+ timestamp: new Date(now()).toISOString(),
267
+ context: resolveActionContext(context, surfaceId),
268
+ ...(wantResponse !== undefined ? { wantResponse } : {}),
269
+ ...(actionId !== undefined ? { actionId } : {}),
270
+ };
271
+ return { ok: true, kind: 'agent', message: buildActionMessage(payload) };
272
+ }
273
+ return {
274
+ applyAgentMessage,
275
+ getSurface,
276
+ listSurfaceIds: () => [...surfaces.keys()],
277
+ getRoot,
278
+ buildAction,
279
+ resolve,
280
+ subscribe: (listener) => {
281
+ listeners.add(listener);
282
+ return () => listeners.delete(listener);
283
+ },
284
+ };
285
+ }
286
+ export { WireComponentSchema };
287
+ //# sourceMappingURL=interpreter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interpreter.js","sourceRoot":"","sources":["../../src/a2ui/interpreter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @module json-pointer
3
+ *
4
+ * A minimal RFC 6901 (JSON Pointer) implementation for A2UI's data-model bindings
5
+ * (`common_types.json#/$defs/DataBinding`: `{"path": "/user/name"}`). Deliberately small — no
6
+ * external dependency pulled in for this; the operations A2UI actually needs (root-scope read,
7
+ * collection-scope relative read via string concatenation, write-with-null-deletes) are a thin
8
+ * slice of the full RFC.
9
+ *
10
+ * One documented, deliberate deviation from strict RFC 6901: `updateDataModel`'s own spec text
11
+ * (`agent_to_renderer.json`, `UpdateDataModelMessage.path`'s description, fetched verbatim) says
12
+ * "An optional path to a location within the data model (e.g., '/user/name'). If omitted, or set
13
+ * to '/', refers to the entire data model." Under strict RFC 6901, `""` (empty string) is the
14
+ * pointer to the whole document and `"/"` is the pointer to the property keyed by the empty
15
+ * string on the root object — two different things. A2UI's own spec text explicitly overloads
16
+ * `"/"` to mean "the whole document," not "the empty-string-keyed property." This module follows
17
+ * A2UI's own wording exactly (not raw RFC 6901) since that is what a conformant renderer must do;
18
+ * flagged here rather than silently treated as an oversight.
19
+ */
20
+ export interface PointerGetResult {
21
+ readonly found: boolean;
22
+ readonly value: unknown;
23
+ }
24
+ /** Splits a non-root pointer into its unescaped reference tokens. `pointer` must start with `/`. */
25
+ export declare function parsePointerTokens(pointer: string): string[];
26
+ export declare function joinPointer(base: string, ...tokens: string[]): string;
27
+ /** Reads the value at `pointer` in `doc`. Never throws on a non-resolving path — `found: false` degrades sanely, matching this port's "a bad binding must not crash the renderer" adversarial requirement (see `resolve.ts`). */
28
+ export declare function getAtPointer(doc: unknown, pointer: string): PointerGetResult;
29
+ /**
30
+ * Writes `value` at `pointer` in `doc`, returning a **new** document (the original is never
31
+ * mutated — every intermediate object on the path is shallow-copied). Missing intermediate
32
+ * segments are created as plain objects (this port does not attempt array-vs-object inference for
33
+ * not-yet-existing intermediate segments — a documented simplification, not a spec requirement).
34
+ * `value === null` at a non-root pointer deletes the key/value at that location, per
35
+ * `updateDataModel`'s own spec text ("To delete the key/value at path, set value explicitly to
36
+ * null."). At the root pointer, `value === null` replaces the entire data model with `null` (there
37
+ * is no "key" to delete at the root; documented as this port's own consistent interpretation).
38
+ *
39
+ * Never throws on a malformed pointer (e.g. missing leading `/`) — degrades to a no-op (`doc`
40
+ * returned unchanged), matching `getAtPointer`'s "a bad binding must not crash the renderer"
41
+ * contract. `updateDataModel`'s `path` is agent-authored wire data; an uncaught throw here had no
42
+ * error boundary above it anywhere in `packages/chat-react` or its hosts to stop it from
43
+ * unmounting the whole chat React root (see `ExtEventErrorBoundary`, added as a systemic backstop
44
+ * for the same class of bug — this is the specific root cause it would otherwise have had to
45
+ * catch).
46
+ */
47
+ export declare function setAtPointer(doc: unknown, pointer: string, value: unknown): unknown;
48
+ //# sourceMappingURL=json-pointer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-pointer.d.ts","sourceRoot":"","sources":["../../src/a2ui/json-pointer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAiBD,oGAAoG;AACpG,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAM5D;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAGrE;AAED,iOAAiO;AACjO,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,gBAAgB,CA4B5E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAkDnF"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * @module json-pointer
3
+ *
4
+ * A minimal RFC 6901 (JSON Pointer) implementation for A2UI's data-model bindings
5
+ * (`common_types.json#/$defs/DataBinding`: `{"path": "/user/name"}`). Deliberately small — no
6
+ * external dependency pulled in for this; the operations A2UI actually needs (root-scope read,
7
+ * collection-scope relative read via string concatenation, write-with-null-deletes) are a thin
8
+ * slice of the full RFC.
9
+ *
10
+ * One documented, deliberate deviation from strict RFC 6901: `updateDataModel`'s own spec text
11
+ * (`agent_to_renderer.json`, `UpdateDataModelMessage.path`'s description, fetched verbatim) says
12
+ * "An optional path to a location within the data model (e.g., '/user/name'). If omitted, or set
13
+ * to '/', refers to the entire data model." Under strict RFC 6901, `""` (empty string) is the
14
+ * pointer to the whole document and `"/"` is the pointer to the property keyed by the empty
15
+ * string on the root object — two different things. A2UI's own spec text explicitly overloads
16
+ * `"/"` to mean "the whole document," not "the empty-string-keyed property." This module follows
17
+ * A2UI's own wording exactly (not raw RFC 6901) since that is what a conformant renderer must do;
18
+ * flagged here rather than silently treated as an oversight.
19
+ */
20
+ /** `true` for the two spellings A2UI's own spec treats as "the whole document" (see module doc). Anything else is parsed as a normal RFC 6901 pointer. */
21
+ function isRootPointer(pointer) {
22
+ return pointer === '' || pointer === '/';
23
+ }
24
+ function unescapeToken(token) {
25
+ // RFC 6901 §4: ~1 must be decoded *before* ~0 is checked (a literal '~' that was itself part of
26
+ // an escaped '/' must not be re-decoded as '~0').
27
+ return token.replaceAll('~1', '/').replaceAll('~0', '~');
28
+ }
29
+ function escapeToken(token) {
30
+ return token.replaceAll('~', '~0').replaceAll('/', '~1');
31
+ }
32
+ /** Splits a non-root pointer into its unescaped reference tokens. `pointer` must start with `/`. */
33
+ export function parsePointerTokens(pointer) {
34
+ if (pointer === '')
35
+ return [];
36
+ if (!pointer.startsWith('/')) {
37
+ throw new Error(`invalid JSON Pointer (must start with "/"): ${JSON.stringify(pointer)}`);
38
+ }
39
+ return pointer.slice(1).split('/').map(unescapeToken);
40
+ }
41
+ export function joinPointer(base, ...tokens) {
42
+ const baseTokens = base === '' || base === '/' ? [] : parsePointerTokens(base);
43
+ return '/' + [...baseTokens, ...tokens].map(escapeToken).join('/');
44
+ }
45
+ /** Reads the value at `pointer` in `doc`. Never throws on a non-resolving path — `found: false` degrades sanely, matching this port's "a bad binding must not crash the renderer" adversarial requirement (see `resolve.ts`). */
46
+ export function getAtPointer(doc, pointer) {
47
+ if (isRootPointer(pointer))
48
+ return { found: true, value: doc };
49
+ let tokens;
50
+ try {
51
+ tokens = parsePointerTokens(pointer);
52
+ }
53
+ catch {
54
+ return { found: false, value: undefined };
55
+ }
56
+ let current = doc;
57
+ for (const token of tokens) {
58
+ if (Array.isArray(current)) {
59
+ if (!/^(0|[1-9]\d*)$/.test(token))
60
+ return { found: false, value: undefined };
61
+ const index = Number(token);
62
+ if (index >= current.length)
63
+ return { found: false, value: undefined };
64
+ current = current[index];
65
+ continue;
66
+ }
67
+ if (current !== null && typeof current === 'object') {
68
+ const record = current;
69
+ if (!(token in record))
70
+ return { found: false, value: undefined };
71
+ current = record[token];
72
+ continue;
73
+ }
74
+ return { found: false, value: undefined };
75
+ }
76
+ return { found: true, value: current };
77
+ }
78
+ /**
79
+ * Writes `value` at `pointer` in `doc`, returning a **new** document (the original is never
80
+ * mutated — every intermediate object on the path is shallow-copied). Missing intermediate
81
+ * segments are created as plain objects (this port does not attempt array-vs-object inference for
82
+ * not-yet-existing intermediate segments — a documented simplification, not a spec requirement).
83
+ * `value === null` at a non-root pointer deletes the key/value at that location, per
84
+ * `updateDataModel`'s own spec text ("To delete the key/value at path, set value explicitly to
85
+ * null."). At the root pointer, `value === null` replaces the entire data model with `null` (there
86
+ * is no "key" to delete at the root; documented as this port's own consistent interpretation).
87
+ *
88
+ * Never throws on a malformed pointer (e.g. missing leading `/`) — degrades to a no-op (`doc`
89
+ * returned unchanged), matching `getAtPointer`'s "a bad binding must not crash the renderer"
90
+ * contract. `updateDataModel`'s `path` is agent-authored wire data; an uncaught throw here had no
91
+ * error boundary above it anywhere in `packages/chat-react` or its hosts to stop it from
92
+ * unmounting the whole chat React root (see `ExtEventErrorBoundary`, added as a systemic backstop
93
+ * for the same class of bug — this is the specific root cause it would otherwise have had to
94
+ * catch).
95
+ */
96
+ export function setAtPointer(doc, pointer, value) {
97
+ if (isRootPointer(pointer))
98
+ return value;
99
+ let tokens;
100
+ try {
101
+ tokens = parsePointerTokens(pointer);
102
+ }
103
+ catch {
104
+ return doc;
105
+ }
106
+ const parentTokens = tokens.slice(0, -1);
107
+ const lastToken = tokens[tokens.length - 1];
108
+ function recurse(current, remaining) {
109
+ if (remaining.length === 0) {
110
+ // `current` here is the parent container; apply the final write/delete.
111
+ if (Array.isArray(current)) {
112
+ if (!/^(0|[1-9]\d*)$/.test(lastToken))
113
+ return current;
114
+ const index = Number(lastToken);
115
+ const next = current.slice();
116
+ if (value === null) {
117
+ if (index < next.length)
118
+ next.splice(index, 1);
119
+ return next;
120
+ }
121
+ next[index] = value;
122
+ return next;
123
+ }
124
+ const record = current !== null && typeof current === 'object' ? { ...current } : {};
125
+ if (value === null) {
126
+ delete record[lastToken];
127
+ return record;
128
+ }
129
+ record[lastToken] = value;
130
+ return record;
131
+ }
132
+ const [head, ...rest] = remaining;
133
+ if (Array.isArray(current)) {
134
+ if (!head || !/^(0|[1-9]\d*)$/.test(head))
135
+ return current;
136
+ const index = Number(head);
137
+ const next = current.slice();
138
+ next[index] = recurse(index < next.length ? next[index] : {}, rest);
139
+ return next;
140
+ }
141
+ const record = current !== null && typeof current === 'object' ? { ...current } : {};
142
+ if (!head)
143
+ return record;
144
+ record[head] = recurse(head in record ? record[head] : {}, rest);
145
+ return record;
146
+ }
147
+ return recurse(doc, parentTokens);
148
+ }
149
+ //# sourceMappingURL=json-pointer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-pointer.js","sourceRoot":"","sources":["../../src/a2ui/json-pointer.ts"],"names":[],"mappings":"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"}