@jini-ai/agentic 0.4.0 → 0.4.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 (66) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/core/a2ui/index.d.ts +1 -0
  3. package/dist/core/a2ui/index.js +1 -0
  4. package/dist/core/a2ui/surface-properties.d.ts +34 -0
  5. package/dist/core/a2ui/surface-properties.js +49 -0
  6. package/dist/core/annotated-actions-script.d.ts +13 -0
  7. package/dist/core/annotated-actions-script.js +137 -0
  8. package/dist/core/index.d.ts +1 -0
  9. package/dist/core/index.js +1 -0
  10. package/package.json +2 -2
  11. package/dist/a2ui/agent-to-renderer.d.ts +0 -613
  12. package/dist/a2ui/agent-to-renderer.js +0 -191
  13. package/dist/a2ui/catalog.d.ts +0 -73
  14. package/dist/a2ui/catalog.js +0 -304
  15. package/dist/a2ui/common-types.d.ts +0 -401
  16. package/dist/a2ui/common-types.js +0 -130
  17. package/dist/a2ui/index.d.ts +0 -16
  18. package/dist/a2ui/index.js +0 -16
  19. package/dist/a2ui/interpreter.d.ts +0 -71
  20. package/dist/a2ui/interpreter.js +0 -337
  21. package/dist/a2ui/json-pointer.d.ts +0 -48
  22. package/dist/a2ui/json-pointer.js +0 -174
  23. package/dist/a2ui/renderer-to-agent.d.ts +0 -342
  24. package/dist/a2ui/renderer-to-agent.js +0 -111
  25. package/dist/a2ui/resolve.d.ts +0 -28
  26. package/dist/a2ui/resolve.js +0 -144
  27. package/dist/a2ui/tree.d.ts +0 -66
  28. package/dist/a2ui/tree.js +0 -74
  29. package/dist/ag-ui.d.ts +0 -82
  30. package/dist/ag-ui.js +0 -85
  31. package/dist/agui/encoder.d.ts +0 -50
  32. package/dist/agui/encoder.js +0 -97
  33. package/dist/agui/events.d.ts +0 -59
  34. package/dist/agui/events.js +0 -15
  35. package/dist/capability.d.ts +0 -81
  36. package/dist/capability.js +0 -79
  37. package/dist/dom/dom-page-driver.d.ts +0 -36
  38. package/dist/dom/dom-page-driver.js +0 -601
  39. package/dist/dom/index.d.ts +0 -17
  40. package/dist/dom/index.js +0 -17
  41. package/dist/dom/model-context.d.ts +0 -69
  42. package/dist/dom/model-context.js +0 -44
  43. package/dist/element-handles.d.ts +0 -120
  44. package/dist/element-handles.js +0 -39
  45. package/dist/gen-ui/encoder.d.ts +0 -50
  46. package/dist/gen-ui/encoder.js +0 -97
  47. package/dist/gen-ui/events.d.ts +0 -59
  48. package/dist/gen-ui/events.js +0 -15
  49. package/dist/gen-ui/index.d.ts +0 -18
  50. package/dist/gen-ui/index.js +0 -17
  51. package/dist/guards.d.ts +0 -96
  52. package/dist/guards.js +0 -186
  53. package/dist/handle.d.ts +0 -41
  54. package/dist/handle.js +0 -41
  55. package/dist/mcp-ui-apps.d.ts +0 -223
  56. package/dist/mcp-ui-apps.js +0 -252
  57. package/dist/mcp-ui.d.ts +0 -133
  58. package/dist/mcp-ui.js +0 -134
  59. package/dist/page-capabilities.d.ts +0 -14
  60. package/dist/page-capabilities.js +0 -129
  61. package/dist/page-driver.d.ts +0 -120
  62. package/dist/page-driver.js +0 -2
  63. package/dist/page-executor.d.ts +0 -94
  64. package/dist/page-executor.js +0 -320
  65. package/dist/webmcp.d.ts +0 -202
  66. package/dist/webmcp.js +0 -173
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # @jini-ai/agentic
2
2
 
