Files
NetMesh/electron/capabilities/codegen/toolSurfaces.cjs
zhaolei 3c72efcb7f
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
[Init] Initial commit - NetMesh terminal manager
2026-09-13 18:24:01 +08:00

205 lines
6.4 KiB
JavaScript

"use strict";
const { AGENT_KINDS, CAPABILITY_STATUS, CAPABILITY_SURFACES } = require("../constants.cjs");
const { ALL_CAPABILITIES } = require("../catalog/index.cjs");
const { TOOL_INPUT_FIELDS, MODEL_DESCRIPTION_HINTS } = require("../schemas/toolInputs.cjs");
function buildZodShape(fields) {
const shape = {};
for (const [key, field] of Object.entries(fields || {})) {
shape[key] = {
type: field.type,
optional: Boolean(field.optional),
description: field.description || "",
};
}
return shape;
}
function getMcpToolName(capability) {
return capability.surfaces?.public?.mcpTool
|| capability.surfaces?.builtin?.mcpTool
|| null;
}
function getCattyToolName(capability) {
return capability.surfaces?.[CAPABILITY_SURFACES.CATTY]?.toolName
|| getMcpToolName(capability)
|| capability.id.replace(/\./g, "_");
}
function getCattyRpcMethod(capability) {
return capability.surfaces?.builtin?.rpcMethod
|| capability.surfaces?.global?.rpcMethod
|| capability.surfaces?.public?.rpcMethod
|| null;
}
function getAgentToolName(capability, agentKind) {
if (agentKind === AGENT_KINDS.GLOBAL) {
return capability.surfaces?.[CAPABILITY_SURFACES.GLOBAL_AGENT]?.toolName
|| getMcpToolName(capability)
|| capability.id.replace(/\./g, "_");
}
return getCattyToolName(capability);
}
function getAgentRpcMethod(capability) {
return getCattyRpcMethod(capability);
}
function buildToolDescription(capability) {
const hint = MODEL_DESCRIPTION_HINTS[capability.id];
if (!hint) return capability.description;
return `${capability.description} ${hint}`;
}
function listToolSurfaces(options = {}) {
const {
surface = CAPABILITY_SURFACES.PUBLIC,
status = CAPABILITY_STATUS.IMPLEMENTED,
includeCatty = true,
} = options;
const tools = [];
for (const capability of ALL_CAPABILITIES) {
if (capability.status !== status) continue;
const binding = capability.surfaces?.[surface] || capability.surfaces?.public || capability.surfaces?.builtin;
if (!binding) continue;
const mcpTool = getMcpToolName(capability);
const cattyToolName = getCattyToolName(capability);
if (!includeCatty && !mcpTool) continue;
const builtinRpc = capability.surfaces?.builtin?.rpcMethod || binding.rpcMethod || null;
tools.push({
capabilityId: capability.id,
domain: capability.domain,
toolName: cattyToolName,
mcpTool,
rpcMethod: builtinRpc,
publicRpcMethod: capability.surfaces?.public?.rpcMethod || null,
description: buildToolDescription(capability),
policy: capability.policy,
inputShape: buildZodShape(TOOL_INPUT_FIELDS[capability.id]),
cattyEnabled: includeCatty && Boolean(TOOL_INPUT_FIELDS[capability.id] != null || mcpTool),
});
}
return tools;
}
function listMcpTools() {
return listToolSurfaces({ surface: CAPABILITY_SURFACES.PUBLIC, includeCatty: false })
.filter((tool) => tool.mcpTool);
}
/** Capabilities excluded from Catty even when implemented (CLI-only / meta). */
const CATTY_CAPABILITY_DENYLIST = new Set([
"meta.status",
"session.cancel",
"session.resume",
"session.get",
]);
function isCattyOnlyCapability(capability) {
return isAgentLocalOnlyCapability(capability, AGENT_KINDS.SIDEBAR);
}
function isAgentLocalOnlyCapability(capability, agentKind) {
if (agentKind === AGENT_KINDS.GLOBAL) {
return Boolean(capability.surfaces?.[CAPABILITY_SURFACES.GLOBAL_AGENT]?.toolName)
&& !getAgentRpcMethod(capability)
&& !getMcpToolName(capability);
}
return Boolean(capability.surfaces?.[CAPABILITY_SURFACES.CATTY]?.toolName)
&& !getAgentRpcMethod(capability)
&& !getMcpToolName(capability);
}
/**
* Resolve which agents may use a capability when agentKinds is not set explicitly.
* - surfaces.globalAgent only → global agent
* - surfaces.catty only (harness) → sidebar agent
* - RPC/MCP-backed tools → both agents (shared infrastructure)
*/
function resolveAgentKinds(capability) {
if (Array.isArray(capability.agentKinds) && capability.agentKinds.length > 0) {
return capability.agentKinds;
}
if (capability.surfaces?.[CAPABILITY_SURFACES.GLOBAL_AGENT]) {
return [AGENT_KINDS.GLOBAL];
}
if (isAgentLocalOnlyCapability(capability, AGENT_KINDS.SIDEBAR)) {
return [AGENT_KINDS.SIDEBAR];
}
if (isAgentEligibleForKind(capability, AGENT_KINDS.SIDEBAR, { skipAgentKindCheck: true })) {
return [AGENT_KINDS.SIDEBAR, AGENT_KINDS.GLOBAL];
}
return [];
}
function isAgentEligibleForKind(capability, agentKind, options = {}) {
if (capability.status !== CAPABILITY_STATUS.IMPLEMENTED) return false;
if (CATTY_CAPABILITY_DENYLIST.has(capability.id)) return false;
if (!options.skipAgentKindCheck && !resolveAgentKinds(capability).includes(agentKind)) {
return false;
}
const hasInputFields = Object.prototype.hasOwnProperty.call(TOOL_INPUT_FIELDS, capability.id);
if (!hasInputFields) return false;
if (isAgentLocalOnlyCapability(capability, agentKind)) return true;
const hasBuiltinRpc = Boolean(capability.surfaces?.builtin?.rpcMethod);
const hasGlobalRpc = Boolean(capability.surfaces?.global?.rpcMethod);
return hasBuiltinRpc || hasGlobalRpc || Boolean(getMcpToolName(capability));
}
function isCattyEligible(capability) {
return isAgentEligibleForKind(capability, AGENT_KINDS.SIDEBAR);
}
function listAgentToolSpecs(agentKind = AGENT_KINDS.SIDEBAR) {
return ALL_CAPABILITIES
.filter((capability) => isAgentEligibleForKind(capability, agentKind))
.map((capability) => {
const spec = {
capabilityId: capability.id,
toolName: getAgentToolName(capability, agentKind),
rpcMethod: getAgentRpcMethod(capability),
localExecution: isAgentLocalOnlyCapability(capability, agentKind),
description: buildToolDescription(capability),
inputShape: buildZodShape(TOOL_INPUT_FIELDS[capability.id]),
policy: capability.policy,
};
if (agentKind !== AGENT_KINDS.SIDEBAR) {
spec.agentKind = agentKind;
}
return spec;
});
}
function listCattyToolSpecs() {
return listAgentToolSpecs(AGENT_KINDS.SIDEBAR);
}
module.exports = {
AGENT_KINDS,
buildZodShape,
buildToolDescription,
CATTY_CAPABILITY_DENYLIST,
getAgentRpcMethod,
getAgentToolName,
getCattyToolName,
getCattyRpcMethod,
isAgentEligibleForKind,
isAgentLocalOnlyCapability,
isCattyEligible,
isCattyOnlyCapability,
listAgentToolSpecs,
listToolSurfaces,
listMcpTools,
listCattyToolSpecs,
resolveAgentKinds,
};