@build-astron-co/nimbus 0.2.0
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/LICENSE +21 -0
- package/README.md +628 -0
- package/bin/nimbus +38 -0
- package/package.json +80 -0
- package/src/__tests__/app.test.ts +76 -0
- package/src/__tests__/audit.test.ts +877 -0
- package/src/__tests__/circuit-breaker.test.ts +116 -0
- package/src/__tests__/cli-run.test.ts +115 -0
- package/src/__tests__/context-manager.test.ts +502 -0
- package/src/__tests__/context.test.ts +242 -0
- package/src/__tests__/enterprise.test.ts +401 -0
- package/src/__tests__/generator.test.ts +433 -0
- package/src/__tests__/hooks.test.ts +582 -0
- package/src/__tests__/init.test.ts +436 -0
- package/src/__tests__/intent-parser.test.ts +229 -0
- package/src/__tests__/llm-router.test.ts +209 -0
- package/src/__tests__/lsp.test.ts +293 -0
- package/src/__tests__/modes.test.ts +336 -0
- package/src/__tests__/permissions.test.ts +338 -0
- package/src/__tests__/serve.test.ts +275 -0
- package/src/__tests__/sessions.test.ts +227 -0
- package/src/__tests__/sharing.test.ts +288 -0
- package/src/__tests__/snapshots.test.ts +581 -0
- package/src/__tests__/state-db.test.ts +334 -0
- package/src/__tests__/stream-with-tools.test.ts +732 -0
- package/src/__tests__/subagents.test.ts +176 -0
- package/src/__tests__/system-prompt.test.ts +169 -0
- package/src/__tests__/tool-converter.test.ts +256 -0
- package/src/__tests__/tool-schemas.test.ts +397 -0
- package/src/__tests__/tools.test.ts +143 -0
- package/src/__tests__/version.test.ts +49 -0
- package/src/agent/compaction-agent.ts +227 -0
- package/src/agent/context-manager.ts +435 -0
- package/src/agent/context.ts +427 -0
- package/src/agent/deploy-preview.ts +426 -0
- package/src/agent/index.ts +68 -0
- package/src/agent/loop.ts +717 -0
- package/src/agent/modes.ts +429 -0
- package/src/agent/permissions.ts +466 -0
- package/src/agent/subagents/base.ts +116 -0
- package/src/agent/subagents/cost.ts +51 -0
- package/src/agent/subagents/explore.ts +42 -0
- package/src/agent/subagents/general.ts +54 -0
- package/src/agent/subagents/index.ts +102 -0
- package/src/agent/subagents/infra.ts +59 -0
- package/src/agent/subagents/security.ts +69 -0
- package/src/agent/system-prompt.ts +436 -0
- package/src/app.ts +122 -0
- package/src/audit/activity-log.ts +290 -0
- package/src/audit/compliance-checker.ts +540 -0
- package/src/audit/cost-tracker.ts +318 -0
- package/src/audit/index.ts +23 -0
- package/src/audit/security-scanner.ts +596 -0
- package/src/auth/guard.ts +75 -0
- package/src/auth/index.ts +56 -0
- package/src/auth/oauth.ts +455 -0
- package/src/auth/providers.ts +470 -0
- package/src/auth/sso.ts +113 -0
- package/src/auth/store.ts +505 -0
- package/src/auth/types.ts +187 -0
- package/src/build.ts +141 -0
- package/src/cli/index.ts +16 -0
- package/src/cli/init.ts +854 -0
- package/src/cli/openapi-spec.ts +356 -0
- package/src/cli/run.ts +237 -0
- package/src/cli/serve-auth.ts +80 -0
- package/src/cli/serve.ts +462 -0
- package/src/cli/web.ts +67 -0
- package/src/cli.ts +1417 -0
- package/src/clients/core-engine-client.ts +227 -0
- package/src/clients/enterprise-client.ts +334 -0
- package/src/clients/generator-client.ts +351 -0
- package/src/clients/git-client.ts +627 -0
- package/src/clients/github-client.ts +410 -0
- package/src/clients/helm-client.ts +504 -0
- package/src/clients/index.ts +80 -0
- package/src/clients/k8s-client.ts +497 -0
- package/src/clients/llm-client.ts +161 -0
- package/src/clients/rest-client.ts +130 -0
- package/src/clients/service-discovery.ts +33 -0
- package/src/clients/terraform-client.ts +482 -0
- package/src/clients/tools-client.ts +1843 -0
- package/src/clients/ws-client.ts +115 -0
- package/src/commands/analyze/index.ts +352 -0
- package/src/commands/apply/helm.ts +473 -0
- package/src/commands/apply/index.ts +213 -0
- package/src/commands/apply/k8s.ts +454 -0
- package/src/commands/apply/terraform.ts +582 -0
- package/src/commands/ask.ts +167 -0
- package/src/commands/audit/index.ts +238 -0
- package/src/commands/auth-cloud.ts +294 -0
- package/src/commands/auth-list.ts +134 -0
- package/src/commands/auth-profile.ts +121 -0
- package/src/commands/auth-status.ts +141 -0
- package/src/commands/aws/ec2.ts +501 -0
- package/src/commands/aws/iam.ts +397 -0
- package/src/commands/aws/index.ts +133 -0
- package/src/commands/aws/lambda.ts +396 -0
- package/src/commands/aws/rds.ts +439 -0
- package/src/commands/aws/s3.ts +439 -0
- package/src/commands/aws/vpc.ts +393 -0
- package/src/commands/aws-discover.ts +649 -0
- package/src/commands/aws-terraform.ts +805 -0
- package/src/commands/azure/aks.ts +376 -0
- package/src/commands/azure/functions.ts +253 -0
- package/src/commands/azure/index.ts +116 -0
- package/src/commands/azure/storage.ts +478 -0
- package/src/commands/azure/vm.ts +355 -0
- package/src/commands/billing/index.ts +256 -0
- package/src/commands/chat.ts +314 -0
- package/src/commands/config.ts +346 -0
- package/src/commands/cost/cloud-cost-estimator.ts +266 -0
- package/src/commands/cost/estimator.ts +79 -0
- package/src/commands/cost/index.ts +594 -0
- package/src/commands/cost/parsers/terraform.ts +273 -0
- package/src/commands/cost/parsers/types.ts +25 -0
- package/src/commands/cost/pricing/aws.ts +544 -0
- package/src/commands/cost/pricing/azure.ts +499 -0
- package/src/commands/cost/pricing/gcp.ts +396 -0
- package/src/commands/cost/pricing/index.ts +40 -0
- package/src/commands/demo.ts +250 -0
- package/src/commands/doctor.ts +794 -0
- package/src/commands/drift/index.ts +439 -0
- package/src/commands/explain.ts +277 -0
- package/src/commands/feedback.ts +389 -0
- package/src/commands/fix.ts +324 -0
- package/src/commands/fs/index.ts +402 -0
- package/src/commands/gcp/compute.ts +325 -0
- package/src/commands/gcp/functions.ts +271 -0
- package/src/commands/gcp/gke.ts +438 -0
- package/src/commands/gcp/iam.ts +344 -0
- package/src/commands/gcp/index.ts +129 -0
- package/src/commands/gcp/storage.ts +284 -0
- package/src/commands/generate-helm.ts +1249 -0
- package/src/commands/generate-k8s.ts +1560 -0
- package/src/commands/generate-terraform.ts +1460 -0
- package/src/commands/gh/index.ts +863 -0
- package/src/commands/git/index.ts +1343 -0
- package/src/commands/helm/index.ts +1126 -0
- package/src/commands/help.ts +539 -0
- package/src/commands/history.ts +142 -0
- package/src/commands/import.ts +868 -0
- package/src/commands/index.ts +367 -0
- package/src/commands/init.ts +1046 -0
- package/src/commands/k8s/index.ts +1137 -0
- package/src/commands/login.ts +631 -0
- package/src/commands/logout.ts +83 -0
- package/src/commands/onboarding.ts +228 -0
- package/src/commands/plan/display.ts +279 -0
- package/src/commands/plan/index.ts +599 -0
- package/src/commands/preview.ts +452 -0
- package/src/commands/questionnaire.ts +1270 -0
- package/src/commands/resume.ts +55 -0
- package/src/commands/team/index.ts +346 -0
- package/src/commands/template.ts +232 -0
- package/src/commands/tf/index.ts +1034 -0
- package/src/commands/upgrade.ts +550 -0
- package/src/commands/usage/index.ts +134 -0
- package/src/commands/version.ts +170 -0
- package/src/compat/index.ts +2 -0
- package/src/compat/runtime.ts +12 -0
- package/src/compat/sqlite.ts +107 -0
- package/src/config/index.ts +17 -0
- package/src/config/manager.ts +530 -0
- package/src/config/safety-policy.ts +358 -0
- package/src/config/schema.ts +125 -0
- package/src/config/types.ts +527 -0
- package/src/context/context-db.ts +199 -0
- package/src/demo/index.ts +349 -0
- package/src/demo/scenarios/full-journey.ts +229 -0
- package/src/demo/scenarios/getting-started.ts +127 -0
- package/src/demo/scenarios/helm-release.ts +341 -0
- package/src/demo/scenarios/k8s-deployment.ts +194 -0
- package/src/demo/scenarios/terraform-vpc.ts +170 -0
- package/src/demo/types.ts +92 -0
- package/src/engine/cost-estimator.ts +438 -0
- package/src/engine/diagram-generator.ts +256 -0
- package/src/engine/drift-detector.ts +902 -0
- package/src/engine/executor.ts +1035 -0
- package/src/engine/index.ts +76 -0
- package/src/engine/orchestrator.ts +636 -0
- package/src/engine/planner.ts +720 -0
- package/src/engine/safety.ts +743 -0
- package/src/engine/verifier.ts +770 -0
- package/src/enterprise/audit.ts +348 -0
- package/src/enterprise/auth.ts +270 -0
- package/src/enterprise/billing.ts +822 -0
- package/src/enterprise/index.ts +17 -0
- package/src/enterprise/teams.ts +443 -0
- package/src/generator/best-practices.ts +1608 -0
- package/src/generator/helm.ts +630 -0
- package/src/generator/index.ts +37 -0
- package/src/generator/intent-parser.ts +514 -0
- package/src/generator/kubernetes.ts +976 -0
- package/src/generator/terraform.ts +1867 -0
- package/src/history/index.ts +8 -0
- package/src/history/manager.ts +322 -0
- package/src/history/types.ts +34 -0
- package/src/hooks/config.ts +432 -0
- package/src/hooks/engine.ts +391 -0
- package/src/hooks/index.ts +4 -0
- package/src/llm/auth-bridge.ts +198 -0
- package/src/llm/circuit-breaker.ts +140 -0
- package/src/llm/config-loader.ts +201 -0
- package/src/llm/cost-calculator.ts +171 -0
- package/src/llm/index.ts +8 -0
- package/src/llm/model-aliases.ts +115 -0
- package/src/llm/provider-registry.ts +63 -0
- package/src/llm/providers/anthropic.ts +433 -0
- package/src/llm/providers/bedrock.ts +477 -0
- package/src/llm/providers/google.ts +405 -0
- package/src/llm/providers/ollama.ts +767 -0
- package/src/llm/providers/openai-compatible.ts +340 -0
- package/src/llm/providers/openai.ts +328 -0
- package/src/llm/providers/openrouter.ts +338 -0
- package/src/llm/router.ts +1035 -0
- package/src/llm/types.ts +232 -0
- package/src/lsp/client.ts +298 -0
- package/src/lsp/languages.ts +116 -0
- package/src/lsp/manager.ts +278 -0
- package/src/mcp/client.ts +402 -0
- package/src/mcp/index.ts +5 -0
- package/src/mcp/manager.ts +133 -0
- package/src/nimbus.ts +214 -0
- package/src/plugins/index.ts +27 -0
- package/src/plugins/loader.ts +334 -0
- package/src/plugins/manager.ts +376 -0
- package/src/plugins/types.ts +284 -0
- package/src/scanners/cicd-scanner.ts +258 -0
- package/src/scanners/cloud-scanner.ts +466 -0
- package/src/scanners/framework-scanner.ts +469 -0
- package/src/scanners/iac-scanner.ts +388 -0
- package/src/scanners/index.ts +539 -0
- package/src/scanners/language-scanner.ts +276 -0
- package/src/scanners/package-manager-scanner.ts +277 -0
- package/src/scanners/types.ts +172 -0
- package/src/sessions/manager.ts +365 -0
- package/src/sessions/types.ts +44 -0
- package/src/sharing/sync.ts +296 -0
- package/src/sharing/viewer.ts +97 -0
- package/src/snapshots/index.ts +2 -0
- package/src/snapshots/manager.ts +530 -0
- package/src/state/artifacts.ts +147 -0
- package/src/state/audit.ts +137 -0
- package/src/state/billing.ts +240 -0
- package/src/state/checkpoints.ts +117 -0
- package/src/state/config.ts +67 -0
- package/src/state/conversations.ts +14 -0
- package/src/state/credentials.ts +154 -0
- package/src/state/db.ts +58 -0
- package/src/state/index.ts +26 -0
- package/src/state/messages.ts +115 -0
- package/src/state/projects.ts +123 -0
- package/src/state/schema.ts +236 -0
- package/src/state/sessions.ts +147 -0
- package/src/state/teams.ts +200 -0
- package/src/telemetry.ts +108 -0
- package/src/tools/aws-ops.ts +952 -0
- package/src/tools/azure-ops.ts +579 -0
- package/src/tools/file-ops.ts +593 -0
- package/src/tools/gcp-ops.ts +625 -0
- package/src/tools/git-ops.ts +773 -0
- package/src/tools/github-ops.ts +799 -0
- package/src/tools/helm-ops.ts +943 -0
- package/src/tools/index.ts +17 -0
- package/src/tools/k8s-ops.ts +819 -0
- package/src/tools/schemas/converter.ts +184 -0
- package/src/tools/schemas/devops.ts +612 -0
- package/src/tools/schemas/index.ts +73 -0
- package/src/tools/schemas/standard.ts +1144 -0
- package/src/tools/schemas/types.ts +705 -0
- package/src/tools/terraform-ops.ts +862 -0
- package/src/types/ambient.d.ts +193 -0
- package/src/types/config.ts +83 -0
- package/src/types/drift.ts +116 -0
- package/src/types/enterprise.ts +335 -0
- package/src/types/index.ts +20 -0
- package/src/types/plan.ts +44 -0
- package/src/types/request.ts +65 -0
- package/src/types/response.ts +54 -0
- package/src/types/service.ts +51 -0
- package/src/ui/App.tsx +997 -0
- package/src/ui/DeployPreview.tsx +169 -0
- package/src/ui/Header.tsx +68 -0
- package/src/ui/InputBox.tsx +350 -0
- package/src/ui/MessageList.tsx +585 -0
- package/src/ui/PermissionPrompt.tsx +151 -0
- package/src/ui/StatusBar.tsx +158 -0
- package/src/ui/ToolCallDisplay.tsx +409 -0
- package/src/ui/chat-ui.ts +853 -0
- package/src/ui/index.ts +33 -0
- package/src/ui/ink/index.ts +711 -0
- package/src/ui/streaming.ts +176 -0
- package/src/ui/types.ts +57 -0
- package/src/utils/analytics.ts +72 -0
- package/src/utils/cost-warning.ts +27 -0
- package/src/utils/env.ts +46 -0
- package/src/utils/errors.ts +69 -0
- package/src/utils/event-bus.ts +38 -0
- package/src/utils/index.ts +24 -0
- package/src/utils/logger.ts +171 -0
- package/src/utils/rate-limiter.ts +121 -0
- package/src/utils/service-auth.ts +49 -0
- package/src/utils/validation.ts +53 -0
- package/src/version.ts +4 -0
- package/src/watcher/index.ts +163 -0
- package/src/wizard/approval.ts +383 -0
- package/src/wizard/index.ts +25 -0
- package/src/wizard/prompts.ts +338 -0
- package/src/wizard/types.ts +171 -0
- package/src/wizard/ui.ts +556 -0
- package/src/wizard/wizard.ts +304 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,705 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nimbus Agentic Tool-Use Type System
|
|
3
|
+
*
|
|
4
|
+
* Core type definitions for the agentic tool-use system. Every tool that
|
|
5
|
+
* Nimbus can invoke -- whether a built-in operation, a DevOps command, or
|
|
6
|
+
* an MCP server tool -- is described by a {@link ToolDefinition} and
|
|
7
|
+
* registered in the {@link ToolRegistry}.
|
|
8
|
+
*
|
|
9
|
+
* The permission model follows a four-tier escalation ladder
|
|
10
|
+
* ({@link PermissionTier}) that controls whether a tool invocation requires
|
|
11
|
+
* user confirmation, and the three-category taxonomy ({@link ToolCategory})
|
|
12
|
+
* allows consumers to filter tools by surface area.
|
|
13
|
+
*
|
|
14
|
+
* Provider-specific serialization helpers ({@link AnthropicTool},
|
|
15
|
+
* {@link OpenAITool}, {@link GoogleTool}) let the engine convert a single
|
|
16
|
+
* {@link ToolDefinition} into whatever shape each LLM API expects.
|
|
17
|
+
*
|
|
18
|
+
* @module tools/schemas/types
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import type { z } from 'zod';
|
|
22
|
+
import type { JSONSchema } from '../../llm/types';
|
|
23
|
+
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// Permission Tiers
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Four-tier permission model that governs how tool invocations are
|
|
30
|
+
* authorized at runtime.
|
|
31
|
+
*
|
|
32
|
+
* | Tier | Prompt behavior | Example tools |
|
|
33
|
+
* | -------------- | -------------------------------------------- | --------------------------------- |
|
|
34
|
+
* | `auto_allow` | Execute immediately, no user prompt | `read_file`, `terraform validate` |
|
|
35
|
+
* | `ask_once` | Ask user once per session, then auto-allow | `write_file`, non-destructive bash |
|
|
36
|
+
* | `always_ask` | Always prompt the user before execution | `terraform apply`, `kubectl delete` |
|
|
37
|
+
* | `blocked` | Never allow, even if the user tries to force | `rm -rf /`, `DROP DATABASE` |
|
|
38
|
+
*/
|
|
39
|
+
export type PermissionTier = 'auto_allow' | 'ask_once' | 'always_ask' | 'blocked';
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Ordered list of all permission tiers from least restrictive to most
|
|
43
|
+
* restrictive. Useful for comparison and escalation logic.
|
|
44
|
+
*/
|
|
45
|
+
export const PERMISSION_TIER_ORDER: readonly PermissionTier[] = [
|
|
46
|
+
'auto_allow',
|
|
47
|
+
'ask_once',
|
|
48
|
+
'always_ask',
|
|
49
|
+
'blocked',
|
|
50
|
+
] as const;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Return the numeric severity index of a {@link PermissionTier}.
|
|
54
|
+
* Lower values are less restrictive.
|
|
55
|
+
*
|
|
56
|
+
* @param tier - The permission tier to evaluate.
|
|
57
|
+
* @returns An integer from 0 (`auto_allow`) to 3 (`blocked`).
|
|
58
|
+
*/
|
|
59
|
+
export function permissionTierIndex(tier: PermissionTier): number {
|
|
60
|
+
return PERMISSION_TIER_ORDER.indexOf(tier);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
// Backward-compatible alias
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Alias kept for backward compatibility with code that references the
|
|
69
|
+
* previous type name. Prefer {@link PermissionTier} in new code.
|
|
70
|
+
*
|
|
71
|
+
* @deprecated Use {@link PermissionTier} instead.
|
|
72
|
+
*/
|
|
73
|
+
export type PermissionLevel = PermissionTier;
|
|
74
|
+
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// Tool Categories
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* High-level taxonomy that groups tools by their operational surface area.
|
|
81
|
+
*
|
|
82
|
+
* - `standard` -- built-in operations such as file I/O, search, and git.
|
|
83
|
+
* - `devops` -- infrastructure tools: Terraform, Kubernetes, Helm, cloud CLIs.
|
|
84
|
+
* - `mcp` -- tools sourced from external MCP (Model Context Protocol) servers.
|
|
85
|
+
*/
|
|
86
|
+
export type ToolCategory = 'standard' | 'devops' | 'mcp';
|
|
87
|
+
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
// Tool Result
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* The value returned by every tool execution. Consumers should check
|
|
94
|
+
* {@link isError} before reading {@link output}.
|
|
95
|
+
*/
|
|
96
|
+
export interface ToolResult {
|
|
97
|
+
/** The textual output produced by the tool. */
|
|
98
|
+
output: string;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Human-readable error message. Present only when {@link isError} is
|
|
102
|
+
* `true`.
|
|
103
|
+
*/
|
|
104
|
+
error?: string;
|
|
105
|
+
|
|
106
|
+
/** Whether the execution failed. */
|
|
107
|
+
isError: boolean;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
// Tool Definition
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Complete description of an executable tool.
|
|
116
|
+
*
|
|
117
|
+
* Each tool carries its own Zod input schema so that the engine can
|
|
118
|
+
* validate arguments before execution, and its own permission tier so
|
|
119
|
+
* that the permission engine can decide whether to prompt the user.
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```ts
|
|
123
|
+
* const readFileTool: ToolDefinition = {
|
|
124
|
+
* name: 'read_file',
|
|
125
|
+
* description: 'Read the contents of a file at the given path.',
|
|
126
|
+
* inputSchema: z.object({
|
|
127
|
+
* path: z.string().describe('Absolute or workspace-relative file path'),
|
|
128
|
+
* encoding: z.enum(['utf-8', 'base64']).default('utf-8'),
|
|
129
|
+
* }),
|
|
130
|
+
* execute: async (input) => {
|
|
131
|
+
* const content = await fs.readFile(input.path, input.encoding);
|
|
132
|
+
* return { output: content, isError: false };
|
|
133
|
+
* },
|
|
134
|
+
* permissionTier: 'auto_allow',
|
|
135
|
+
* category: 'standard',
|
|
136
|
+
* isDestructive: false,
|
|
137
|
+
* };
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
export interface ToolDefinition {
|
|
141
|
+
/**
|
|
142
|
+
* Unique snake_case identifier for this tool (e.g. `'read_file'`,
|
|
143
|
+
* `'terraform_apply'`).
|
|
144
|
+
*/
|
|
145
|
+
name: string;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Natural-language description surfaced to the LLM so it understands
|
|
149
|
+
* when and how to invoke this tool.
|
|
150
|
+
*/
|
|
151
|
+
description: string;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Zod schema that validates and parses the raw input object before it
|
|
155
|
+
* reaches {@link execute}. The schema is also converted to JSON Schema
|
|
156
|
+
* for provider APIs via {@link zodToJsonSchema}.
|
|
157
|
+
*/
|
|
158
|
+
inputSchema: z.ZodType<unknown>;
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Execute the tool with validated input and return a {@link ToolResult}.
|
|
162
|
+
*
|
|
163
|
+
* Implementations should catch their own errors and return them inside
|
|
164
|
+
* the result rather than throwing, so that the agentic loop can report
|
|
165
|
+
* the failure back to the LLM gracefully.
|
|
166
|
+
*
|
|
167
|
+
* @param input - The validated (parsed) input object.
|
|
168
|
+
* @returns A promise resolving to the tool's output.
|
|
169
|
+
*/
|
|
170
|
+
execute: (input: unknown) => Promise<ToolResult>;
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Which permission tier this tool belongs to. Determines whether the
|
|
174
|
+
* user is prompted before execution.
|
|
175
|
+
*/
|
|
176
|
+
permissionTier: PermissionTier;
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* High-level category for filtering and display purposes.
|
|
180
|
+
*/
|
|
181
|
+
category: ToolCategory;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Whether this tool modifies external state (files, infrastructure,
|
|
185
|
+
* databases, etc.). Defaults to `false` when omitted.
|
|
186
|
+
*
|
|
187
|
+
* Tools marked destructive are surfaced with extra warnings in the CLI
|
|
188
|
+
* and are never auto-approved in CI mode.
|
|
189
|
+
*/
|
|
190
|
+
isDestructive?: boolean;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// ---------------------------------------------------------------------------
|
|
194
|
+
// Helper / Utility Types
|
|
195
|
+
// ---------------------------------------------------------------------------
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Infer the validated input type from a {@link ToolDefinition}'s
|
|
199
|
+
* `inputSchema`.
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* ```ts
|
|
203
|
+
* type ReadFileInput = ToolInput<typeof readFileTool>;
|
|
204
|
+
* // { path: string; encoding?: 'utf-8' | 'base64' }
|
|
205
|
+
* ```
|
|
206
|
+
*/
|
|
207
|
+
export type ToolInput<T extends ToolDefinition> =
|
|
208
|
+
T['inputSchema'] extends z.ZodType<infer U> ? U : never;
|
|
209
|
+
|
|
210
|
+
// ---------------------------------------------------------------------------
|
|
211
|
+
// Provider-Specific Tool Formats
|
|
212
|
+
// ---------------------------------------------------------------------------
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Tool definition formatted for the Anthropic Messages API.
|
|
216
|
+
*
|
|
217
|
+
* Anthropic expects each tool to be an object with `name`, `description`,
|
|
218
|
+
* and an `input_schema` that must have `type: 'object'` at the top level.
|
|
219
|
+
*
|
|
220
|
+
* @see https://docs.anthropic.com/en/docs/build-with-claude/tool-use
|
|
221
|
+
*/
|
|
222
|
+
export interface AnthropicTool {
|
|
223
|
+
/** Tool name -- must match `[a-zA-Z0-9_-]+` and be <= 64 chars. */
|
|
224
|
+
name: string;
|
|
225
|
+
|
|
226
|
+
/** Description surfaced to the model. */
|
|
227
|
+
description: string;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* JSON Schema describing the expected input. Anthropic requires this
|
|
231
|
+
* to have `type: 'object'` at the top level.
|
|
232
|
+
*/
|
|
233
|
+
input_schema: JSONSchema & { type: 'object' };
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Tool definition formatted for the OpenAI Chat Completions API
|
|
238
|
+
* (function calling).
|
|
239
|
+
*
|
|
240
|
+
* OpenAI wraps each function in a `{ type: 'function', function: { ... } }`
|
|
241
|
+
* envelope.
|
|
242
|
+
*
|
|
243
|
+
* @see https://platform.openai.com/docs/guides/function-calling
|
|
244
|
+
*/
|
|
245
|
+
export interface OpenAITool {
|
|
246
|
+
/** Always `'function'` for the function-calling interface. */
|
|
247
|
+
type: 'function';
|
|
248
|
+
|
|
249
|
+
/** The function metadata. */
|
|
250
|
+
function: {
|
|
251
|
+
/** Function name. */
|
|
252
|
+
name: string;
|
|
253
|
+
|
|
254
|
+
/** Description surfaced to the model. */
|
|
255
|
+
description: string;
|
|
256
|
+
|
|
257
|
+
/** JSON Schema for the function parameters. */
|
|
258
|
+
parameters: JSONSchema;
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Tool definition formatted for the Google Generative AI
|
|
264
|
+
* (`@google/generative-ai`) function declarations.
|
|
265
|
+
*
|
|
266
|
+
* Google wraps all function declarations inside a single tool object with
|
|
267
|
+
* a `functionDeclarations` array.
|
|
268
|
+
*
|
|
269
|
+
* @see https://ai.google.dev/gemini-api/docs/function-calling
|
|
270
|
+
*/
|
|
271
|
+
export interface GoogleTool {
|
|
272
|
+
/** Array of function declarations passed inside a single tool object. */
|
|
273
|
+
functionDeclarations: Array<{
|
|
274
|
+
/** Function name. */
|
|
275
|
+
name: string;
|
|
276
|
+
|
|
277
|
+
/** Description surfaced to the model. */
|
|
278
|
+
description: string;
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Parameters described as a JSON Schema object. Google expects the
|
|
282
|
+
* top-level `type` to be the string `'OBJECT'`.
|
|
283
|
+
*/
|
|
284
|
+
parameters: JSONSchema & { type: 'OBJECT' };
|
|
285
|
+
}>;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// ---------------------------------------------------------------------------
|
|
289
|
+
// JSON Schema Conversion Utility
|
|
290
|
+
// ---------------------------------------------------------------------------
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Convert a Zod schema into a plain JSON Schema object suitable for
|
|
294
|
+
* provider APIs.
|
|
295
|
+
*
|
|
296
|
+
* This is a lightweight converter that handles the most common Zod types
|
|
297
|
+
* used in tool definitions (objects, strings, numbers, booleans, arrays,
|
|
298
|
+
* enums, optionals, and defaults). For deeply nested or exotic schemas
|
|
299
|
+
* consider using a full-featured library like `zod-to-json-schema`.
|
|
300
|
+
*
|
|
301
|
+
* @param schema - Any Zod schema.
|
|
302
|
+
* @returns A JSON Schema object.
|
|
303
|
+
*/
|
|
304
|
+
export function zodToJsonSchema(schema: z.ZodType<unknown>): JSONSchema {
|
|
305
|
+
return convertZodNode(schema);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Internal recursive walker that translates individual Zod nodes into
|
|
310
|
+
* their JSON Schema equivalents.
|
|
311
|
+
*
|
|
312
|
+
* Because this function must work with Zod v3 _and_ v4 (whose generic
|
|
313
|
+
* constraints differ significantly), the runtime casts use `any` to
|
|
314
|
+
* bypass version-specific type parameter requirements. This is safe
|
|
315
|
+
* because every branch is guarded by a runtime type-tag check first.
|
|
316
|
+
*/
|
|
317
|
+
function convertZodNode(schema: z.ZodType<unknown>): JSONSchema {
|
|
318
|
+
// Cast once to `any` for internal introspection. Every access below is
|
|
319
|
+
// guarded by a runtime type-tag check, so this is safe.
|
|
320
|
+
const s: any = schema;
|
|
321
|
+
|
|
322
|
+
// Unwrap ZodOptional / ZodNullable / ZodDefault to reach the inner type.
|
|
323
|
+
if (isZodOptional(schema)) {
|
|
324
|
+
return convertZodNode(s.unwrap());
|
|
325
|
+
}
|
|
326
|
+
if (isZodDefault(schema)) {
|
|
327
|
+
const inner = convertZodNode(s.removeDefault());
|
|
328
|
+
// Zod v3: _def.defaultValue is a function. Zod v4: it is a plain value.
|
|
329
|
+
const raw = s._def?.defaultValue ?? s._zod?.def?.defaultValue;
|
|
330
|
+
const defaultValue = typeof raw === 'function' ? raw() : raw;
|
|
331
|
+
return { ...inner, default: defaultValue };
|
|
332
|
+
}
|
|
333
|
+
if (isZodNullable(schema)) {
|
|
334
|
+
const inner = convertZodNode(s.unwrap());
|
|
335
|
+
return { ...inner, nullable: true };
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// ZodObject
|
|
339
|
+
if (isZodObject(schema)) {
|
|
340
|
+
const shape: Record<string, z.ZodType<unknown>> = s.shape;
|
|
341
|
+
const properties: Record<string, JSONSchema> = {};
|
|
342
|
+
const required: string[] = [];
|
|
343
|
+
|
|
344
|
+
for (const [key, value] of Object.entries(shape)) {
|
|
345
|
+
const fieldSchema = value as z.ZodType<unknown>;
|
|
346
|
+
properties[key] = convertZodNode(fieldSchema);
|
|
347
|
+
|
|
348
|
+
// Attach description from .describe() if present.
|
|
349
|
+
// Zod v3: _def.description. Zod v4: _zod.def.description.
|
|
350
|
+
const fieldAny = fieldSchema as any;
|
|
351
|
+
const desc: string | undefined =
|
|
352
|
+
fieldAny._def?.description ?? fieldAny._zod?.def?.description;
|
|
353
|
+
if (desc) {
|
|
354
|
+
properties[key].description = desc;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// A field is required unless it is optional/default-wrapped.
|
|
358
|
+
if (!isZodOptional(fieldSchema) && !isZodDefault(fieldSchema)) {
|
|
359
|
+
required.push(key);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
const result: JSONSchema = { type: 'object', properties };
|
|
364
|
+
if (required.length > 0) {
|
|
365
|
+
result.required = required;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
const objDesc: string | undefined = s._def?.description ?? s._zod?.def?.description;
|
|
369
|
+
if (objDesc) {
|
|
370
|
+
result.description = objDesc;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
return result;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// ZodString
|
|
377
|
+
if (isZodString(schema)) {
|
|
378
|
+
return { type: 'string' };
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// ZodNumber
|
|
382
|
+
if (isZodNumber(schema)) {
|
|
383
|
+
return { type: 'number' };
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// ZodBoolean
|
|
387
|
+
if (isZodBoolean(schema)) {
|
|
388
|
+
return { type: 'boolean' };
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// ZodEnum
|
|
392
|
+
if (isZodEnum(schema)) {
|
|
393
|
+
// `.options` is available in both Zod v3 and v4.
|
|
394
|
+
const values: unknown[] = s.options;
|
|
395
|
+
return { type: 'string', enum: values };
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// ZodArray
|
|
399
|
+
if (isZodArray(schema)) {
|
|
400
|
+
const itemSchema: z.ZodType<unknown> = s.element;
|
|
401
|
+
return { type: 'array', items: convertZodNode(itemSchema) };
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// ZodLiteral
|
|
405
|
+
if (isZodLiteral(schema)) {
|
|
406
|
+
const value: unknown = s.value;
|
|
407
|
+
return { type: typeof value as string, const: value };
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// ZodUnion (simple enum-like unions of literals)
|
|
411
|
+
if (isZodUnion(schema)) {
|
|
412
|
+
const options: z.ZodType<unknown>[] = s.options;
|
|
413
|
+
return { type: 'object', anyOf: options.map(o => convertZodNode(o)) };
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// ZodRecord
|
|
417
|
+
if (isZodRecord(schema)) {
|
|
418
|
+
// Zod v3: `.valueSchema`. Zod v4: `._zod.def.valueType`.
|
|
419
|
+
const valueSchema: z.ZodType<unknown> = s.valueSchema ?? s._zod?.def?.valueType;
|
|
420
|
+
if (valueSchema) {
|
|
421
|
+
return { type: 'object', additionalProperties: convertZodNode(valueSchema) };
|
|
422
|
+
}
|
|
423
|
+
return { type: 'object' };
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// Fallback -- treat as opaque object
|
|
427
|
+
return { type: 'object' };
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// ---------------------------------------------------------------------------
|
|
431
|
+
// Zod type-tag guards (work across Zod v3 and v4)
|
|
432
|
+
// ---------------------------------------------------------------------------
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Extract the internal type discriminator from a Zod schema.
|
|
436
|
+
*
|
|
437
|
+
* - Zod v3 stores it at `_def.typeName` (e.g. `'ZodString'`).
|
|
438
|
+
* - Zod v4 stores it at `_zod.def.type` (e.g. `'string'`).
|
|
439
|
+
*
|
|
440
|
+
* We normalize both to the v3-style `'ZodXxx'` name so the guards below
|
|
441
|
+
* can use a single comparison.
|
|
442
|
+
*/
|
|
443
|
+
function zodTypeName(schema: z.ZodType<unknown>): string {
|
|
444
|
+
const s = schema as any;
|
|
445
|
+
|
|
446
|
+
// Zod v3 path
|
|
447
|
+
const v3Name: string | undefined = s._def?.typeName;
|
|
448
|
+
if (v3Name) {
|
|
449
|
+
return v3Name;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// Zod v4 path: `_zod.def.type` is a lowercase short name like 'string'.
|
|
453
|
+
const v4Type: string | undefined = s._zod?.def?.type;
|
|
454
|
+
if (v4Type) {
|
|
455
|
+
// Capitalize to match Zod v3 convention: 'string' -> 'ZodString'.
|
|
456
|
+
return `Zod${v4Type.charAt(0).toUpperCase()}${v4Type.slice(1)}`;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
return '';
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
function isZodObject(s: z.ZodType<unknown>): boolean {
|
|
463
|
+
return zodTypeName(s) === 'ZodObject';
|
|
464
|
+
}
|
|
465
|
+
function isZodString(s: z.ZodType<unknown>): boolean {
|
|
466
|
+
return zodTypeName(s) === 'ZodString';
|
|
467
|
+
}
|
|
468
|
+
function isZodNumber(s: z.ZodType<unknown>): boolean {
|
|
469
|
+
return zodTypeName(s) === 'ZodNumber';
|
|
470
|
+
}
|
|
471
|
+
function isZodBoolean(s: z.ZodType<unknown>): boolean {
|
|
472
|
+
return zodTypeName(s) === 'ZodBoolean';
|
|
473
|
+
}
|
|
474
|
+
function isZodEnum(s: z.ZodType<unknown>): boolean {
|
|
475
|
+
return zodTypeName(s) === 'ZodEnum';
|
|
476
|
+
}
|
|
477
|
+
function isZodArray(s: z.ZodType<unknown>): boolean {
|
|
478
|
+
return zodTypeName(s) === 'ZodArray';
|
|
479
|
+
}
|
|
480
|
+
function isZodOptional(s: z.ZodType<unknown>): boolean {
|
|
481
|
+
return zodTypeName(s) === 'ZodOptional';
|
|
482
|
+
}
|
|
483
|
+
function isZodDefault(s: z.ZodType<unknown>): boolean {
|
|
484
|
+
return zodTypeName(s) === 'ZodDefault';
|
|
485
|
+
}
|
|
486
|
+
function isZodNullable(s: z.ZodType<unknown>): boolean {
|
|
487
|
+
return zodTypeName(s) === 'ZodNullable';
|
|
488
|
+
}
|
|
489
|
+
function isZodLiteral(s: z.ZodType<unknown>): boolean {
|
|
490
|
+
return zodTypeName(s) === 'ZodLiteral';
|
|
491
|
+
}
|
|
492
|
+
function isZodUnion(s: z.ZodType<unknown>): boolean {
|
|
493
|
+
return zodTypeName(s) === 'ZodUnion';
|
|
494
|
+
}
|
|
495
|
+
function isZodRecord(s: z.ZodType<unknown>): boolean {
|
|
496
|
+
return zodTypeName(s) === 'ZodRecord';
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// ---------------------------------------------------------------------------
|
|
500
|
+
// Provider Format Converters
|
|
501
|
+
// ---------------------------------------------------------------------------
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Convert a {@link ToolDefinition} into an {@link AnthropicTool}.
|
|
505
|
+
*
|
|
506
|
+
* @param tool - The tool definition to convert.
|
|
507
|
+
* @returns The tool in Anthropic Messages API format.
|
|
508
|
+
*/
|
|
509
|
+
export function toAnthropicTool(tool: ToolDefinition): AnthropicTool {
|
|
510
|
+
const jsonSchema = zodToJsonSchema(tool.inputSchema);
|
|
511
|
+
return {
|
|
512
|
+
name: tool.name,
|
|
513
|
+
description: tool.description,
|
|
514
|
+
input_schema: {
|
|
515
|
+
...jsonSchema,
|
|
516
|
+
type: 'object',
|
|
517
|
+
},
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Convert a {@link ToolDefinition} into an {@link OpenAITool}.
|
|
523
|
+
*
|
|
524
|
+
* @param tool - The tool definition to convert.
|
|
525
|
+
* @returns The tool in OpenAI function-calling format.
|
|
526
|
+
*/
|
|
527
|
+
export function toOpenAITool(tool: ToolDefinition): OpenAITool {
|
|
528
|
+
return {
|
|
529
|
+
type: 'function',
|
|
530
|
+
function: {
|
|
531
|
+
name: tool.name,
|
|
532
|
+
description: tool.description,
|
|
533
|
+
parameters: zodToJsonSchema(tool.inputSchema),
|
|
534
|
+
},
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Convert one or more {@link ToolDefinition}s into a single
|
|
540
|
+
* {@link GoogleTool} object (Google expects all declarations inside a
|
|
541
|
+
* single array).
|
|
542
|
+
*
|
|
543
|
+
* @param tools - The tool definitions to convert.
|
|
544
|
+
* @returns The tool in Google Generative AI format.
|
|
545
|
+
*/
|
|
546
|
+
export function toGoogleTool(tools: readonly ToolDefinition[]): GoogleTool {
|
|
547
|
+
return {
|
|
548
|
+
functionDeclarations: tools.map(tool => {
|
|
549
|
+
const jsonSchema = zodToJsonSchema(tool.inputSchema);
|
|
550
|
+
return {
|
|
551
|
+
name: tool.name,
|
|
552
|
+
description: tool.description,
|
|
553
|
+
parameters: {
|
|
554
|
+
...jsonSchema,
|
|
555
|
+
type: 'OBJECT' as const,
|
|
556
|
+
},
|
|
557
|
+
};
|
|
558
|
+
}),
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// ---------------------------------------------------------------------------
|
|
563
|
+
// Tool Registry
|
|
564
|
+
// ---------------------------------------------------------------------------
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* Central, mutable registry that stores all available tool definitions.
|
|
568
|
+
*
|
|
569
|
+
* The registry is intentionally a plain class (not a singleton) so that
|
|
570
|
+
* tests can instantiate isolated instances. Production code should use
|
|
571
|
+
* the shared {@link defaultToolRegistry} export.
|
|
572
|
+
*
|
|
573
|
+
* @example
|
|
574
|
+
* ```ts
|
|
575
|
+
* const registry = new ToolRegistry();
|
|
576
|
+
* registry.register(readFileTool);
|
|
577
|
+
* registry.register(terraformApplyTool);
|
|
578
|
+
*
|
|
579
|
+
* const devopsTools = registry.getByCategory('devops');
|
|
580
|
+
* const anthropicPayload = registry.getAll().map(toAnthropicTool);
|
|
581
|
+
* ```
|
|
582
|
+
*/
|
|
583
|
+
export class ToolRegistry {
|
|
584
|
+
/** Internal map keyed by tool name. */
|
|
585
|
+
private readonly tools: Map<string, ToolDefinition> = new Map();
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* Register a tool definition. Throws if a tool with the same name is
|
|
589
|
+
* already registered -- call {@link get} first if you need upsert
|
|
590
|
+
* semantics.
|
|
591
|
+
*
|
|
592
|
+
* @param tool - The tool definition to register.
|
|
593
|
+
* @throws {Error} If a tool with the same {@link ToolDefinition.name}
|
|
594
|
+
* already exists.
|
|
595
|
+
*/
|
|
596
|
+
register(tool: ToolDefinition): void {
|
|
597
|
+
if (this.tools.has(tool.name)) {
|
|
598
|
+
throw new Error(
|
|
599
|
+
`ToolRegistry: tool '${tool.name}' is already registered. ` +
|
|
600
|
+
`Unregister it first or use a different name.`
|
|
601
|
+
);
|
|
602
|
+
}
|
|
603
|
+
this.tools.set(tool.name, tool);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Retrieve a tool definition by name.
|
|
608
|
+
*
|
|
609
|
+
* @param name - The unique tool name.
|
|
610
|
+
* @returns The tool definition, or `undefined` if not found.
|
|
611
|
+
*/
|
|
612
|
+
get(name: string): ToolDefinition | undefined {
|
|
613
|
+
return this.tools.get(name);
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Return every registered tool definition, in insertion order.
|
|
618
|
+
*/
|
|
619
|
+
getAll(): ToolDefinition[] {
|
|
620
|
+
return Array.from(this.tools.values());
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
/**
|
|
624
|
+
* Return all tools that belong to the given {@link ToolCategory}.
|
|
625
|
+
*
|
|
626
|
+
* @param category - The category to filter by.
|
|
627
|
+
* @returns An array of matching tool definitions (may be empty).
|
|
628
|
+
*/
|
|
629
|
+
getByCategory(category: ToolCategory): ToolDefinition[] {
|
|
630
|
+
return this.getAll().filter(t => t.category === category);
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* Return all tools that belong to the given {@link PermissionTier}.
|
|
635
|
+
*
|
|
636
|
+
* @param tier - The permission tier to filter by.
|
|
637
|
+
* @returns An array of matching tool definitions (may be empty).
|
|
638
|
+
*/
|
|
639
|
+
getByPermissionTier(tier: PermissionTier): ToolDefinition[] {
|
|
640
|
+
return this.getAll().filter(t => t.permissionTier === tier);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Return the names of all registered tools, in insertion order.
|
|
645
|
+
*/
|
|
646
|
+
getNames(): string[] {
|
|
647
|
+
return Array.from(this.tools.keys());
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Remove a previously registered tool by name.
|
|
652
|
+
*
|
|
653
|
+
* @param name - The tool name to unregister.
|
|
654
|
+
* @returns `true` if the tool was found and removed, `false` otherwise.
|
|
655
|
+
*/
|
|
656
|
+
unregister(name: string): boolean {
|
|
657
|
+
return this.tools.delete(name);
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
/**
|
|
661
|
+
* Remove all registered tools. Primarily useful in tests.
|
|
662
|
+
*/
|
|
663
|
+
clear(): void {
|
|
664
|
+
this.tools.clear();
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* The number of currently registered tools.
|
|
669
|
+
*/
|
|
670
|
+
get size(): number {
|
|
671
|
+
return this.tools.size;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
/**
|
|
675
|
+
* Convert all registered tools to the Anthropic Messages API format.
|
|
676
|
+
*/
|
|
677
|
+
toAnthropicTools(): AnthropicTool[] {
|
|
678
|
+
return this.getAll().map(toAnthropicTool);
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* Convert all registered tools to the OpenAI function-calling format.
|
|
683
|
+
*/
|
|
684
|
+
toOpenAITools(): OpenAITool[] {
|
|
685
|
+
return this.getAll().map(toOpenAITool);
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* Convert all registered tools to a single Google Generative AI tool
|
|
690
|
+
* object.
|
|
691
|
+
*/
|
|
692
|
+
toGoogleTool(): GoogleTool {
|
|
693
|
+
return toGoogleTool(this.getAll());
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
// ---------------------------------------------------------------------------
|
|
698
|
+
// Shared Default Instance
|
|
699
|
+
// ---------------------------------------------------------------------------
|
|
700
|
+
|
|
701
|
+
/**
|
|
702
|
+
* Application-wide tool registry instance. Import this wherever you need
|
|
703
|
+
* to register or look up tools at runtime.
|
|
704
|
+
*/
|
|
705
|
+
export const defaultToolRegistry = new ToolRegistry();
|