@copilotkit/core 1.70.0 → 1.70.1
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/index.cjs +170 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +112 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +112 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +169 -31
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +169 -30
- package/dist/index.umd.js.map +1 -1
- package/package.json +2 -2
package/dist/index.umd.js
CHANGED
|
@@ -2491,6 +2491,141 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2491
2491
|
return normalizeToolResultContent(content) === FORWARDED_TO_CLIENT;
|
|
2492
2492
|
}
|
|
2493
2493
|
|
|
2494
|
+
//#endregion
|
|
2495
|
+
//#region src/core/tool-schema.ts
|
|
2496
|
+
/**
|
|
2497
|
+
* Empty tool schema constant
|
|
2498
|
+
*/
|
|
2499
|
+
const EMPTY_TOOL_SCHEMA = {
|
|
2500
|
+
type: "object",
|
|
2501
|
+
properties: {}
|
|
2502
|
+
};
|
|
2503
|
+
/**
|
|
2504
|
+
* Create a JSON schema from a tool's parameters
|
|
2505
|
+
*/
|
|
2506
|
+
function createToolSchema(tool) {
|
|
2507
|
+
if (!tool.parameters) return { ...EMPTY_TOOL_SCHEMA };
|
|
2508
|
+
const rawSchema = (0, _copilotkit_shared.schemaToJsonSchema)(tool.parameters, { zodToJsonSchema: (schema, options) => (0, zod_to_json_schema.zodToJsonSchema)(schema, options) });
|
|
2509
|
+
if (!rawSchema || typeof rawSchema !== "object") return { ...EMPTY_TOOL_SCHEMA };
|
|
2510
|
+
const { $schema: _$schema, ...schema } = rawSchema;
|
|
2511
|
+
if (typeof schema.type !== "string") schema.type = "object";
|
|
2512
|
+
if (typeof schema.properties !== "object" || schema.properties === null) schema.properties = {};
|
|
2513
|
+
stripAdditionalProperties(schema);
|
|
2514
|
+
return schema;
|
|
2515
|
+
}
|
|
2516
|
+
/**
|
|
2517
|
+
* Remove every `additionalProperties` key from a JSON schema tree, in place.
|
|
2518
|
+
* Some LLM providers reject schemas that carry it.
|
|
2519
|
+
*/
|
|
2520
|
+
function stripAdditionalProperties(schema) {
|
|
2521
|
+
if (!schema || typeof schema !== "object") return;
|
|
2522
|
+
if (Array.isArray(schema)) {
|
|
2523
|
+
schema.forEach(stripAdditionalProperties);
|
|
2524
|
+
return;
|
|
2525
|
+
}
|
|
2526
|
+
const record = schema;
|
|
2527
|
+
if (record.additionalProperties !== void 0) delete record.additionalProperties;
|
|
2528
|
+
for (const value of Object.values(record)) stripAdditionalProperties(value);
|
|
2529
|
+
}
|
|
2530
|
+
|
|
2531
|
+
//#endregion
|
|
2532
|
+
//#region src/core/webmcp.ts
|
|
2533
|
+
/**
|
|
2534
|
+
* Return the page's `document.modelContext`, or null when WebMCP is not
|
|
2535
|
+
* available (SSR, React Native, browsers without the API enabled).
|
|
2536
|
+
*/
|
|
2537
|
+
function getWebMCPModelContext() {
|
|
2538
|
+
if (typeof document === "undefined") return null;
|
|
2539
|
+
const modelContext = document.modelContext;
|
|
2540
|
+
return modelContext !== null && modelContext !== void 0 ? modelContext : null;
|
|
2541
|
+
}
|
|
2542
|
+
/**
|
|
2543
|
+
* Keeps a set of frontend tools registered on the page's WebMCP model context.
|
|
2544
|
+
*
|
|
2545
|
+
* `sync(desired)` reconciles the registrations with the desired set: tools that
|
|
2546
|
+
* are gone (or were re-registered with a new tool object) are unregistered by
|
|
2547
|
+
* aborting their registration signal, and new tools are registered with an
|
|
2548
|
+
* `execute` that delegates to the frontend tool's own handler.
|
|
2549
|
+
*
|
|
2550
|
+
* All WebMCP-API constraints live here so callers only supply the desired set:
|
|
2551
|
+
* a tool without a description is skipped with a warning (the spec rejects
|
|
2552
|
+
* empty descriptions), and failures from `registerTool` (duplicate name,
|
|
2553
|
+
* unsupported context, ...) are warned rather than thrown.
|
|
2554
|
+
*/
|
|
2555
|
+
var WebMCPRegistry = class {
|
|
2556
|
+
constructor() {
|
|
2557
|
+
_defineProperty(this, "entries", /* @__PURE__ */ new Map());
|
|
2558
|
+
_defineProperty(this, "warnedNames", /* @__PURE__ */ new Set());
|
|
2559
|
+
}
|
|
2560
|
+
/** Names currently kept registered on the model context. */
|
|
2561
|
+
get registeredNames() {
|
|
2562
|
+
return [...this.entries.keys()];
|
|
2563
|
+
}
|
|
2564
|
+
/** Reconcile the registered tools with the desired set. */
|
|
2565
|
+
sync(desired) {
|
|
2566
|
+
const modelContext = getWebMCPModelContext();
|
|
2567
|
+
if (!modelContext) return;
|
|
2568
|
+
for (const [name, entry] of [...this.entries]) if (desired.get(name) !== entry.tool) {
|
|
2569
|
+
entry.controller.abort();
|
|
2570
|
+
this.entries.delete(name);
|
|
2571
|
+
}
|
|
2572
|
+
for (const [name, tool] of desired) {
|
|
2573
|
+
if (this.entries.has(name)) continue;
|
|
2574
|
+
if (!tool.description) {
|
|
2575
|
+
this.warnOnce(name, `Skipping WebMCP registration for tool '${name}': WebMCP requires a description.`);
|
|
2576
|
+
continue;
|
|
2577
|
+
}
|
|
2578
|
+
const controller = new AbortController();
|
|
2579
|
+
this.entries.set(name, {
|
|
2580
|
+
tool,
|
|
2581
|
+
controller
|
|
2582
|
+
});
|
|
2583
|
+
modelContext.registerTool(this.buildModelContextTool(tool), { signal: controller.signal }).catch((error) => {
|
|
2584
|
+
var _this$entries$get;
|
|
2585
|
+
if (((_this$entries$get = this.entries.get(name)) === null || _this$entries$get === void 0 ? void 0 : _this$entries$get.controller) !== controller) return;
|
|
2586
|
+
this.entries.delete(name);
|
|
2587
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2588
|
+
this.warnOnce(name, `WebMCP registration failed for tool '${name}': ${message}`);
|
|
2589
|
+
});
|
|
2590
|
+
}
|
|
2591
|
+
}
|
|
2592
|
+
/**
|
|
2593
|
+
* Build the WebMCP model-context tool for a frontend tool. The `execute`
|
|
2594
|
+
* callback delegates to the frontend tool's own handler, so a browser agent
|
|
2595
|
+
* call runs the same application code as an agent call.
|
|
2596
|
+
*/
|
|
2597
|
+
buildModelContextTool(tool) {
|
|
2598
|
+
const annotations = typeof tool.webmcp === "object" ? tool.webmcp.annotations : void 0;
|
|
2599
|
+
return {
|
|
2600
|
+
name: tool.name,
|
|
2601
|
+
description: tool.description,
|
|
2602
|
+
inputSchema: createToolSchema(tool),
|
|
2603
|
+
execute: async (args, options) => {
|
|
2604
|
+
if (!tool.handler) return "";
|
|
2605
|
+
const toolCall = {
|
|
2606
|
+
id: (0, _copilotkit_shared.randomUUID)(),
|
|
2607
|
+
type: "function",
|
|
2608
|
+
function: {
|
|
2609
|
+
name: tool.name,
|
|
2610
|
+
arguments: JSON.stringify(args !== null && args !== void 0 ? args : {})
|
|
2611
|
+
}
|
|
2612
|
+
};
|
|
2613
|
+
return await tool.handler(args, {
|
|
2614
|
+
toolCall,
|
|
2615
|
+
signal: options === null || options === void 0 ? void 0 : options.signal
|
|
2616
|
+
});
|
|
2617
|
+
},
|
|
2618
|
+
...annotations ? { annotations } : {}
|
|
2619
|
+
};
|
|
2620
|
+
}
|
|
2621
|
+
/** Log `message` once per tool name. Repeated syncs must not spam the log. */
|
|
2622
|
+
warnOnce(name, message) {
|
|
2623
|
+
if (this.warnedNames.has(name)) return;
|
|
2624
|
+
this.warnedNames.add(name);
|
|
2625
|
+
_copilotkit_shared.logger.warn(`[CopilotKit] ${message}`);
|
|
2626
|
+
}
|
|
2627
|
+
};
|
|
2628
|
+
|
|
2494
2629
|
//#endregion
|
|
2495
2630
|
//#region src/core/run-handler.ts
|
|
2496
2631
|
/**
|
|
@@ -2527,6 +2662,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2527
2662
|
_defineProperty(this, "_disabledToolKeys", /* @__PURE__ */ new Set());
|
|
2528
2663
|
_defineProperty(this, "_runAbortController", null);
|
|
2529
2664
|
_defineProperty(this, "_runDepth", 0);
|
|
2665
|
+
_defineProperty(this, "_webmcpRegistry", new WebMCPRegistry());
|
|
2530
2666
|
_defineProperty(this, "_lastConnectedThreadIdsByAgent", /* @__PURE__ */ new Map());
|
|
2531
2667
|
_defineProperty(this, "_anonymousAgentIds", /* @__PURE__ */ new WeakMap());
|
|
2532
2668
|
_defineProperty(this, "_nextAnonymousAgentId", 0);
|
|
@@ -2581,6 +2717,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2581
2717
|
initialize(tools) {
|
|
2582
2718
|
this._propTools = [...tools];
|
|
2583
2719
|
this._cachedMergedTools = null;
|
|
2720
|
+
this.syncWebMCP();
|
|
2584
2721
|
}
|
|
2585
2722
|
/**
|
|
2586
2723
|
* Add a tool to the registry. Survives provider re-syncs ({@link setTools}),
|
|
@@ -2594,6 +2731,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2594
2731
|
}
|
|
2595
2732
|
this._hookTools.set(key, tool);
|
|
2596
2733
|
this._cachedMergedTools = null;
|
|
2734
|
+
this.syncWebMCP();
|
|
2597
2735
|
}
|
|
2598
2736
|
/**
|
|
2599
2737
|
* Remove a tool by name and optionally by agentId
|
|
@@ -2605,6 +2743,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2605
2743
|
return !(tool.name === id && !tool.agentId);
|
|
2606
2744
|
});
|
|
2607
2745
|
this._cachedMergedTools = null;
|
|
2746
|
+
this.syncWebMCP();
|
|
2608
2747
|
}
|
|
2609
2748
|
/**
|
|
2610
2749
|
* Get a tool by name and optionally by agentId.
|
|
@@ -2627,6 +2766,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2627
2766
|
setTools(tools) {
|
|
2628
2767
|
this._propTools = [...tools];
|
|
2629
2768
|
this._cachedMergedTools = null;
|
|
2769
|
+
this.syncWebMCP();
|
|
2630
2770
|
}
|
|
2631
2771
|
/**
|
|
2632
2772
|
* Return the registered A2UI catalog components (readonly).
|
|
@@ -3172,6 +3312,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3172
3312
|
const key = this.capabilityKey(name, agentId);
|
|
3173
3313
|
if (enabled) this._disabledToolKeys.delete(key);
|
|
3174
3314
|
else this._disabledToolKeys.add(key);
|
|
3315
|
+
this.syncWebMCP();
|
|
3175
3316
|
}
|
|
3176
3317
|
/** Whether a tool is currently enabled (not overridden off). Defaults true. */
|
|
3177
3318
|
isToolEnabled(name, agentId) {
|
|
@@ -3191,6 +3332,32 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3191
3332
|
});
|
|
3192
3333
|
}
|
|
3193
3334
|
/**
|
|
3335
|
+
* Reconcile the WebMCP registrations with the current tool registry. Tools
|
|
3336
|
+
* opt in via `webmcp: true` or `webmcp: { annotations }`; the same
|
|
3337
|
+
* availability rules as `buildFrontendTools` apply. WebMCP tools are
|
|
3338
|
+
* page-level, so unlike the agent tool list they are not filtered by
|
|
3339
|
+
* agentId — a name collision across agentIds keeps the first registration.
|
|
3340
|
+
*/
|
|
3341
|
+
syncWebMCP() {
|
|
3342
|
+
const desired = /* @__PURE__ */ new Map();
|
|
3343
|
+
const warnedCollisions = /* @__PURE__ */ new Set();
|
|
3344
|
+
for (const tool of this.tools) {
|
|
3345
|
+
if (!tool.webmcp) continue;
|
|
3346
|
+
if (tool.name === WILDCARD_TOOL_NAME) continue;
|
|
3347
|
+
if (tool.available === false || tool.available === "disabled") continue;
|
|
3348
|
+
if (!this.isToolEnabled(tool.name, tool.agentId)) continue;
|
|
3349
|
+
if (desired.has(tool.name)) {
|
|
3350
|
+
if (!warnedCollisions.has(tool.name)) {
|
|
3351
|
+
warnedCollisions.add(tool.name);
|
|
3352
|
+
_copilotkit_shared.logger.warn(`[CopilotKit] Multiple WebMCP tools share the name '${tool.name}'. Only the first registration is exposed to browser agents.`);
|
|
3353
|
+
}
|
|
3354
|
+
continue;
|
|
3355
|
+
}
|
|
3356
|
+
desired.set(tool.name, tool);
|
|
3357
|
+
}
|
|
3358
|
+
this._webmcpRegistry.sync(desired);
|
|
3359
|
+
}
|
|
3360
|
+
/**
|
|
3194
3361
|
* Create an agent error subscriber
|
|
3195
3362
|
*/
|
|
3196
3363
|
createAgentErrorSubscriber(agent) {
|
|
@@ -3224,36 +3391,6 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3224
3391
|
}
|
|
3225
3392
|
};
|
|
3226
3393
|
/**
|
|
3227
|
-
* Empty tool schema constant
|
|
3228
|
-
*/
|
|
3229
|
-
const EMPTY_TOOL_SCHEMA = {
|
|
3230
|
-
type: "object",
|
|
3231
|
-
properties: {}
|
|
3232
|
-
};
|
|
3233
|
-
/**
|
|
3234
|
-
* Create a JSON schema from a tool's parameters
|
|
3235
|
-
*/
|
|
3236
|
-
function createToolSchema(tool) {
|
|
3237
|
-
if (!tool.parameters) return { ...EMPTY_TOOL_SCHEMA };
|
|
3238
|
-
const rawSchema = (0, _copilotkit_shared.schemaToJsonSchema)(tool.parameters, { zodToJsonSchema: (schema, options) => (0, zod_to_json_schema.zodToJsonSchema)(schema, options) });
|
|
3239
|
-
if (!rawSchema || typeof rawSchema !== "object") return { ...EMPTY_TOOL_SCHEMA };
|
|
3240
|
-
const { $schema: _$schema, ...schema } = rawSchema;
|
|
3241
|
-
if (typeof schema.type !== "string") schema.type = "object";
|
|
3242
|
-
if (typeof schema.properties !== "object" || schema.properties === null) schema.properties = {};
|
|
3243
|
-
stripAdditionalProperties(schema);
|
|
3244
|
-
return schema;
|
|
3245
|
-
}
|
|
3246
|
-
function stripAdditionalProperties(schema) {
|
|
3247
|
-
if (!schema || typeof schema !== "object") return;
|
|
3248
|
-
if (Array.isArray(schema)) {
|
|
3249
|
-
schema.forEach(stripAdditionalProperties);
|
|
3250
|
-
return;
|
|
3251
|
-
}
|
|
3252
|
-
const record = schema;
|
|
3253
|
-
if (record.additionalProperties !== void 0) delete record.additionalProperties;
|
|
3254
|
-
for (const value of Object.values(record)) stripAdditionalProperties(value);
|
|
3255
|
-
}
|
|
3256
|
-
/**
|
|
3257
3394
|
* Ensures parsed tool arguments are a plain object.
|
|
3258
3395
|
* Throws for non-object values so the caller's catch block can emit
|
|
3259
3396
|
* a structured TOOL_ARGUMENT_PARSE_FAILED error.
|
|
@@ -6781,6 +6918,7 @@ exports.RunHandler = RunHandler;
|
|
|
6781
6918
|
exports.StateManager = StateManager;
|
|
6782
6919
|
exports.SuggestionEngine = SuggestionEngine;
|
|
6783
6920
|
exports.ToolCallStatus = ToolCallStatus;
|
|
6921
|
+
exports.WebMCPRegistry = WebMCPRegistry;
|
|
6784
6922
|
exports.completePartialMarkdown = completePartialMarkdown;
|
|
6785
6923
|
exports.createActionGroup = createActionGroup;
|
|
6786
6924
|
exports.createEffect = createEffect;
|
|
@@ -6794,6 +6932,7 @@ exports.emitInspectorViewThread = emitInspectorViewThread;
|
|
|
6794
6932
|
exports.emitInspectorViewThreadResult = emitInspectorViewThreadResult;
|
|
6795
6933
|
exports.empty = empty;
|
|
6796
6934
|
exports.ensureObjectArgs = ensureObjectArgs;
|
|
6935
|
+
exports.getWebMCPModelContext = getWebMCPModelContext;
|
|
6797
6936
|
exports.isAbortError = isAbortError;
|
|
6798
6937
|
exports.isInspectorThreadBridgeEnabled = isInspectorThreadBridgeEnabled;
|
|
6799
6938
|
exports.isRunCompletionAware = isRunCompletionAware;
|