@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.
@@ -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: { type: "array", description: "Alternative search phrases for the same navigation task. Use instead of query.", minItems: 1, maxItems: 3, items: { type: "string", minLength: 1 } },
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.normalize("NFKC").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").toLowerCase();
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)].filter((part) => part.isWordLike).map((part) => part.segment);
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 ? characters : characters.slice(1).map((character, index) => characters[index] + character);
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].sort(([left, a], [right, b]) => {
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
- }).slice(0, 5).map(([tool]) => tool);
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" ? new Intl.Segmenter("zh", { granularity: "word" }) : undefined;
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.map((document) => {
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 + idf.get(term) * frequency * 2.2 / (frequency + 1.2 * (0.25 + 0.75 * document.length / averageLength));
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
- }).filter(({ score }) => score > 0).sort((left, right) => {
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
- }).slice(0, 5).map(({ tool }) => tool);
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 { status: current.status === "ending" ? "ending" : "active", operationId: operation.id };
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: { type: "object", properties: { operationId: { type: "string" } }, required: ["operationId"], additionalProperties: false },
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 || typeof args !== "object" || Array.isArray(args) || typeof args.operationId !== "string" || Object.keys(args).some((key) => key !== "operationId"))
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 || owned.id !== operationId || runtime.getActivitySnapshot().operation?.id !== operationId)
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 ?? { type: "object", properties: {}, additionalProperties: false },
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 || typeof args !== "object" || Array.isArray(args)
169
- || !args.input || typeof args.input !== "object" || Array.isArray(args.input)
170
- || Object.keys(args).some((key) => key !== "input" && key !== "progressLabel")
171
- || (args.progressLabel !== undefined && typeof args.progressLabel !== "string")) {
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" ? { progressLabel: args.progressLabel } : {}),
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.getWebMcpTools().filter((tool) => !["nxf_beginOperation", "nxf_endOperation"].includes(tool.definition.name)).map((tool) => [tool.definition.name, tool]));
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexface/tools",
3
- "version": "0.1.13-alpha.4",
3
+ "version": "0.1.13-alpha.5",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {