zoe-agent 0.3.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/CHANGELOG.md +154 -0
- package/LICENSE +96 -0
- package/README.md +568 -0
- package/dist/adapters/cli/agent.d.ts +59 -0
- package/dist/adapters/cli/agent.js +232 -0
- package/dist/adapters/cli/bootstrap.d.ts +25 -0
- package/dist/adapters/cli/bootstrap.js +204 -0
- package/dist/adapters/cli/commands/build-registry.d.ts +14 -0
- package/dist/adapters/cli/commands/build-registry.js +88 -0
- package/dist/adapters/cli/commands/clear.d.ts +7 -0
- package/dist/adapters/cli/commands/clear.js +10 -0
- package/dist/adapters/cli/commands/compact.d.ts +13 -0
- package/dist/adapters/cli/commands/compact.js +96 -0
- package/dist/adapters/cli/commands/exit.d.ts +7 -0
- package/dist/adapters/cli/commands/exit.js +9 -0
- package/dist/adapters/cli/commands/gateway.d.ts +7 -0
- package/dist/adapters/cli/commands/gateway.js +152 -0
- package/dist/adapters/cli/commands/help.d.ts +9 -0
- package/dist/adapters/cli/commands/help.js +12 -0
- package/dist/adapters/cli/commands/models.d.ts +10 -0
- package/dist/adapters/cli/commands/models.js +32 -0
- package/dist/adapters/cli/commands/registry.d.ts +70 -0
- package/dist/adapters/cli/commands/registry.js +111 -0
- package/dist/adapters/cli/commands/settings-utils.d.ts +38 -0
- package/dist/adapters/cli/commands/settings-utils.js +182 -0
- package/dist/adapters/cli/commands/settings.d.ts +9 -0
- package/dist/adapters/cli/commands/settings.js +395 -0
- package/dist/adapters/cli/commands/skills.d.ts +7 -0
- package/dist/adapters/cli/commands/skills.js +21 -0
- package/dist/adapters/cli/config-loader.d.ts +27 -0
- package/dist/adapters/cli/config-loader.js +48 -0
- package/dist/adapters/cli/docker-utils.d.ts +37 -0
- package/dist/adapters/cli/docker-utils.js +90 -0
- package/dist/adapters/cli/index.d.ts +2 -0
- package/dist/adapters/cli/index.js +88 -0
- package/dist/adapters/cli/repl.d.ts +22 -0
- package/dist/adapters/cli/repl.js +256 -0
- package/dist/adapters/cli/setup.d.ts +19 -0
- package/dist/adapters/cli/setup.js +613 -0
- package/dist/adapters/cli/system-prompts.d.ts +56 -0
- package/dist/adapters/cli/system-prompts.js +131 -0
- package/dist/adapters/cli/tui/app.d.ts +58 -0
- package/dist/adapters/cli/tui/app.js +314 -0
- package/dist/adapters/cli/tui/components/assistant-message.d.ts +5 -0
- package/dist/adapters/cli/tui/components/assistant-message.js +9 -0
- package/dist/adapters/cli/tui/components/autocomplete.d.ts +19 -0
- package/dist/adapters/cli/tui/components/autocomplete.js +75 -0
- package/dist/adapters/cli/tui/components/command-palette.d.ts +15 -0
- package/dist/adapters/cli/tui/components/command-palette.js +50 -0
- package/dist/adapters/cli/tui/components/diff-viewer.d.ts +5 -0
- package/dist/adapters/cli/tui/components/diff-viewer.js +109 -0
- package/dist/adapters/cli/tui/components/error-message.d.ts +5 -0
- package/dist/adapters/cli/tui/components/error-message.js +8 -0
- package/dist/adapters/cli/tui/components/footer.d.ts +20 -0
- package/dist/adapters/cli/tui/components/footer.js +19 -0
- package/dist/adapters/cli/tui/components/goal-status.d.ts +12 -0
- package/dist/adapters/cli/tui/components/goal-status.js +22 -0
- package/dist/adapters/cli/tui/components/info-message.d.ts +5 -0
- package/dist/adapters/cli/tui/components/info-message.js +8 -0
- package/dist/adapters/cli/tui/components/logo-banner.d.ts +7 -0
- package/dist/adapters/cli/tui/components/logo-banner.js +33 -0
- package/dist/adapters/cli/tui/components/markdown.d.ts +9 -0
- package/dist/adapters/cli/tui/components/markdown.js +92 -0
- package/dist/adapters/cli/tui/components/message-area.d.ts +19 -0
- package/dist/adapters/cli/tui/components/message-area.js +55 -0
- package/dist/adapters/cli/tui/components/permission-prompt.d.ts +13 -0
- package/dist/adapters/cli/tui/components/permission-prompt.js +32 -0
- package/dist/adapters/cli/tui/components/prompt-area.d.ts +22 -0
- package/dist/adapters/cli/tui/components/prompt-area.js +68 -0
- package/dist/adapters/cli/tui/components/text-input.d.ts +27 -0
- package/dist/adapters/cli/tui/components/text-input.js +142 -0
- package/dist/adapters/cli/tui/components/tool-call-block.d.ts +11 -0
- package/dist/adapters/cli/tui/components/tool-call-block.js +68 -0
- package/dist/adapters/cli/tui/components/user-message.d.ts +5 -0
- package/dist/adapters/cli/tui/components/user-message.js +8 -0
- package/dist/adapters/cli/tui/diff/file-write-meta.d.ts +11 -0
- package/dist/adapters/cli/tui/diff/file-write-meta.js +11 -0
- package/dist/adapters/cli/tui/diff/line-diff.d.ts +17 -0
- package/dist/adapters/cli/tui/diff/line-diff.js +44 -0
- package/dist/adapters/cli/tui/feed-serializer.d.ts +29 -0
- package/dist/adapters/cli/tui/feed-serializer.js +70 -0
- package/dist/adapters/cli/tui/file-index.d.ts +8 -0
- package/dist/adapters/cli/tui/file-index.js +41 -0
- package/dist/adapters/cli/tui/hooks/use-agent.d.ts +54 -0
- package/dist/adapters/cli/tui/hooks/use-agent.js +177 -0
- package/dist/adapters/cli/tui/hooks/use-feed.d.ts +16 -0
- package/dist/adapters/cli/tui/hooks/use-feed.js +25 -0
- package/dist/adapters/cli/tui/hooks/use-file-watcher.d.ts +10 -0
- package/dist/adapters/cli/tui/hooks/use-file-watcher.js +43 -0
- package/dist/adapters/cli/tui/hooks/use-keybindings.d.ts +16 -0
- package/dist/adapters/cli/tui/hooks/use-keybindings.js +25 -0
- package/dist/adapters/cli/tui/hooks/use-theme.d.ts +8 -0
- package/dist/adapters/cli/tui/hooks/use-theme.js +12 -0
- package/dist/adapters/cli/tui/index.d.ts +19 -0
- package/dist/adapters/cli/tui/index.js +206 -0
- package/dist/adapters/cli/tui/ink-reset.d.ts +29 -0
- package/dist/adapters/cli/tui/ink-reset.js +57 -0
- package/dist/adapters/cli/tui/layout.d.ts +15 -0
- package/dist/adapters/cli/tui/layout.js +15 -0
- package/dist/adapters/cli/tui/logo/gradient.d.ts +11 -0
- package/dist/adapters/cli/tui/logo/gradient.js +31 -0
- package/dist/adapters/cli/tui/overlays/help-dialog.d.ts +4 -0
- package/dist/adapters/cli/tui/overlays/help-dialog.js +26 -0
- package/dist/adapters/cli/tui/overlays/model-selector.d.ts +14 -0
- package/dist/adapters/cli/tui/overlays/model-selector.js +43 -0
- package/dist/adapters/cli/tui/overlays/session-selector.d.ts +35 -0
- package/dist/adapters/cli/tui/overlays/session-selector.js +162 -0
- package/dist/adapters/cli/tui/overlays/settings-overlay.d.ts +24 -0
- package/dist/adapters/cli/tui/overlays/settings-overlay.js +126 -0
- package/dist/adapters/cli/tui/session-export.d.ts +21 -0
- package/dist/adapters/cli/tui/session-export.js +63 -0
- package/dist/adapters/cli/tui/theme.d.ts +23 -0
- package/dist/adapters/cli/tui/theme.js +22 -0
- package/dist/adapters/cli/tui/types.d.ts +52 -0
- package/dist/adapters/cli/tui/types.js +12 -0
- package/dist/adapters/sdk/agent.d.ts +20 -0
- package/dist/adapters/sdk/agent.js +356 -0
- package/dist/adapters/sdk/http.d.ts +43 -0
- package/dist/adapters/sdk/http.js +61 -0
- package/dist/adapters/sdk/index.d.ts +58 -0
- package/dist/adapters/sdk/index.js +209 -0
- package/dist/adapters/sdk/settings.d.ts +18 -0
- package/dist/adapters/sdk/settings.js +57 -0
- package/dist/adapters/sdk/tools.d.ts +7 -0
- package/dist/adapters/sdk/tools.js +13 -0
- package/dist/adapters/server/auth.d.ts +53 -0
- package/dist/adapters/server/auth.js +168 -0
- package/dist/adapters/server/index.d.ts +40 -0
- package/dist/adapters/server/index.js +255 -0
- package/dist/adapters/server/rest-gateway.d.ts +13 -0
- package/dist/adapters/server/rest-gateway.js +218 -0
- package/dist/adapters/server/rest.d.ts +37 -0
- package/dist/adapters/server/rest.js +341 -0
- package/dist/adapters/server/server-core.d.ts +55 -0
- package/dist/adapters/server/server-core.js +121 -0
- package/dist/adapters/server/session-store.d.ts +81 -0
- package/dist/adapters/server/session-store.js +272 -0
- package/dist/adapters/server/settings-handlers.d.ts +24 -0
- package/dist/adapters/server/settings-handlers.js +360 -0
- package/dist/adapters/server/standalone.d.ts +19 -0
- package/dist/adapters/server/standalone.js +113 -0
- package/dist/adapters/server/websocket.d.ts +26 -0
- package/dist/adapters/server/websocket.js +68 -0
- package/dist/adapters/server/ws-handlers.d.ts +32 -0
- package/dist/adapters/server/ws-handlers.js +523 -0
- package/dist/adapters/server/ws-types.d.ts +304 -0
- package/dist/adapters/server/ws-types.js +7 -0
- package/dist/core/agent-loop.d.ts +68 -0
- package/dist/core/agent-loop.js +423 -0
- package/dist/core/config.d.ts +115 -0
- package/dist/core/config.js +189 -0
- package/dist/core/errors.d.ts +58 -0
- package/dist/core/errors.js +88 -0
- package/dist/core/hooks.d.ts +35 -0
- package/dist/core/hooks.js +49 -0
- package/dist/core/index.d.ts +23 -0
- package/dist/core/index.js +29 -0
- package/dist/core/message-convert.d.ts +41 -0
- package/dist/core/message-convert.js +94 -0
- package/dist/core/middleware/auth.d.ts +24 -0
- package/dist/core/middleware/auth.js +28 -0
- package/dist/core/middleware/logging.d.ts +23 -0
- package/dist/core/middleware/logging.js +28 -0
- package/dist/core/middleware/rate-limit.d.ts +27 -0
- package/dist/core/middleware/rate-limit.js +38 -0
- package/dist/core/middleware/semantic-tools.d.ts +10 -0
- package/dist/core/middleware/semantic-tools.js +43 -0
- package/dist/core/middleware.d.ts +48 -0
- package/dist/core/middleware.js +38 -0
- package/dist/core/permission.d.ts +25 -0
- package/dist/core/permission.js +50 -0
- package/dist/core/provider-config.d.ts +129 -0
- package/dist/core/provider-config.js +273 -0
- package/dist/core/provider-env.d.ts +39 -0
- package/dist/core/provider-env.js +142 -0
- package/dist/core/provider-resolver.d.ts +12 -0
- package/dist/core/provider-resolver.js +12 -0
- package/dist/core/session-store.d.ts +75 -0
- package/dist/core/session-store.js +245 -0
- package/dist/core/settings-manager.d.ts +57 -0
- package/dist/core/settings-manager.js +359 -0
- package/dist/core/settings-schema.d.ts +38 -0
- package/dist/core/settings-schema.js +171 -0
- package/dist/core/skill-catalog.d.ts +6 -0
- package/dist/core/skill-catalog.js +17 -0
- package/dist/core/skill-invoker.d.ts +127 -0
- package/dist/core/skill-invoker.js +182 -0
- package/dist/core/stream-accumulator.d.ts +21 -0
- package/dist/core/stream-accumulator.js +51 -0
- package/dist/core/stream-manager.d.ts +58 -0
- package/dist/core/stream-manager.js +212 -0
- package/dist/core/tool-executor.d.ts +84 -0
- package/dist/core/tool-executor.js +256 -0
- package/dist/core/types.d.ts +259 -0
- package/dist/core/types.js +11 -0
- package/dist/gateway/gateway.d.ts +52 -0
- package/dist/gateway/gateway.js +537 -0
- package/dist/gateway/index.d.ts +21 -0
- package/dist/gateway/index.js +31 -0
- package/dist/gateway/openapi-importer.d.ts +15 -0
- package/dist/gateway/openapi-importer.js +66 -0
- package/dist/gateway/semantic-scorer.d.ts +7 -0
- package/dist/gateway/semantic-scorer.js +24 -0
- package/dist/gateway/settings-adapter.d.ts +49 -0
- package/dist/gateway/settings-adapter.js +137 -0
- package/dist/gateway/tool-factory.d.ts +9 -0
- package/dist/gateway/tool-factory.js +414 -0
- package/dist/gateway/types.d.ts +68 -0
- package/dist/gateway/types.js +7 -0
- package/dist/models-catalog.js +46 -0
- package/dist/providers/anthropic.d.ts +22 -0
- package/dist/providers/anthropic.js +148 -0
- package/dist/providers/factory.d.ts +10 -0
- package/dist/providers/factory.js +25 -0
- package/dist/providers/openai.d.ts +15 -0
- package/dist/providers/openai.js +71 -0
- package/dist/providers/types.d.ts +48 -0
- package/dist/providers/types.js +1 -0
- package/dist/skills/args.d.ts +37 -0
- package/dist/skills/args.js +99 -0
- package/dist/skills/index.d.ts +11 -0
- package/dist/skills/index.js +23 -0
- package/dist/skills/loader.d.ts +3 -0
- package/dist/skills/loader.js +59 -0
- package/dist/skills/parser.d.ts +7 -0
- package/dist/skills/parser.js +152 -0
- package/dist/skills/registry.d.ts +13 -0
- package/dist/skills/registry.js +74 -0
- package/dist/skills/resolver.d.ts +19 -0
- package/dist/skills/resolver.js +116 -0
- package/dist/skills/types.d.ts +74 -0
- package/dist/skills/types.js +50 -0
- package/dist/tools/browser.d.ts +2 -0
- package/dist/tools/browser.js +68 -0
- package/dist/tools/core.d.ts +20 -0
- package/dist/tools/core.js +244 -0
- package/dist/tools/email.d.ts +2 -0
- package/dist/tools/email.js +61 -0
- package/dist/tools/image.d.ts +2 -0
- package/dist/tools/image.js +257 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.js +88 -0
- package/dist/tools/interface.d.ts +22 -0
- package/dist/tools/interface.js +1 -0
- package/dist/tools/notify.d.ts +2 -0
- package/dist/tools/notify.js +100 -0
- package/dist/tools/prompt-optimizer.d.ts +2 -0
- package/dist/tools/prompt-optimizer.js +65 -0
- package/dist/tools/screenshot.d.ts +2 -0
- package/dist/tools/screenshot.js +184 -0
- package/dist/tools/search.d.ts +2 -0
- package/dist/tools/search.js +78 -0
- package/dist/tools/todos.d.ts +10 -0
- package/dist/tools/todos.js +50 -0
- package/package.json +119 -0
- package/skills/docker-ops/SKILL.md +329 -0
- package/skills/k8s-deploy/SKILL.md +397 -0
- package/skills/log-analyzer/SKILL.md +331 -0
- package/skills/speckit-analyze/SKILL.md +260 -0
- package/skills/speckit-checklist/SKILL.md +374 -0
- package/skills/speckit-clarify/SKILL.md +286 -0
- package/skills/speckit-constitution/SKILL.md +157 -0
- package/skills/speckit-implement/SKILL.md +224 -0
- package/skills/speckit-plan/SKILL.md +171 -0
- package/skills/speckit-specify/SKILL.md +346 -0
- package/skills/speckit-tasks/SKILL.md +215 -0
- package/skills/speckit-taskstoissues/SKILL.md +107 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zoe Gateway — Type definitions
|
|
3
|
+
*
|
|
4
|
+
* Types for MCP targets, REST targets, audit records, and gateway config.
|
|
5
|
+
* Reuses Zoe's existing ToolModule and ToolDefinition from src/tools/interface.ts.
|
|
6
|
+
*/
|
|
7
|
+
export type AuthType = 'none' | 'header' | 'bearer' | 'query' | 'basic';
|
|
8
|
+
export type McpTransportType = 'stdio' | 'sse' | 'http';
|
|
9
|
+
export interface RestTarget {
|
|
10
|
+
kind: 'rest';
|
|
11
|
+
baseUrl: string;
|
|
12
|
+
description: string;
|
|
13
|
+
auth: {
|
|
14
|
+
type: AuthType;
|
|
15
|
+
name?: string;
|
|
16
|
+
credentialRef?: string;
|
|
17
|
+
};
|
|
18
|
+
defaultHeaders: Record<string, string>;
|
|
19
|
+
operations: Array<{
|
|
20
|
+
opId: string;
|
|
21
|
+
method: string;
|
|
22
|
+
path: string;
|
|
23
|
+
summary: string;
|
|
24
|
+
}>;
|
|
25
|
+
tags: string[];
|
|
26
|
+
enabled: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface McpTarget {
|
|
29
|
+
kind: 'mcp';
|
|
30
|
+
transport: McpTransportType;
|
|
31
|
+
command?: string;
|
|
32
|
+
args?: string[];
|
|
33
|
+
env?: Record<string, string>;
|
|
34
|
+
url?: string;
|
|
35
|
+
auth?: {
|
|
36
|
+
type: AuthType;
|
|
37
|
+
name?: string;
|
|
38
|
+
credentialRef?: string;
|
|
39
|
+
};
|
|
40
|
+
description: string;
|
|
41
|
+
tags: string[];
|
|
42
|
+
enabled: boolean;
|
|
43
|
+
capabilities?: {
|
|
44
|
+
tools?: any[];
|
|
45
|
+
resources?: any[];
|
|
46
|
+
prompts?: any[];
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export type Target = RestTarget | McpTarget;
|
|
50
|
+
export interface AuditRecord {
|
|
51
|
+
timestamp: number;
|
|
52
|
+
agent: string;
|
|
53
|
+
target: string;
|
|
54
|
+
operation: string;
|
|
55
|
+
status: string;
|
|
56
|
+
durationMs: number;
|
|
57
|
+
success: boolean;
|
|
58
|
+
}
|
|
59
|
+
export interface GatewayHooks {
|
|
60
|
+
onAudit?: (record: AuditRecord) => void | Promise<void>;
|
|
61
|
+
onSamplingRequest?: (params: any) => Promise<any>;
|
|
62
|
+
}
|
|
63
|
+
export interface GatewayConfig {
|
|
64
|
+
enabled: boolean;
|
|
65
|
+
semanticTopK: number;
|
|
66
|
+
defaultRateLimitPerMin: number;
|
|
67
|
+
maxAuditLogsInMemory: number;
|
|
68
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const M = (id, name, contextWindow, input, output) => ({
|
|
2
|
+
id, name, contextWindow, pricing: { input, output },
|
|
3
|
+
});
|
|
4
|
+
export const MODEL_CATALOG = {
|
|
5
|
+
'openai-compatible': [], // No curated list — user provides their own model name
|
|
6
|
+
openai: [
|
|
7
|
+
M('gpt-5.4', 'GPT-5.4', 256000, 2.5, 10),
|
|
8
|
+
M('gpt-5.4-pro', 'GPT-5.4 Pro', 256000, 5, 20),
|
|
9
|
+
M('gpt-5.4-mini', 'GPT-5.4 Mini', 128000, 0.15, 0.6),
|
|
10
|
+
M('gpt-5.4-nano', 'GPT-5.4 Nano', 128000, 0.05, 0.2),
|
|
11
|
+
M('gpt-5.3-instant', 'GPT-5.3 Instant', 128000, 0.5, 2),
|
|
12
|
+
M('gpt-5.3-codex', 'GPT-5.3 Codex', 256000, 2, 8),
|
|
13
|
+
M('o3', 'o3', 200000, 5, 15),
|
|
14
|
+
M('o3-mini', 'o3 Mini', 200000, 1, 4),
|
|
15
|
+
],
|
|
16
|
+
anthropic: [
|
|
17
|
+
M('claude-sonnet-4-6-20260320', 'Claude Sonnet 4.6', 200000, 3, 15),
|
|
18
|
+
M('claude-opus-4-6-20260320', 'Claude Opus 4.6', 200000, 15, 75),
|
|
19
|
+
M('claude-haiku-4-5-20251001', 'Claude Haiku 4.5', 200000, 0.8, 4),
|
|
20
|
+
],
|
|
21
|
+
glm: [
|
|
22
|
+
M('haiku', 'GLM-4.5 Air', 128000, 0.5, 1.5),
|
|
23
|
+
M('sonnet', 'GLM-4.7', 128000, 1, 3),
|
|
24
|
+
M('opus', 'GLM-5.1', 128000, 2, 6),
|
|
25
|
+
],
|
|
26
|
+
};
|
|
27
|
+
export const CUSTOM_MODEL_VALUE = '__custom__';
|
|
28
|
+
/**
|
|
29
|
+
* Default model ID for each provider.
|
|
30
|
+
* Single source of truth — all other files import from here.
|
|
31
|
+
*/
|
|
32
|
+
export const DEFAULT_MODELS = {
|
|
33
|
+
openai: 'gpt-5.4',
|
|
34
|
+
anthropic: 'claude-sonnet-4-6-20260320',
|
|
35
|
+
glm: 'opus',
|
|
36
|
+
'openai-compatible': 'gpt-5.4',
|
|
37
|
+
};
|
|
38
|
+
/** Look up a model's metadata (context window + pricing) by id, across providers. */
|
|
39
|
+
export function getModelMeta(id) {
|
|
40
|
+
for (const list of Object.values(MODEL_CATALOG)) {
|
|
41
|
+
const found = list.find((m) => m.id === id);
|
|
42
|
+
if (found)
|
|
43
|
+
return found;
|
|
44
|
+
}
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ProviderMessage, ProviderResponse, LLMProvider, ChatOptions, StreamDelta } from './types.js';
|
|
2
|
+
import type { ToolDefinition } from '../tools/interface.js';
|
|
3
|
+
export declare class AnthropicProvider implements LLMProvider {
|
|
4
|
+
private client;
|
|
5
|
+
private model;
|
|
6
|
+
constructor(apiKey: string, model: string, options?: {
|
|
7
|
+
baseURL?: string;
|
|
8
|
+
timeout?: number;
|
|
9
|
+
});
|
|
10
|
+
/**
|
|
11
|
+
* Translate Zoe messages + tools into Anthropic's request shape. Shared by
|
|
12
|
+
* `chat()` and `chatStream()` so the (non-trivial) translation lives once.
|
|
13
|
+
*/
|
|
14
|
+
private buildRequest;
|
|
15
|
+
chat(messages: ProviderMessage[], tools: ToolDefinition[], options?: ChatOptions): Promise<ProviderResponse>;
|
|
16
|
+
/**
|
|
17
|
+
* Stream the response via Anthropic's message stream. Text blocks yield
|
|
18
|
+
* `text_delta`; tool_use blocks yield `tool_call_begin` (on block start) then
|
|
19
|
+
* `tool_call_delta` for each `input_json_delta` fragment, keyed by block index.
|
|
20
|
+
*/
|
|
21
|
+
chatStream(messages: ProviderMessage[], tools: ToolDefinition[], options?: ChatOptions): AsyncIterable<StreamDelta>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
2
|
+
export class AnthropicProvider {
|
|
3
|
+
client;
|
|
4
|
+
model;
|
|
5
|
+
constructor(apiKey, model, options) {
|
|
6
|
+
this.client = new Anthropic({
|
|
7
|
+
apiKey,
|
|
8
|
+
baseURL: options?.baseURL,
|
|
9
|
+
timeout: options?.timeout,
|
|
10
|
+
});
|
|
11
|
+
this.model = model;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Translate Zoe messages + tools into Anthropic's request shape. Shared by
|
|
15
|
+
* `chat()` and `chatStream()` so the (non-trivial) translation lives once.
|
|
16
|
+
*/
|
|
17
|
+
buildRequest(messages, tools) {
|
|
18
|
+
const systemParts = [];
|
|
19
|
+
const nonSystem = [];
|
|
20
|
+
for (const msg of messages) {
|
|
21
|
+
if (msg.role === 'system') {
|
|
22
|
+
if (msg.content)
|
|
23
|
+
systemParts.push(msg.content);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
nonSystem.push(msg);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const anthropicMessages = [];
|
|
30
|
+
for (const msg of nonSystem) {
|
|
31
|
+
if (msg.role === 'assistant' && msg.tool_calls?.length) {
|
|
32
|
+
const content = [];
|
|
33
|
+
if (msg.content)
|
|
34
|
+
content.push({ type: 'text', text: msg.content });
|
|
35
|
+
for (const tc of msg.tool_calls) {
|
|
36
|
+
content.push({
|
|
37
|
+
type: 'tool_use',
|
|
38
|
+
id: tc.id,
|
|
39
|
+
name: tc.name,
|
|
40
|
+
input: JSON.parse(tc.arguments),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
anthropicMessages.push({ role: 'assistant', content });
|
|
44
|
+
}
|
|
45
|
+
else if (msg.role === 'tool') {
|
|
46
|
+
anthropicMessages.push({
|
|
47
|
+
role: 'user',
|
|
48
|
+
content: [{
|
|
49
|
+
type: 'tool_result',
|
|
50
|
+
tool_use_id: msg.tool_call_id,
|
|
51
|
+
content: msg.content ?? '',
|
|
52
|
+
}],
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
anthropicMessages.push({
|
|
57
|
+
role: msg.role,
|
|
58
|
+
content: msg.content ?? '',
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const anthropicTools = tools.map((t) => ({
|
|
63
|
+
name: t.function.name,
|
|
64
|
+
description: t.function.description,
|
|
65
|
+
input_schema: t.function.parameters,
|
|
66
|
+
}));
|
|
67
|
+
return {
|
|
68
|
+
system: systemParts.length ? systemParts.join('\n') : undefined,
|
|
69
|
+
anthropicMessages,
|
|
70
|
+
anthropicTools,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
async chat(messages, tools, options) {
|
|
74
|
+
const { system, anthropicMessages, anthropicTools } = this.buildRequest(messages, tools);
|
|
75
|
+
const response = await this.client.messages.create({
|
|
76
|
+
model: this.model,
|
|
77
|
+
max_tokens: 16384,
|
|
78
|
+
system,
|
|
79
|
+
messages: anthropicMessages,
|
|
80
|
+
tools: anthropicTools,
|
|
81
|
+
}, { signal: options?.signal });
|
|
82
|
+
// Translate response
|
|
83
|
+
let content;
|
|
84
|
+
const toolCalls = [];
|
|
85
|
+
for (const block of response.content) {
|
|
86
|
+
if (block.type === 'text') {
|
|
87
|
+
content = content ? content + block.text : block.text;
|
|
88
|
+
}
|
|
89
|
+
else if (block.type === 'tool_use') {
|
|
90
|
+
toolCalls.push({
|
|
91
|
+
id: block.id,
|
|
92
|
+
name: block.name,
|
|
93
|
+
arguments: JSON.stringify(block.input),
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
content: content || undefined,
|
|
99
|
+
tool_calls: toolCalls.length ? toolCalls : undefined,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Stream the response via Anthropic's message stream. Text blocks yield
|
|
104
|
+
* `text_delta`; tool_use blocks yield `tool_call_begin` (on block start) then
|
|
105
|
+
* `tool_call_delta` for each `input_json_delta` fragment, keyed by block index.
|
|
106
|
+
*/
|
|
107
|
+
async *chatStream(messages, tools, options) {
|
|
108
|
+
const { system, anthropicMessages, anthropicTools } = this.buildRequest(messages, tools);
|
|
109
|
+
const stream = this.client.messages.stream({
|
|
110
|
+
model: this.model,
|
|
111
|
+
max_tokens: 16384,
|
|
112
|
+
system,
|
|
113
|
+
messages: anthropicMessages,
|
|
114
|
+
tools: anthropicTools,
|
|
115
|
+
}, { signal: options?.signal });
|
|
116
|
+
for await (const event of stream) {
|
|
117
|
+
if (event.type === 'content_block_start' && event.content_block.type === 'tool_use') {
|
|
118
|
+
yield {
|
|
119
|
+
type: 'tool_call_begin',
|
|
120
|
+
index: event.index,
|
|
121
|
+
id: event.content_block.id,
|
|
122
|
+
name: event.content_block.name,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
else if (event.type === 'content_block_delta') {
|
|
126
|
+
if (event.delta.type === 'text_delta') {
|
|
127
|
+
yield { type: 'text_delta', content: event.delta.text };
|
|
128
|
+
}
|
|
129
|
+
else if (event.delta.type === 'input_json_delta') {
|
|
130
|
+
yield { type: 'tool_call_delta', index: event.index, argumentsDelta: event.delta.partial_json };
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
else if (event.type === 'message_delta' && event.usage) {
|
|
134
|
+
const inputTokens = event.usage.input_tokens ?? 0;
|
|
135
|
+
const outputTokens = event.usage.output_tokens ?? 0;
|
|
136
|
+
yield {
|
|
137
|
+
type: 'finish',
|
|
138
|
+
usage: {
|
|
139
|
+
promptTokens: inputTokens,
|
|
140
|
+
completionTokens: outputTokens,
|
|
141
|
+
totalTokens: inputTokens + outputTokens,
|
|
142
|
+
cost: 0,
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ProviderType, LLMProvider } from './types.js';
|
|
2
|
+
export interface ProviderConfig {
|
|
3
|
+
type: ProviderType;
|
|
4
|
+
apiKey: string;
|
|
5
|
+
model: string;
|
|
6
|
+
baseUrl?: string;
|
|
7
|
+
timeout?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const GLM_MODEL_MAP: Record<string, string>;
|
|
10
|
+
export declare function createProvider(config: ProviderConfig): Promise<LLMProvider>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export const GLM_MODEL_MAP = {
|
|
2
|
+
haiku: 'glm-4.5-air',
|
|
3
|
+
sonnet: 'glm-4.7',
|
|
4
|
+
opus: 'glm-5.1',
|
|
5
|
+
};
|
|
6
|
+
export async function createProvider(config) {
|
|
7
|
+
switch (config.type) {
|
|
8
|
+
case 'openai': {
|
|
9
|
+
const { OpenAIProvider } = await import('./openai.js');
|
|
10
|
+
return new OpenAIProvider(config.apiKey, config.model, 'https://api.openai.com/v1');
|
|
11
|
+
}
|
|
12
|
+
case 'openai-compatible': {
|
|
13
|
+
const { OpenAIProvider } = await import('./openai.js');
|
|
14
|
+
return new OpenAIProvider(config.apiKey, config.model, config.baseUrl);
|
|
15
|
+
}
|
|
16
|
+
case 'anthropic': {
|
|
17
|
+
const { AnthropicProvider } = await import('./anthropic.js');
|
|
18
|
+
return new AnthropicProvider(config.apiKey, config.model);
|
|
19
|
+
}
|
|
20
|
+
case 'glm': {
|
|
21
|
+
const { AnthropicProvider } = await import('./anthropic.js');
|
|
22
|
+
return new AnthropicProvider(config.apiKey, GLM_MODEL_MAP[config.model] || config.model, { baseURL: 'https://api.z.ai/api/anthropic', timeout: 3000000 });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ProviderMessage, ProviderResponse, LLMProvider, ChatOptions, StreamDelta } from './types.js';
|
|
2
|
+
import type { ToolDefinition } from '../tools/interface.js';
|
|
3
|
+
export declare class OpenAIProvider implements LLMProvider {
|
|
4
|
+
private client;
|
|
5
|
+
private model;
|
|
6
|
+
constructor(apiKey: string, model: string, baseURL?: string);
|
|
7
|
+
chat(messages: ProviderMessage[], tools: ToolDefinition[], options?: ChatOptions): Promise<ProviderResponse>;
|
|
8
|
+
/**
|
|
9
|
+
* Stream the response using the OpenAI SDK's native streaming. Maps chunks to
|
|
10
|
+
* `StreamDelta`s: text deltas, tool-call begin (id+name on the first chunk)
|
|
11
|
+
* and argument fragments (subsequent chunks, keyed by `index`), and a final
|
|
12
|
+
* `finish` with usage (when `stream_options.include_usage` is set).
|
|
13
|
+
*/
|
|
14
|
+
chatStream(messages: ProviderMessage[], tools: ToolDefinition[], options?: ChatOptions): AsyncIterable<StreamDelta>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { OpenAI } from 'openai';
|
|
2
|
+
export class OpenAIProvider {
|
|
3
|
+
client;
|
|
4
|
+
model;
|
|
5
|
+
constructor(apiKey, model, baseURL) {
|
|
6
|
+
this.client = new OpenAI({ apiKey, baseURL });
|
|
7
|
+
this.model = model;
|
|
8
|
+
}
|
|
9
|
+
async chat(messages, tools, options) {
|
|
10
|
+
const response = await this.client.chat.completions.create({
|
|
11
|
+
model: this.model,
|
|
12
|
+
messages: messages,
|
|
13
|
+
tools: tools,
|
|
14
|
+
}, { signal: options?.signal });
|
|
15
|
+
const message = response.choices[0]?.message;
|
|
16
|
+
if (!message)
|
|
17
|
+
return {};
|
|
18
|
+
return {
|
|
19
|
+
content: message.content ?? undefined,
|
|
20
|
+
tool_calls: message.tool_calls
|
|
21
|
+
?.filter((tc) => tc.type === 'function')
|
|
22
|
+
.map((tc) => ({
|
|
23
|
+
id: tc.id,
|
|
24
|
+
name: tc.function.name,
|
|
25
|
+
arguments: tc.function.arguments,
|
|
26
|
+
})),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Stream the response using the OpenAI SDK's native streaming. Maps chunks to
|
|
31
|
+
* `StreamDelta`s: text deltas, tool-call begin (id+name on the first chunk)
|
|
32
|
+
* and argument fragments (subsequent chunks, keyed by `index`), and a final
|
|
33
|
+
* `finish` with usage (when `stream_options.include_usage` is set).
|
|
34
|
+
*/
|
|
35
|
+
async *chatStream(messages, tools, options) {
|
|
36
|
+
const stream = await this.client.chat.completions.create({
|
|
37
|
+
model: this.model,
|
|
38
|
+
messages: messages,
|
|
39
|
+
tools: tools,
|
|
40
|
+
stream: true,
|
|
41
|
+
stream_options: { include_usage: true },
|
|
42
|
+
}, { signal: options?.signal });
|
|
43
|
+
for await (const chunk of stream) {
|
|
44
|
+
const delta = chunk.choices[0]?.delta;
|
|
45
|
+
if (delta?.content) {
|
|
46
|
+
yield { type: 'text_delta', content: delta.content };
|
|
47
|
+
}
|
|
48
|
+
if (delta?.tool_calls) {
|
|
49
|
+
for (const tc of delta.tool_calls) {
|
|
50
|
+
if (tc.function?.name) {
|
|
51
|
+
yield { type: 'tool_call_begin', index: tc.index, id: tc.id ?? '', name: tc.function.name };
|
|
52
|
+
}
|
|
53
|
+
if (tc.function?.arguments) {
|
|
54
|
+
yield { type: 'tool_call_delta', index: tc.index, argumentsDelta: tc.function.arguments };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (chunk.usage) {
|
|
59
|
+
yield {
|
|
60
|
+
type: 'finish',
|
|
61
|
+
usage: {
|
|
62
|
+
promptTokens: chunk.usage.prompt_tokens,
|
|
63
|
+
completionTokens: chunk.usage.completion_tokens,
|
|
64
|
+
totalTokens: chunk.usage.total_tokens,
|
|
65
|
+
cost: 0,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export type { ProviderType } from "../core/types.js";
|
|
2
|
+
import type { ToolDefinition } from '../tools/interface.js';
|
|
3
|
+
import type { Usage } from '../core/types.js';
|
|
4
|
+
export interface ProviderMessage {
|
|
5
|
+
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
6
|
+
content?: string;
|
|
7
|
+
tool_calls?: ProviderToolCall[];
|
|
8
|
+
tool_call_id?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ProviderToolCall {
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
arguments: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ProviderResponse {
|
|
16
|
+
content?: string;
|
|
17
|
+
tool_calls?: ProviderToolCall[];
|
|
18
|
+
}
|
|
19
|
+
export interface ChatOptions {
|
|
20
|
+
signal?: AbortSignal;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A single chunk from a streaming model response. Providers split a response
|
|
24
|
+
* across many deltas — text arrives token-by-token, and a tool call's JSON
|
|
25
|
+
* arguments usually arrive fragmented. `runAgentLoop` reassembles these via
|
|
26
|
+
* `StreamingResponseAccumulator`.
|
|
27
|
+
*/
|
|
28
|
+
export type StreamDelta = {
|
|
29
|
+
type: 'text_delta';
|
|
30
|
+
content: string;
|
|
31
|
+
} | {
|
|
32
|
+
type: 'tool_call_begin';
|
|
33
|
+
index: number;
|
|
34
|
+
id: string;
|
|
35
|
+
name: string;
|
|
36
|
+
} | {
|
|
37
|
+
type: 'tool_call_delta';
|
|
38
|
+
index: number;
|
|
39
|
+
argumentsDelta: string;
|
|
40
|
+
} | {
|
|
41
|
+
type: 'finish';
|
|
42
|
+
usage?: Usage;
|
|
43
|
+
};
|
|
44
|
+
export interface LLMProvider {
|
|
45
|
+
chat(messages: ProviderMessage[], tools: ToolDefinition[], options?: ChatOptions): Promise<ProviderResponse>;
|
|
46
|
+
/** Optional streaming variant. Absent → callers fall back to `chat()`. */
|
|
47
|
+
chatStream?(messages: ProviderMessage[], tools: ToolDefinition[], options?: ChatOptions): AsyncIterable<StreamDelta>;
|
|
48
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamic argument parsing and template substitution for skills.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - $1, $2, ... — positional arguments
|
|
6
|
+
* - $ALL — all arguments as a single string
|
|
7
|
+
* - $COUNT — number of arguments
|
|
8
|
+
* - $FIRST — first argument
|
|
9
|
+
* - $LAST — last argument
|
|
10
|
+
*/
|
|
11
|
+
export interface ParsedArgs {
|
|
12
|
+
positional: string[];
|
|
13
|
+
raw: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Parse a user input string into a skill name and arguments.
|
|
17
|
+
* Handles quoted strings for multi-word arguments.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* parseInvocation('/docker-ops build myapp:1.2.0 --no-cache')
|
|
21
|
+
* // => { skillName: 'docker-ops', args: { positional: ['build', 'myapp:1.2.0', '--no-cache'], raw: 'build myapp:1.2.0 --no-cache' } }
|
|
22
|
+
*/
|
|
23
|
+
export declare function parseInvocation(input: string): {
|
|
24
|
+
skillName: string;
|
|
25
|
+
args: ParsedArgs;
|
|
26
|
+
} | null;
|
|
27
|
+
/**
|
|
28
|
+
* Substitute template variables in a skill body with actual arguments.
|
|
29
|
+
*
|
|
30
|
+
* Supported variables:
|
|
31
|
+
* - $1, $2, ..., $N — positional arguments (1-indexed)
|
|
32
|
+
* - $ALL — all arguments joined as a string
|
|
33
|
+
* - $COUNT — number of arguments
|
|
34
|
+
* - $FIRST — first argument (same as $1)
|
|
35
|
+
* - $LAST — last argument
|
|
36
|
+
*/
|
|
37
|
+
export declare function substituteArgs(body: string, args: ParsedArgs): string;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamic argument parsing and template substitution for skills.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - $1, $2, ... — positional arguments
|
|
6
|
+
* - $ALL — all arguments as a single string
|
|
7
|
+
* - $COUNT — number of arguments
|
|
8
|
+
* - $FIRST — first argument
|
|
9
|
+
* - $LAST — last argument
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Parse a user input string into a skill name and arguments.
|
|
13
|
+
* Handles quoted strings for multi-word arguments.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* parseInvocation('/docker-ops build myapp:1.2.0 --no-cache')
|
|
17
|
+
* // => { skillName: 'docker-ops', args: { positional: ['build', 'myapp:1.2.0', '--no-cache'], raw: 'build myapp:1.2.0 --no-cache' } }
|
|
18
|
+
*/
|
|
19
|
+
export function parseInvocation(input) {
|
|
20
|
+
if (!input.startsWith('/') || input.length < 2)
|
|
21
|
+
return null;
|
|
22
|
+
const body = input.slice(1);
|
|
23
|
+
const firstSpace = body.search(/\s/);
|
|
24
|
+
if (firstSpace === -1) {
|
|
25
|
+
return { skillName: body, args: { positional: [], raw: '' } };
|
|
26
|
+
}
|
|
27
|
+
const skillName = body.slice(0, firstSpace);
|
|
28
|
+
const argsRaw = body.slice(firstSpace + 1).trim();
|
|
29
|
+
return {
|
|
30
|
+
skillName,
|
|
31
|
+
args: {
|
|
32
|
+
positional: splitArgs(argsRaw),
|
|
33
|
+
raw: argsRaw,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Split argument string respecting quoted strings.
|
|
39
|
+
*/
|
|
40
|
+
function splitArgs(input) {
|
|
41
|
+
const args = [];
|
|
42
|
+
let current = '';
|
|
43
|
+
let inQuote = false;
|
|
44
|
+
let quoteChar = '';
|
|
45
|
+
for (let i = 0; i < input.length; i++) {
|
|
46
|
+
const ch = input[i];
|
|
47
|
+
if (inQuote) {
|
|
48
|
+
if (ch === quoteChar) {
|
|
49
|
+
inQuote = false;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
current += ch;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else if (ch === '"' || ch === "'") {
|
|
56
|
+
inQuote = true;
|
|
57
|
+
quoteChar = ch;
|
|
58
|
+
}
|
|
59
|
+
else if (ch === ' ') {
|
|
60
|
+
if (current) {
|
|
61
|
+
args.push(current);
|
|
62
|
+
current = '';
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
current += ch;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (current)
|
|
70
|
+
args.push(current);
|
|
71
|
+
return args;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Substitute template variables in a skill body with actual arguments.
|
|
75
|
+
*
|
|
76
|
+
* Supported variables:
|
|
77
|
+
* - $1, $2, ..., $N — positional arguments (1-indexed)
|
|
78
|
+
* - $ALL — all arguments joined as a string
|
|
79
|
+
* - $COUNT — number of arguments
|
|
80
|
+
* - $FIRST — first argument (same as $1)
|
|
81
|
+
* - $LAST — last argument
|
|
82
|
+
*/
|
|
83
|
+
export function substituteArgs(body, args) {
|
|
84
|
+
let result = body;
|
|
85
|
+
// $ALL — all arguments as a single string
|
|
86
|
+
result = result.replace(/\$ALL\b/g, args.raw);
|
|
87
|
+
// $COUNT — number of arguments
|
|
88
|
+
result = result.replace(/\$COUNT\b/g, String(args.positional.length));
|
|
89
|
+
// $FIRST — first argument
|
|
90
|
+
result = result.replace(/\$FIRST\b/g, args.positional[0] || '');
|
|
91
|
+
// $LAST — last argument
|
|
92
|
+
result = result.replace(/\$LAST\b/g, args.positional[args.positional.length - 1] || '');
|
|
93
|
+
// $N — positional arguments (must process AFTER $ALL, $COUNT etc. to avoid conflicts)
|
|
94
|
+
// Replace from highest index down to avoid $10 being matched as $1
|
|
95
|
+
for (let i = args.positional.length; i >= 1; i--) {
|
|
96
|
+
result = result.replace(new RegExp(`\\$${i}\\b`, 'g'), args.positional[i - 1]);
|
|
97
|
+
}
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type { Skill, SkillFrontmatter, SkillMetadata, SkillRegistry, SkillModelConfig, TruncationResult } from './types.js';
|
|
2
|
+
export { parseSkillFile, parseFrontmatter } from './parser.js';
|
|
3
|
+
export { discoverSkills, getSkillPaths } from './loader.js';
|
|
4
|
+
export { DefaultSkillRegistry } from './registry.js';
|
|
5
|
+
export { parseInvocation, substituteArgs } from './args.js';
|
|
6
|
+
export type { ParsedArgs } from './args.js';
|
|
7
|
+
export { resolveReferences } from './resolver.js';
|
|
8
|
+
export { limitSkillBody, getSkillBodyLimits } from './types.js';
|
|
9
|
+
import { SkillRegistry } from './types.js';
|
|
10
|
+
export declare function initializeSkillRegistry(cwd: string): Promise<SkillRegistry>;
|
|
11
|
+
export declare function getSkillRegistry(): SkillRegistry | null;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export { parseSkillFile, parseFrontmatter } from './parser.js';
|
|
2
|
+
export { discoverSkills, getSkillPaths } from './loader.js';
|
|
3
|
+
export { DefaultSkillRegistry } from './registry.js';
|
|
4
|
+
export { parseInvocation, substituteArgs } from './args.js';
|
|
5
|
+
export { resolveReferences } from './resolver.js';
|
|
6
|
+
export { limitSkillBody, getSkillBodyLimits } from './types.js';
|
|
7
|
+
import { discoverSkills } from './loader.js';
|
|
8
|
+
import { DefaultSkillRegistry } from './registry.js';
|
|
9
|
+
let registry = null;
|
|
10
|
+
export async function initializeSkillRegistry(cwd) {
|
|
11
|
+
const skills = await discoverSkills(cwd);
|
|
12
|
+
registry = new DefaultSkillRegistry(skills);
|
|
13
|
+
if (process.env.ZOE_SKILLS_DEBUG) {
|
|
14
|
+
console.log(`[SKILLS] Loaded ${skills.length} skills`);
|
|
15
|
+
for (const s of skills) {
|
|
16
|
+
console.log(`[SKILLS] - ${s.name} from ${s.source}`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return registry;
|
|
20
|
+
}
|
|
21
|
+
export function getSkillRegistry() {
|
|
22
|
+
return registry;
|
|
23
|
+
}
|