3
+ ## 0.4.2 — 2026-10-06
4
+
5
+ - `@jini-ai/agentic/a2ui`: `A2UI_DISPLAY_ONLY_PROPERTY` (`"displayOnly"` on `createSurface.surfaceProperties`) plus `displayOnlySurfaceIdOf` and `a2uiSurfaceIdOf` readers.
6
+
7
+ ## 0.4.1 — 2026-10-04
8
+
9
+ - `createAnnotatedActionsScript` registers a published page's annotated actions with WebMCP.
10
+ - Internal `@jini-ai/*` dependencies are caret ranges (`workspace:^`) instead of exact pins, so a host on a newer patch resolves a single copy without an override.
11
+
3
12
  ## 0.4.0 — 2026-10-02
4
13
 
5
14
  ### BREAKING
@@ -13,4 +13,5 @@ export * from './json-pointer.js';
13
13
  export * from './resolve.js';
14
14
  export * from './tree.js';
15
15
  export * from './interpreter.js';
16
+ export * from './surface-properties.js';
16
17
  //# sourceMappingURL=index.d.ts.map
@@ -13,4 +13,5 @@ export * from './json-pointer.js';
13
13
  export * from './resolve.js';
14
14
  export * from './tree.js';
15
15
  export * from './interpreter.js';
