@nexface/tools 0.1.13-alpha.4 → 0.1.13-alpha.5
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/dist/browser/actions.js +34 -9
- package/dist/browser/controller.js +53 -73
- package/dist/browser/diagnostics.js +8 -2
- package/dist/browser/dom.js +12 -27
- package/dist/browser/feedback.js +6 -4
- package/dist/browser/locator.js +3 -8
- package/dist/browser/snapshot.js +10 -21
- package/dist/browser/toolset.js +42 -35
- package/dist/browser/types.d.ts +1 -1
- package/dist/definition.d.ts +1 -3
- package/dist/definition.js +2 -1
- package/dist/internal-react.d.ts +1 -1
- package/dist/internal-react.js +3 -3
- package/dist/operation-lock.js +36 -1
- package/dist/operation-runtime.js +41 -12
- package/dist/operation-surface.js +118 -40
- package/dist/operation-view.d.ts +1 -1
- package/dist/operation-view.js +120 -59
- package/dist/react.js +6 -8
- package/dist/registration.js +3 -1
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +66 -44
- package/dist/shared/errors.d.ts +1 -1
- package/dist/shared/schema.js +45 -18
- package/dist/styles.css +879 -109
- package/dist/tool-search.js +37 -11
- package/dist/webmcp.js +38 -11
- package/package.json +1 -1
package/dist/tool-search.js
CHANGED
|
@@ -7,21 +7,35 @@ export const searchToolDefinition = createAgentToolDefinition({
|
|
|
7
7
|
type: "object",
|
|
8
8
|
properties: {
|
|
9
9
|
query: { type: "string", description: "Page name, purpose, or exact navigation tool name." },
|
|
10
|
-
queries: {
|
|
10
|
+
queries: {
|
|
11
|
+
type: "array",
|
|
12
|
+
description: "Alternative search phrases for the same navigation task. Use instead of query.",
|
|
13
|
+
minItems: 1,
|
|
14
|
+
maxItems: 3,
|
|
15
|
+
items: { type: "string", minLength: 1 },
|
|
16
|
+
},
|
|
11
17
|
},
|
|
12
18
|
additionalProperties: false,
|
|
13
19
|
},
|
|
14
20
|
});
|
|
15
21
|
function tokenize(text, segmenter) {
|
|
16
|
-
const normalized = text
|
|
22
|
+
const normalized = text
|
|
23
|
+
.normalize("NFKC")
|
|
24
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1 $2")
|
|
25
|
+
.replace(/[_-]+/g, " ")
|
|
26
|
+
.toLowerCase();
|
|
17
27
|
if (segmenter) {
|
|
18
|
-
return [...segmenter.segment(normalized)]
|
|
28
|
+
return [...segmenter.segment(normalized)]
|
|
29
|
+
.filter((part) => part.isWordLike)
|
|
30
|
+
.map((part) => part.segment);
|
|
19
31
|
}
|
|
20
32
|
return (normalized.match(/\p{Script=Han}+|[\p{L}\p{N}]+/gu) ?? []).flatMap((word) => {
|
|
21
33
|
if (!/^\p{Script=Han}+$/u.test(word))
|
|
22
34
|
return [word];
|
|
23
35
|
const characters = [...word];
|
|
24
|
-
return characters.length < 2
|
|
36
|
+
return characters.length < 2
|
|
37
|
+
? characters
|
|
38
|
+
: characters.slice(1).map((character, index) => characters[index] + character);
|
|
25
39
|
});
|
|
26
40
|
}
|
|
27
41
|
function schemaText(value) {
|
|
@@ -51,16 +65,21 @@ export function searchNavigationTools(tools, query) {
|
|
|
51
65
|
scores.set(tool, (scores.get(tool) ?? 0) + 1 / (60 + index + 1));
|
|
52
66
|
});
|
|
53
67
|
}
|
|
54
|
-
return [...scores]
|
|
68
|
+
return [...scores]
|
|
69
|
+
.sort(([left, a], [right, b]) => {
|
|
55
70
|
const x = left.definition.name;
|
|
56
71
|
const y = right.definition.name;
|
|
57
72
|
return b - a || (x < y ? -1 : x > y ? 1 : 0);
|
|
58
|
-
})
|
|
73
|
+
})
|
|
74
|
+
.slice(0, 5)
|
|
75
|
+
.map(([tool]) => tool);
|
|
59
76
|
}
|
|
60
77
|
const exact = tools.find((tool) => tool.definition.name === query);
|
|
61
78
|
if (exact)
|
|
62
79
|
return [exact];
|
|
63
|
-
const segmenter = typeof Intl.Segmenter === "function"
|
|
80
|
+
const segmenter = typeof Intl.Segmenter === "function"
|
|
81
|
+
? new Intl.Segmenter("zh", { granularity: "word" })
|
|
82
|
+
: undefined;
|
|
64
83
|
const terms = [...new Set(tokenize(query, segmenter))];
|
|
65
84
|
if (!terms.length || !tools.length)
|
|
66
85
|
return [];
|
|
@@ -77,15 +96,22 @@ export function searchNavigationTools(tools, query) {
|
|
|
77
96
|
const count = documents.filter((document) => document.frequencies.has(term)).length;
|
|
78
97
|
return [term, Math.log(1 + (documents.length - count + 0.5) / (count + 0.5))];
|
|
79
98
|
}));
|
|
80
|
-
return documents
|
|
99
|
+
return documents
|
|
100
|
+
.map((document) => {
|
|
81
101
|
const score = terms.reduce((sum, term) => {
|
|
82
102
|
const frequency = document.frequencies.get(term) ?? 0;
|
|
83
|
-
return sum +
|
|
103
|
+
return (sum +
|
|
104
|
+
(idf.get(term) * frequency * 2.2) /
|
|
105
|
+
(frequency + 1.2 * (0.25 + (0.75 * document.length) / averageLength)));
|
|
84
106
|
}, 0);
|
|
85
107
|
return { tool: document.tool, score };
|
|
86
|
-
})
|
|
108
|
+
})
|
|
109
|
+
.filter(({ score }) => score > 0)
|
|
110
|
+
.sort((left, right) => {
|
|
87
111
|
const a = left.tool.definition.name;
|
|
88
112
|
const b = right.tool.definition.name;
|
|
89
113
|
return right.score - left.score || (a < b ? -1 : a > b ? 1 : 0);
|
|
90
|
-
})
|
|
114
|
+
})
|
|
115
|
+
.slice(0, 5)
|
|
116
|
+
.map(({ tool }) => tool);
|
|
91
117
|
}
|
package/dist/webmcp.js
CHANGED
|
@@ -94,7 +94,10 @@ function createConnection(runtime, modelContext) {
|
|
|
94
94
|
throw new TypeError("nxf_beginOperation requires {}.");
|
|
95
95
|
const current = runtime.getActivitySnapshot().operation;
|
|
96
96
|
if (operation && current?.id === operation.id) {
|
|
97
|
-
return {
|
|
97
|
+
return {
|
|
98
|
+
status: current.status === "ending" ? "ending" : "active",
|
|
99
|
+
operationId: operation.id,
|
|
100
|
+
};
|
|
98
101
|
}
|
|
99
102
|
operation = undefined;
|
|
100
103
|
try {
|
|
@@ -111,16 +114,27 @@ function createConnection(runtime, modelContext) {
|
|
|
111
114
|
const end = {
|
|
112
115
|
name: "nxf_endOperation",
|
|
113
116
|
description: "End the page operation identified by operationId after all page work. Waits for its admitted tools to settle. Does not stop an external agent or undo changes.",
|
|
114
|
-
inputSchema: {
|
|
117
|
+
inputSchema: {
|
|
118
|
+
type: "object",
|
|
119
|
+
properties: { operationId: { type: "string" } },
|
|
120
|
+
required: ["operationId"],
|
|
121
|
+
additionalProperties: false,
|
|
122
|
+
},
|
|
115
123
|
execute: async (input, options = {}) => {
|
|
116
124
|
options.signal?.throwIfAborted();
|
|
117
125
|
controls.signal.throwIfAborted();
|
|
118
126
|
const args = input;
|
|
119
|
-
if (!args ||
|
|
127
|
+
if (!args ||
|
|
128
|
+
typeof args !== "object" ||
|
|
129
|
+
Array.isArray(args) ||
|
|
130
|
+
typeof args.operationId !== "string" ||
|
|
131
|
+
Object.keys(args).some((key) => key !== "operationId"))
|
|
120
132
|
throw new TypeError("nxf_endOperation requires { operationId: string }.");
|
|
121
133
|
const operationId = args.operationId;
|
|
122
134
|
const owned = operation;
|
|
123
|
-
if (!owned ||
|
|
135
|
+
if (!owned ||
|
|
136
|
+
owned.id !== operationId ||
|
|
137
|
+
runtime.getActivitySnapshot().operation?.id !== operationId)
|
|
124
138
|
return { status: "not_active", operationId };
|
|
125
139
|
await owned.end();
|
|
126
140
|
if (operation === owned)
|
|
@@ -154,7 +168,11 @@ function createConnection(runtime, modelContext) {
|
|
|
154
168
|
inputSchema: {
|
|
155
169
|
type: "object",
|
|
156
170
|
properties: {
|
|
157
|
-
input: definition.inputSchema ?? {
|
|
171
|
+
input: definition.inputSchema ?? {
|
|
172
|
+
type: "object",
|
|
173
|
+
properties: {},
|
|
174
|
+
additionalProperties: false,
|
|
175
|
+
},
|
|
158
176
|
progressLabel: {
|
|
159
177
|
type: "string",
|
|
160
178
|
description: "Briefly describe this tool action in the user’s language. Do not expose internal identifiers or claim success before completion.",
|
|
@@ -165,15 +183,21 @@ function createConnection(runtime, modelContext) {
|
|
|
165
183
|
},
|
|
166
184
|
execute: async (parameters, options = {}) => {
|
|
167
185
|
const args = parameters;
|
|
168
|
-
if (!args ||
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
186
|
+
if (!args ||
|
|
187
|
+
typeof args !== "object" ||
|
|
188
|
+
Array.isArray(args) ||
|
|
189
|
+
!args.input ||
|
|
190
|
+
typeof args.input !== "object" ||
|
|
191
|
+
Array.isArray(args.input) ||
|
|
192
|
+
Object.keys(args).some((key) => key !== "input" && key !== "progressLabel") ||
|
|
193
|
+
(args.progressLabel !== undefined && typeof args.progressLabel !== "string")) {
|
|
172
194
|
throw new TypeError("WebMCP tools require { input: object, progressLabel?: string }.");
|
|
173
195
|
}
|
|
174
196
|
return runtime.execute(tool, args.input, {
|
|
175
197
|
...(options.signal ? { signal: options.signal } : {}),
|
|
176
|
-
...(typeof args.progressLabel === "string"
|
|
198
|
+
...(typeof args.progressLabel === "string"
|
|
199
|
+
? { progressLabel: args.progressLabel }
|
|
200
|
+
: {}),
|
|
177
201
|
});
|
|
178
202
|
},
|
|
179
203
|
}, { signal: controller.signal });
|
|
@@ -193,7 +217,10 @@ function createConnection(runtime, modelContext) {
|
|
|
193
217
|
});
|
|
194
218
|
};
|
|
195
219
|
const reconcile = () => {
|
|
196
|
-
const tools = new Map(runtime
|
|
220
|
+
const tools = new Map(runtime
|
|
221
|
+
.getWebMcpTools()
|
|
222
|
+
.filter((tool) => !["nxf_beginOperation", "nxf_endOperation"].includes(tool.definition.name))
|
|
223
|
+
.map((tool) => [tool.definition.name, tool]));
|
|
197
224
|
for (const [name, registration] of registrations) {
|
|
198
225
|
if (tools.get(name) === registration.tool)
|
|
199
226
|
continue;
|