16
+ export * from './surface-properties.js';
16
17
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @module surface-properties
3
+ *
4
+ * Reading facts about a surface off the raw wire messages, without an interpreter.
5
+ *
6
+ * Why a display-only marker: a host's chat pane treats a surface that arrives while its tool call is
7
+ * still open as a question the person must answer ("Waiting for your answer above"). That is right
8
+ * for a form or a choice, and wrong for a chart a tool draws and then holds its call open only to
9
+ * hear whether the browser refused it (Tovu demo V3, 2026-10-05). The tool that emits the surface is
10
+ * the only party that knows which it is, so it says so on `createSurface.surfaceProperties`, which
11
+ * the v1.0 schema already accepts as an open record; renderers ignore the key.
12
+ */
13
+ /** `createSurface.surfaceProperties` key: `true` means the surface shows something and asks nothing. */
14
+ export declare const A2UI_DISPLAY_ONLY_PROPERTY = "displayOnly";
15
+ /**
16
+ * The `surfaceId` a surface-scoped message (create/update components/update data/delete) names, or
17
+ * `undefined` for any other message or a malformed value. Never throws.
18
+ *
19
+ * @complexity O(1).
20
+ */
21
+ export declare function a2uiSurfaceIdOf({ message }: {
22
+ message: unknown;
23
+ }): string | undefined;
24
+ /**
25
+ * The `surfaceId` of a `createSurface` that declares {@link A2UI_DISPLAY_ONLY_PROPERTY} `true`, else
26
+ * `undefined`. Only `createSurface` carries surface properties, so a caller folding a stream records
27
+ * the id here and matches later messages with {@link a2uiSurfaceIdOf}.
28
+ *
29
+ * @complexity O(1).
30
+ */
31
+ export declare function displayOnlySurfaceIdOf({ message }: {
32
+ message: unknown;
33
+ }): string | undefined;
34
+ //# sourceMappingURL=surface-properties.d.ts.map
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @module surface-properties
3
+ *
4
+ * Reading facts about a surface off the raw wire messages, without an interpreter.
5
+ *
6
+ * Why a display-only marker: a host's chat pane treats a surface that arrives while its tool call is
7
+ * still open as a question the person must answer ("Waiting for your answer above"). That is right
8
+ * for a form or a choice, and wrong for a chart a tool draws and then holds its call open only to
9
+ * hear whether the browser refused it (Tovu demo V3, 2026-10-05). The tool that emits the surface is
10
+ * the only party that knows which it is, so it says so on `createSurface.surfaceProperties`, which
11
+ * the v1.0 schema already accepts as an open record; renderers ignore the key.
12
+ */
13
+ /** `createSurface.surfaceProperties` key: `true` means the surface shows something and asks nothing. */
14
+ export const A2UI_DISPLAY_ONLY_PROPERTY = 'displayOnly';
15
+ const SURFACE_SCOPED_KEYS = ['createSurface', 'updateComponents', 'updateDataModel', 'deleteSurface'];
16
+ function isRecord(value) {
17
+ return typeof value === 'object' && value !== null;
18
+ }
19
+ /**
20
+ * The `surfaceId` a surface-scoped message (create/update components/update data/delete) names, or
21
+ * `undefined` for any other message or a malformed value. Never throws.
22
+ *
23
+ * @complexity O(1).
24
+ */
25
+ export function a2uiSurfaceIdOf({ message }) {
26
+ if (!isRecord(message))
27
+ return undefined;
28
+ for (const key of SURFACE_SCOPED_KEYS) {
29
+ const body = message[key];
30
+ if (isRecord(body) && typeof body.surfaceId === 'string')
31
+ return body.surfaceId;
32
+ }
33
+ return undefined;
34
+ }
35
+ /**
36
+ * The `surfaceId` of a `createSurface` that declares {@link A2UI_DISPLAY_ONLY_PROPERTY} `true`, else
37
+ * `undefined`. Only `createSurface` carries surface properties, so a caller folding a stream records
38
+ * the id here and matches later messages with {@link a2uiSurfaceIdOf}.
39
+ *
40
+ * @complexity O(1).
41
+ */
42
+ export function displayOnlySurfaceIdOf({ message }) {
43
+ const body = isRecord(message) ? message.createSurface : undefined;
44
+ if (!isRecord(body) || typeof body.surfaceId !== 'string')
45
+ return undefined;
46
+ const properties = body.surfaceProperties;
47
+ return isRecord(properties) && properties[A2UI_DISPLAY_ONLY_PROPERTY] === true ? body.surfaceId : undefined;
48
+ }
49
+ //# sourceMappingURL=surface-properties.js.map
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Framework-free script asset for data-toolname/data-tooldescription actions.
3
+ * Native tool* forms remain the browser's responsibility. No polyfill, transport,
4
+ * field-value reader, arbitrary selector input or cross-origin exposure is added.
5
+ * The host owns consent copy and its browser preference key. This string asset
6
+ * can be inlined into static exports without importing a DOM runtime on Node.
7
+ */
8
+ export declare function createAnnotatedActionsScript({ preferenceKey, confirmationMessage, confirmationMessages }: {
9
+ preferenceKey?: string;
10
+ confirmationMessage?: string;
11
+ confirmationMessages?: Readonly<Record<string, string>>;
12
+ }, _optional?: Record<string, never>): string;
13
+ //# sourceMappingURL=annotated-actions-script.d.ts.map
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Framework-free script asset for data-toolname/data-tooldescription actions.
3
+ * Native tool* forms remain the browser's responsibility. No polyfill, transport,
4
+ * field-value reader, arbitrary selector input or cross-origin exposure is added.
5
+ * The host owns consent copy and its browser preference key. This string asset
6
+ * can be inlined into static exports without importing a DOM runtime on Node.
7
+ */
8
+ export function createAnnotatedActionsScript({ preferenceKey, confirmationMessage = 'Allow this browser-agent action?', confirmationMessages = {} }, _optional = {}) {
9
+ const config = JSON.stringify({ preferenceKey, confirmationMessage, confirmationMessages }).replace(/</g, '\\u003c');
10
+ return String.raw `(function install(config) {
11
+ 'use strict';
12
+ var doc = document;
13
+ var locale = (doc.documentElement.lang || 'en').toLowerCase();
14
+ var messages = config.confirmationMessages;
15
+ var confirmation = Object.keys(messages).find(function (key) { return key.toLowerCase() === locale; });
16
+ var confirmationMessage = messages[confirmation] || messages[locale.split('-')[0]] || config.confirmationMessage;
17
+ var stopped = false;
18
+ var registrations = [];
19
+ var observer;
20
+ function enabled() {
21
+ try { return !config.preferenceKey || localStorage.getItem(config.preferenceKey) !== 'false'; }
22
+ catch (_) { return true; }
23
+ }
24
+ function stripNativeForms() {
25
+ doc.querySelectorAll('form[toolname]').forEach(function (form) {
26
+ ['toolname', 'tooldescription', 'toolautosubmit'].forEach(function (name) { form.removeAttribute(name); });
27
+ });
28
+ }
29
+ function stop(event) {
30
+ stopped = true;
31
+ registrations.forEach(function (controller) { controller.abort(); });
32
+ registrations = [];
33
+ if (observer) observer.disconnect();
34
+ window.removeEventListener('storage', onStorage);
35
+ window.removeEventListener('pagehide', stop);
36
+ // A cached Document executes no scripts when the browser restores it.
37
+ // Reinstall on pageshow, while old callbacks remain permanently stopped.
38
+ if (event && event.persisted) window.addEventListener('pageshow', function () { install(config); }, { once: true });
39
+ }
40
+ function onStorage(event) {
41
+ if (event.key !== null && event.key !== config.preferenceKey) return;
42
+ if (!enabled()) { stripNativeForms(); stop(); }
43
+ }
44
+ if (!enabled()) { stripNativeForms(); return; }
45
+ var context = [doc.modelContext, typeof navigator !== 'undefined' && navigator.modelContext].find(function (value) {
46
+ return value && typeof value.registerTool === 'function';
47
+ });
48
+ if (!context || typeof context.registerTool !== 'function') return;
49
+ function visible(element) {
50
+ if (!element.isConnected || element.closest('[hidden], [inert], [aria-hidden="true"], dialog:not([open])')) return false;
51
+ for (var current = element; current; current = current.parentElement) {
52
+ var style = window.getComputedStyle(current);
53
+ if (style.display === 'none' || style.visibility === 'hidden' || style.visibility === 'collapse') return false;
54
+ }
55
+ return true;
56
+ }
57
+ function descriptor(element) {
58
+ var name = element.getAttribute('data-toolname') || '';
59
+ var description = element.getAttribute('data-tooldescription') || '';
60
+ if (!/^[A-Za-z0-9_.-]{1,128}$/.test(name) || !description.trim() || !visible(element)) return null;
61
+ if (element.matches(':disabled, [aria-disabled="true"]')) return null;
62
+ if (element.tagName === 'A') {
63
+ if (!element.hasAttribute('href') || element.hasAttribute('download')) return null;
64
+ var url;
65
+ try { url = new URL(element.getAttribute('href'), doc.baseURI); } catch (_) { return null; }
66
+ if (!/^https?:$/.test(url.protocol) || url.origin !== window.location.origin || url.username || url.password) return null;
67
+ return { name: name, description: description, href: url.href };
68
+ }
69
+ // Inputs and form submission are intentionally absent: declarative forms
70
+ // preserve native validation and human submission, with no secret fields.
71
+ if (element.tagName !== 'BUTTON' || element.type !== 'button') return null;
72
+ return { name: name, description: description, href: null };
73
+ }
74
+ function refresh() {
75
+ registrations.forEach(function (controller) { controller.abort(); });
76
+ registrations = [];
77
+ if (stopped || !enabled()) { stripNativeForms(); stop(); return; }
78
+ var counts = new Map();
79
+ doc.querySelectorAll('[data-toolname], form[toolname]').forEach(function (element) {
80
+ if (!visible(element)) return;
81
+ var name = element.getAttribute('data-toolname') || element.getAttribute('toolname');
82
+ counts.set(name, (counts.get(name) || 0) + 1);
83
+ });
84
+ doc.querySelectorAll('[data-toolname]').forEach(function (element) {
85
+ var action = descriptor(element);
86
+ if (!action || counts.get(action.name) !== 1) return;
87
+ var controller = new AbortController();
88
+ registrations.push(controller);
89
+ function current() {
90
+ var latest = descriptor(element);
91
+ var matches = Array.from(doc.querySelectorAll('[data-toolname], form[toolname]')).filter(function (candidate) {
92
+ return visible(candidate) && (candidate.getAttribute('data-toolname') || candidate.getAttribute('toolname')) === action.name;
93
+ });
94
+ if (stopped || controller.signal.aborted || !enabled() || !latest ||
95
+ matches.length !== 1 || latest.name !== action.name || latest.description !== action.description || latest.href !== action.href) {
96
+ throw new Error('Browser-agent action is unavailable');
97
+ }
98
+ }
99
+ var tool = {
100
+ name: action.name,
101
+ description: action.description,
102
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
103
+ annotations: { readOnlyHint: action.href !== null },
104
+ execute: async function (args) {
105
+ current();
106
+ if (!args || typeof args !== 'object' || Array.isArray(args) || Object.keys(args).length !== 0) {
107
+ throw new Error('This action takes no arguments');
108
+ }
109
+ if (action.href !== null) {
110
+ // Navigation has no click-handler side effects and cannot forward
111
+ // arbitrary agent-supplied URLs or use a theme's cross-origin base.
112
+ window.location.assign(action.href);
113
+ return { navigationRequested: true };
114
+ }
115
+ if (!window.confirm(confirmationMessage + '\n\n' + action.description)) {
116
+ throw new Error('Browser-agent action declined');
117
+ }
118
+ current();
119
+ element.click();
120
+ // Activation acknowledges the UI event, never business success.
121
+ return { activated: true };
122
+ }
123
+ };
124
+ try {
125
+ Promise.resolve(context.registerTool(tool, { signal: controller.signal })).catch(function () { controller.abort(); });
126
+ } catch (_) { controller.abort(); }
127
+ });
128
+ }
129
+ window.addEventListener('pagehide', stop);
130
+ window.addEventListener('storage', onStorage);
131
+ refresh();
132
+ observer = new MutationObserver(refresh);
133
+ observer.observe(doc.documentElement, { subtree: true, childList: true, attributes: true,
134
+ attributeFilter: ['data-toolname', 'data-tooldescription', 'toolname', 'href', 'download', 'type', 'disabled', 'aria-disabled', 'hidden', 'inert', 'aria-hidden', 'style', 'class', 'open'] });
135
+ })(` + config + ');';
136
+ }
137
+ //# sourceMappingURL=annotated-actions-script.js.map
@@ -73,4 +73,5 @@ export { toAgUiTool, toAgUiTools, createAgUiToolResult, AG_UI_TOOL_CALL_EVENTS,
73
73
  export { createGenUiEncoder, type GenUiEncodeContext, type GenUiEncoder, type GenUiAgentMessageEvent, type GenUiEvent, type GenUiEventBase, type GenUiEventKind, type GenUiRunLifecycleEvent, type GenUiStateUpdateEvent, type GenUiSurfaceRequestedEvent, type GenUiSurfaceRespondedEvent, type GenUiToolCallEvent, } from './gen-ui/index.js';
74
74
  export { MCP_UI_VIEW_METHODS, MCP_UI_HOST_NOTIFICATIONS, MCP_UI_VIEW_NOTIFICATIONS, MCP_UI_HOST_REQUESTS, MCP_UI_SANDBOX_NOTE, JINI_PAGE_ACTION_METHOD, JSON_RPC_ERROR_CODES, isJsonRpcMessage, isJsonRpcRequest, createJsonRpcRequest, createJsonRpcNotification, createJsonRpcResult, createJsonRpcError, createPageActionRequest, type JsonRpcMessage, type JsonRpcRequest, type JsonRpcNotification, type JsonRpcResponse, type JsonRpcError, } from './mcp-ui-apps.js';
75
75
  export { defaultAgenticMessages } from "./messages.js";
76
+ export { createAnnotatedActionsScript } from './annotated-actions-script.js';
76
77
  //# sourceMappingURL=index.d.ts.map
@@ -72,4 +72,5 @@ export { toAgUiTool, toAgUiTools, createAgUiToolResult, AG_UI_TOOL_CALL_EVENTS,
72
72
  export { createGenUiEncoder, } from './gen-ui/index.js';
73
73
  export { MCP_UI_VIEW_METHODS, MCP_UI_HOST_NOTIFICATIONS, MCP_UI_VIEW_NOTIFICATIONS, MCP_UI_HOST_REQUESTS, MCP_UI_SANDBOX_NOTE, JINI_PAGE_ACTION_METHOD, JSON_RPC_ERROR_CODES, isJsonRpcMessage, isJsonRpcRequest, createJsonRpcRequest, createJsonRpcNotification, createJsonRpcResult, createJsonRpcError, createPageActionRequest, } from './mcp-ui-apps.js';
74
74
  export { defaultAgenticMessages } from "./messages.js";
75
+ export { createAnnotatedActionsScript } from './annotated-actions-script.js';
75
76
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jini-ai/agentic",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "Framework-free agent-control layer: page-capability vocabulary and manifests, the data-agent-* markup convention, AG-UI projection, generative-UI streams, and A2UI.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -75,7 +75,7 @@
75
75
  "dependencies": {
76
76
  "zod": "^3.25.76",
77
77
  "@jini-ai/core": "^0.4.0",
78
- "@jini-ai/protocol": "0.4.0"
78
+ "@jini-ai/protocol": "^0.4.0"
79
79
  },
80
80
  "devDependencies": {
81
81
  "@vitest/coverage-v8": "^2.1.9",