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,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zoe SDK — Public entry point
|
|
3
|
+
*
|
|
4
|
+
* Exports `generateText`, `streamText`, `createAgent`, and all public types,
|
|
5
|
+
* tool factories, provider helpers, and skill utilities.
|
|
6
|
+
*/
|
|
7
|
+
import { getProvider } from "../../core/provider-resolver.js";
|
|
8
|
+
import { createHookExecutor } from "../../core/hooks.js";
|
|
9
|
+
import { StreamManager } from "../../core/stream-manager.js";
|
|
10
|
+
import { resolveTools, getAllToolDefinitions } from "./tools.js";
|
|
11
|
+
import { runAgentLoop } from "../../core/agent-loop.js";
|
|
12
|
+
import { generateId, now, toZoeError, } from "../../core/message-convert.js";
|
|
13
|
+
import { homedir } from 'os';
|
|
14
|
+
import * as path from 'path';
|
|
15
|
+
// ── Re-exports ───────────────────────────────────────────────────────────
|
|
16
|
+
export { createAgent } from "./agent.js";
|
|
17
|
+
export { tool, CORE_TOOLS, COMM_TOOLS, ADVANCED_TOOLS, ALL_TOOLS } from "./tools.js";
|
|
18
|
+
export { settings, SettingsError } from "./settings.js";
|
|
19
|
+
export { configureProviders, loadProviderConfig, provider } from "../../core/provider-resolver.js";
|
|
20
|
+
export { createSkillProviderSwitcher } from "../../core/skill-invoker.js";
|
|
21
|
+
// Re-export middleware pipeline
|
|
22
|
+
export { compose, loggingMiddleware, rateLimitMiddleware, authMiddleware, } from "../../core/index.js";
|
|
23
|
+
// Gateway (lazy — only loaded when used)
|
|
24
|
+
export const gateway = {
|
|
25
|
+
async createGateway(config, settingsAdapter) {
|
|
26
|
+
const { createGateway } = await import('../../gateway/index.js');
|
|
27
|
+
const { GatewaySettingsAdapter: Adapter } = await import('../../gateway/settings-adapter.js');
|
|
28
|
+
const adapter = settingsAdapter ?? new Adapter(process.env.ZOE_GATEWAY_DIR ?? path.join(homedir(), '.zoe'));
|
|
29
|
+
if (!settingsAdapter)
|
|
30
|
+
await adapter.initialize();
|
|
31
|
+
return createGateway(config, adapter);
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
export { createPersistenceBackend, registerBackend, createSessionStore, createMemoryStore, } from "../../core/session-store.js";
|
|
35
|
+
// ── generateText ─────────────────────────────────────────────────────────
|
|
36
|
+
/**
|
|
37
|
+
* Run a one-shot agent loop and return the structured result.
|
|
38
|
+
*
|
|
39
|
+
* Creates fresh state for each call (stateless). Handles tool calls
|
|
40
|
+
* automatically until the provider returns no more tool calls or
|
|
41
|
+
* `maxSteps` is reached.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* const result = await generateText("What is the weather in SF?", {
|
|
46
|
+
* tools: ["web_search"],
|
|
47
|
+
* maxSteps: 5,
|
|
48
|
+
* });
|
|
49
|
+
* console.log(result.text);
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export async function generateText(prompt, options) {
|
|
53
|
+
const opts = options ?? {};
|
|
54
|
+
const maxSteps = opts.maxSteps ?? 10;
|
|
55
|
+
// Resolve provider
|
|
56
|
+
const { provider: llmProvider, model } = await getProvider(opts.provider, opts.model);
|
|
57
|
+
// Resolve tools
|
|
58
|
+
const toolDefs = opts.tools ? resolveTools(opts.tools) : getAllToolDefinitions();
|
|
59
|
+
// Hooks
|
|
60
|
+
const hooks = createHookExecutor(opts.hooks);
|
|
61
|
+
// Build message list
|
|
62
|
+
const messages = [];
|
|
63
|
+
messages.push({
|
|
64
|
+
id: generateId(),
|
|
65
|
+
role: "user",
|
|
66
|
+
content: prompt,
|
|
67
|
+
timestamp: now(),
|
|
68
|
+
});
|
|
69
|
+
// Run the agent loop
|
|
70
|
+
const result = await runAgentLoop({
|
|
71
|
+
provider: llmProvider,
|
|
72
|
+
model,
|
|
73
|
+
messages,
|
|
74
|
+
toolDefs,
|
|
75
|
+
systemPrompt: opts.systemPrompt,
|
|
76
|
+
maxSteps,
|
|
77
|
+
hooks,
|
|
78
|
+
signal: opts.signal,
|
|
79
|
+
config: opts.config,
|
|
80
|
+
metadata: opts.metadata,
|
|
81
|
+
middleware: opts.middleware,
|
|
82
|
+
approveTool: opts.approveTool,
|
|
83
|
+
permissionLevel: opts.permissionLevel,
|
|
84
|
+
});
|
|
85
|
+
// Get the final text
|
|
86
|
+
const lastAssistant = [...result.messages]
|
|
87
|
+
.reverse()
|
|
88
|
+
.find((m) => m.role === "assistant" && m.content);
|
|
89
|
+
const text = lastAssistant?.content ?? "";
|
|
90
|
+
const genResult = {
|
|
91
|
+
text,
|
|
92
|
+
steps: result.steps,
|
|
93
|
+
toolCalls: result.toolCalls,
|
|
94
|
+
usage: result.usage,
|
|
95
|
+
finishReason: result.finishReason,
|
|
96
|
+
messages: result.messages,
|
|
97
|
+
};
|
|
98
|
+
await hooks.onFinish(genResult);
|
|
99
|
+
return genResult;
|
|
100
|
+
}
|
|
101
|
+
// ── streamText ───────────────────────────────────────────────────────────
|
|
102
|
+
/**
|
|
103
|
+
* Run a one-shot agent loop with streaming callbacks.
|
|
104
|
+
*
|
|
105
|
+
* Returns AsyncIterables for text and steps, plus `toResponse()` and
|
|
106
|
+
* `toSSEStream()` for HTTP server integration.
|
|
107
|
+
*
|
|
108
|
+
* Note: The current provider.chat() API returns full responses (not deltas),
|
|
109
|
+
* so onText receives the complete text at once. Future versions will integrate
|
|
110
|
+
* with provider-level streaming.
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```ts
|
|
114
|
+
* const stream = await streamText("Explain quantum computing", {
|
|
115
|
+
* onText: (delta) => process.stdout.write(delta),
|
|
116
|
+
* });
|
|
117
|
+
* const finalText = await stream.fullText;
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
export async function streamText(prompt, options) {
|
|
121
|
+
const opts = options ?? {};
|
|
122
|
+
const maxSteps = opts.maxSteps ?? 10;
|
|
123
|
+
// Resolve provider
|
|
124
|
+
const { provider: llmProvider, model } = await getProvider(opts.provider, opts.model);
|
|
125
|
+
// Resolve tools
|
|
126
|
+
const toolDefs = opts.tools ? resolveTools(opts.tools) : getAllToolDefinitions();
|
|
127
|
+
// Hooks — merge stream-level callbacks with any base hooks
|
|
128
|
+
const mergedHooks = { ...opts.hooks };
|
|
129
|
+
const hooks = createHookExecutor(mergedHooks);
|
|
130
|
+
// Build message list
|
|
131
|
+
const messages = [];
|
|
132
|
+
messages.push({
|
|
133
|
+
id: generateId(),
|
|
134
|
+
role: "user",
|
|
135
|
+
content: prompt,
|
|
136
|
+
timestamp: now(),
|
|
137
|
+
});
|
|
138
|
+
// Abort controller
|
|
139
|
+
const abortController = new AbortController();
|
|
140
|
+
// Stream manager handles queues, async iterables, and SSE
|
|
141
|
+
const stream = new StreamManager();
|
|
142
|
+
// Run loop in background
|
|
143
|
+
(async () => {
|
|
144
|
+
try {
|
|
145
|
+
const result = await runAgentLoop({
|
|
146
|
+
provider: llmProvider,
|
|
147
|
+
model,
|
|
148
|
+
messages,
|
|
149
|
+
toolDefs,
|
|
150
|
+
systemPrompt: opts.systemPrompt,
|
|
151
|
+
maxSteps,
|
|
152
|
+
hooks,
|
|
153
|
+
signal: abortController.signal,
|
|
154
|
+
config: opts.config,
|
|
155
|
+
metadata: opts.metadata,
|
|
156
|
+
middleware: opts.middleware,
|
|
157
|
+
approveTool: opts.approveTool,
|
|
158
|
+
permissionLevel: opts.permissionLevel,
|
|
159
|
+
onStep: (step) => {
|
|
160
|
+
if (opts.onStep)
|
|
161
|
+
opts.onStep(step);
|
|
162
|
+
if (step.type === "text" && step.content) {
|
|
163
|
+
if (opts.onText)
|
|
164
|
+
opts.onText(step.content);
|
|
165
|
+
stream.enqueueText(step.content);
|
|
166
|
+
}
|
|
167
|
+
if (step.type === "tool_call" && step.toolCall) {
|
|
168
|
+
if (opts.onToolCall) {
|
|
169
|
+
opts.onToolCall({ name: step.toolCall.name, args: step.toolCall.args, callId: step.toolCall.id });
|
|
170
|
+
}
|
|
171
|
+
if (opts.onToolResult) {
|
|
172
|
+
opts.onToolResult({ callId: step.toolCall.id, output: step.toolCall.result, success: true });
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
stream.enqueueStep(step);
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
// fullText: join all text deltas that were enqueued
|
|
179
|
+
const allText = result.steps
|
|
180
|
+
.filter((s) => s.type === "text")
|
|
181
|
+
.map((s) => s.content ?? "")
|
|
182
|
+
.join("");
|
|
183
|
+
stream.resolveText(allText);
|
|
184
|
+
stream.resolveUsage(result.usage);
|
|
185
|
+
stream.resolveFinish(result.finishReason);
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
const zoeErr = toZoeError(err, "PROVIDER_ERROR");
|
|
189
|
+
if (opts.onError)
|
|
190
|
+
opts.onError(zoeErr);
|
|
191
|
+
stream.resolveText("");
|
|
192
|
+
stream.resolveUsage({ promptTokens: 0, completionTokens: 0, totalTokens: 0, cost: 0 });
|
|
193
|
+
stream.resolveFinish("error");
|
|
194
|
+
}
|
|
195
|
+
finally {
|
|
196
|
+
stream.complete();
|
|
197
|
+
}
|
|
198
|
+
})();
|
|
199
|
+
return {
|
|
200
|
+
textStream: stream.textStream,
|
|
201
|
+
steps: stream.stepsStream,
|
|
202
|
+
fullText: stream.fullText,
|
|
203
|
+
usage: stream.usage,
|
|
204
|
+
finishReason: stream.finishReason,
|
|
205
|
+
abort: () => abortController.abort(),
|
|
206
|
+
toResponse: () => stream.toResponse(),
|
|
207
|
+
toSSEStream: () => stream.toSSEStream(),
|
|
208
|
+
};
|
|
209
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zoe SDK — Settings Facade
|
|
3
|
+
*
|
|
4
|
+
* Wraps SettingsManager for SDK consumers.
|
|
5
|
+
* Import via `import { settings } from 'zoe-agent'`.
|
|
6
|
+
*/
|
|
7
|
+
import { SettingsError, SettingValue, SettingEntry } from '../../core/settings-manager.js';
|
|
8
|
+
export declare const settings: {
|
|
9
|
+
get(dotKey: string): SettingValue;
|
|
10
|
+
set(dotKey: string, value: string): Promise<void>;
|
|
11
|
+
apply(updates: Record<string, string>): Promise<void>;
|
|
12
|
+
list(): SettingEntry[];
|
|
13
|
+
listByCategory(): Record<string, SettingEntry[]>;
|
|
14
|
+
onChange(callback: (changedKeys: string[]) => void): () => void;
|
|
15
|
+
reset(dotKey: string): Promise<void>;
|
|
16
|
+
resetAll(): Promise<void>;
|
|
17
|
+
};
|
|
18
|
+
export { SettingsError };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zoe SDK — Settings Facade
|
|
3
|
+
*
|
|
4
|
+
* Wraps SettingsManager for SDK consumers.
|
|
5
|
+
* Import via `import { settings } from 'zoe-agent'`.
|
|
6
|
+
*/
|
|
7
|
+
import { SettingsManager, SettingsError, } from '../../core/settings-manager.js';
|
|
8
|
+
import { loadMergedConfig, loadJsonConfig, getConfigPaths, applyEnvOverrides, } from '../../core/config.js';
|
|
9
|
+
// ── Singleton ─────────────────────────────────────────────────────────────
|
|
10
|
+
let manager = null;
|
|
11
|
+
function getManager() {
|
|
12
|
+
if (!manager) {
|
|
13
|
+
const config = applyEnvOverrides(loadMergedConfig());
|
|
14
|
+
const paths = getConfigPaths();
|
|
15
|
+
const projectResult = loadJsonConfig(paths.local);
|
|
16
|
+
const globalResult = loadJsonConfig(paths.global);
|
|
17
|
+
manager = new SettingsManager({
|
|
18
|
+
config,
|
|
19
|
+
projectConfigPath: paths.local,
|
|
20
|
+
globalConfigPath: paths.global,
|
|
21
|
+
projectConfig: projectResult.config,
|
|
22
|
+
globalConfig: globalResult.config,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
return manager;
|
|
26
|
+
}
|
|
27
|
+
// ── Public API ────────────────────────────────────────────────────────────
|
|
28
|
+
export const settings = {
|
|
29
|
+
get(dotKey) {
|
|
30
|
+
return getManager().get(dotKey);
|
|
31
|
+
},
|
|
32
|
+
async set(dotKey, value) {
|
|
33
|
+
return getManager().set(dotKey, value);
|
|
34
|
+
},
|
|
35
|
+
async apply(updates) {
|
|
36
|
+
const m = getManager();
|
|
37
|
+
for (const [key, value] of Object.entries(updates)) {
|
|
38
|
+
await m.set(key, value);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
list() {
|
|
42
|
+
return getManager().list();
|
|
43
|
+
},
|
|
44
|
+
listByCategory() {
|
|
45
|
+
return getManager().listByCategory();
|
|
46
|
+
},
|
|
47
|
+
onChange(callback) {
|
|
48
|
+
return getManager().onChange(callback);
|
|
49
|
+
},
|
|
50
|
+
async reset(dotKey) {
|
|
51
|
+
return getManager().reset(dotKey);
|
|
52
|
+
},
|
|
53
|
+
async resetAll() {
|
|
54
|
+
return getManager().resetAll();
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
export { SettingsError };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zoe SDK — Tool utilities (re-export layer)
|
|
3
|
+
*
|
|
4
|
+
* All tool registry, resolution, and factory logic lives in core/tool-executor.
|
|
5
|
+
* This file re-exports for backward compatibility.
|
|
6
|
+
*/
|
|
7
|
+
export { CORE_TOOLS, COMM_TOOLS, ADVANCED_TOOLS, ALL_TOOLS, tool, resolveTools, getToolGroup, registerTool, executeTool, getAllToolDefinitions, } from "../../core/tool-executor.js";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zoe SDK — Tool utilities (re-export layer)
|
|
3
|
+
*
|
|
4
|
+
* All tool registry, resolution, and factory logic lives in core/tool-executor.
|
|
5
|
+
* This file re-exports for backward compatibility.
|
|
6
|
+
*/
|
|
7
|
+
export {
|
|
8
|
+
// Tool group constants
|
|
9
|
+
CORE_TOOLS, COMM_TOOLS, ADVANCED_TOOLS, ALL_TOOLS,
|
|
10
|
+
// Factory and resolution
|
|
11
|
+
tool, resolveTools, getToolGroup,
|
|
12
|
+
// Registry and execution
|
|
13
|
+
registerTool, executeTool, getAllToolDefinitions, } from "../../core/tool-executor.js";
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zoe Server — API Key Authentication
|
|
3
|
+
*
|
|
4
|
+
* Generates, validates, and manages API keys for server access.
|
|
5
|
+
* Keys are stored in ~/.zoe/server-keys.json with associated scopes.
|
|
6
|
+
*/
|
|
7
|
+
import type { IncomingMessage } from "http";
|
|
8
|
+
export type KeyScope = "agent:run" | "agent:read" | "admin";
|
|
9
|
+
export interface ApiKeyEntry {
|
|
10
|
+
key: string;
|
|
11
|
+
scopes: KeyScope[];
|
|
12
|
+
created: string;
|
|
13
|
+
label: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Generate a new API key with the format `sk_zoe_{random}`.
|
|
17
|
+
* Optionally persist it to the key store file.
|
|
18
|
+
*/
|
|
19
|
+
export declare function generateApiKey(scopes?: KeyScope[], options?: {
|
|
20
|
+
label?: string;
|
|
21
|
+
filePath?: string;
|
|
22
|
+
}): ApiKeyEntry;
|
|
23
|
+
/**
|
|
24
|
+
* Validate an API key string against the stored keys.
|
|
25
|
+
* Returns the matching entry if valid, or null if not found.
|
|
26
|
+
*/
|
|
27
|
+
export declare function validateApiKey(key: string, options?: {
|
|
28
|
+
filePath?: string;
|
|
29
|
+
}): ApiKeyEntry | null;
|
|
30
|
+
/**
|
|
31
|
+
* Extract and validate an API key from an incoming HTTP request.
|
|
32
|
+
*
|
|
33
|
+
* For REST requests: checks `X-Zoe-API-Key` header first,
|
|
34
|
+
* then `Authorization: Bearer sk_zoe_...`.
|
|
35
|
+
* For WebSocket upgrades: checks the `token` query parameter.
|
|
36
|
+
*
|
|
37
|
+
* Returns the ApiKeyEntry if valid, or null if authentication fails.
|
|
38
|
+
*/
|
|
39
|
+
export declare function authMiddleware(req: IncomingMessage): ApiKeyEntry | null;
|
|
40
|
+
/**
|
|
41
|
+
* Load all API keys from the key store file.
|
|
42
|
+
* Returns an array of ApiKeyEntry objects.
|
|
43
|
+
*/
|
|
44
|
+
export declare function loadApiKeys(filePath?: string): ApiKeyEntry[];
|
|
45
|
+
/**
|
|
46
|
+
* Delete an API key from the store.
|
|
47
|
+
* Returns true if the key was found and removed.
|
|
48
|
+
*/
|
|
49
|
+
export declare function revokeApiKey(key: string, filePath?: string): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Check whether a given key entry has a specific scope.
|
|
52
|
+
*/
|
|
53
|
+
export declare function hasScope(entry: ApiKeyEntry, scope: KeyScope): boolean;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zoe Server — API Key Authentication
|
|
3
|
+
*
|
|
4
|
+
* Generates, validates, and manages API keys for server access.
|
|
5
|
+
* Keys are stored in ~/.zoe/server-keys.json with associated scopes.
|
|
6
|
+
*/
|
|
7
|
+
import * as crypto from "crypto";
|
|
8
|
+
import * as fs from "fs";
|
|
9
|
+
import * as path from "path";
|
|
10
|
+
import * as os from "os";
|
|
11
|
+
// ── Defaults ───────────────────────────────────────────────────────────
|
|
12
|
+
const DEFAULT_KEY_PATH = path.join(os.homedir(), ".zoe", "server-keys.json");
|
|
13
|
+
// ── In-memory cache ────────────────────────────────────────────────────
|
|
14
|
+
let cachedKeys = null;
|
|
15
|
+
let cacheMtimeMs = 0;
|
|
16
|
+
// ── Key store I/O ──────────────────────────────────────────────────────
|
|
17
|
+
function readStore(filePath) {
|
|
18
|
+
try {
|
|
19
|
+
const raw = fs.readFileSync(filePath, "utf-8");
|
|
20
|
+
return JSON.parse(raw);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return { keys: [] };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function writeStore(store, filePath) {
|
|
27
|
+
const dir = path.dirname(filePath);
|
|
28
|
+
if (!fs.existsSync(dir)) {
|
|
29
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
30
|
+
}
|
|
31
|
+
fs.writeFileSync(filePath, JSON.stringify(store, null, 2), {
|
|
32
|
+
mode: 0o600,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
// ── Cache helpers ──────────────────────────────────────────────────────
|
|
36
|
+
function invalidateCache() {
|
|
37
|
+
cachedKeys = null;
|
|
38
|
+
cacheMtimeMs = 0;
|
|
39
|
+
}
|
|
40
|
+
function loadCache(filePath) {
|
|
41
|
+
try {
|
|
42
|
+
const stat = fs.statSync(filePath);
|
|
43
|
+
if (cachedKeys && stat.mtimeMs === cacheMtimeMs) {
|
|
44
|
+
return cachedKeys;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// File may not exist yet — rebuild cache
|
|
49
|
+
}
|
|
50
|
+
const store = readStore(filePath);
|
|
51
|
+
const map = new Map();
|
|
52
|
+
for (const entry of store.keys) {
|
|
53
|
+
map.set(entry.key, entry);
|
|
54
|
+
}
|
|
55
|
+
cachedKeys = map;
|
|
56
|
+
try {
|
|
57
|
+
cacheMtimeMs = fs.statSync(filePath).mtimeMs;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
cacheMtimeMs = 0;
|
|
61
|
+
}
|
|
62
|
+
return map;
|
|
63
|
+
}
|
|
64
|
+
// ── Public API ─────────────────────────────────────────────────────────
|
|
65
|
+
/**
|
|
66
|
+
* Generate a new API key with the format `sk_zoe_{random}`.
|
|
67
|
+
* Optionally persist it to the key store file.
|
|
68
|
+
*/
|
|
69
|
+
export function generateApiKey(scopes = ["agent:run"], options) {
|
|
70
|
+
const random = crypto.randomBytes(32).toString("hex");
|
|
71
|
+
const key = `sk_zoe_${random}`;
|
|
72
|
+
const entry = {
|
|
73
|
+
key,
|
|
74
|
+
scopes,
|
|
75
|
+
created: new Date().toISOString(),
|
|
76
|
+
label: options?.label ?? "generated",
|
|
77
|
+
};
|
|
78
|
+
// Persist to disk
|
|
79
|
+
const filePath = options?.filePath ?? DEFAULT_KEY_PATH;
|
|
80
|
+
const store = readStore(filePath);
|
|
81
|
+
store.keys.push(entry);
|
|
82
|
+
writeStore(store, filePath);
|
|
83
|
+
invalidateCache();
|
|
84
|
+
return entry;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Validate an API key string against the stored keys.
|
|
88
|
+
* Returns the matching entry if valid, or null if not found.
|
|
89
|
+
*/
|
|
90
|
+
export function validateApiKey(key, options) {
|
|
91
|
+
if (!key || !key.startsWith("sk_zoe_")) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
const filePath = options?.filePath ?? DEFAULT_KEY_PATH;
|
|
95
|
+
const cache = loadCache(filePath);
|
|
96
|
+
return cache.get(key) ?? null;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Extract and validate an API key from an incoming HTTP request.
|
|
100
|
+
*
|
|
101
|
+
* For REST requests: checks `X-Zoe-API-Key` header first,
|
|
102
|
+
* then `Authorization: Bearer sk_zoe_...`.
|
|
103
|
+
* For WebSocket upgrades: checks the `token` query parameter.
|
|
104
|
+
*
|
|
105
|
+
* Returns the ApiKeyEntry if valid, or null if authentication fails.
|
|
106
|
+
*/
|
|
107
|
+
export function authMiddleware(req) {
|
|
108
|
+
let key;
|
|
109
|
+
// 1. Check X-Zoe-API-Key header
|
|
110
|
+
key = req.headers["x-zoe-api-key"];
|
|
111
|
+
// 2. Check Authorization: Bearer sk_zoe_...
|
|
112
|
+
if (!key) {
|
|
113
|
+
const auth = req.headers.authorization;
|
|
114
|
+
if (auth?.startsWith("Bearer ")) {
|
|
115
|
+
const token = auth.slice(7).trim();
|
|
116
|
+
if (token.startsWith("sk_zoe_")) {
|
|
117
|
+
key = token;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// 3. Check query parameter (for WebSocket upgrades)
|
|
122
|
+
if (!key && req.url) {
|
|
123
|
+
try {
|
|
124
|
+
const url = new URL(req.url, `http://${req.headers.host ?? "localhost"}`);
|
|
125
|
+
const tokenParam = url.searchParams.get("token");
|
|
126
|
+
if (tokenParam?.startsWith("sk_zoe_")) {
|
|
127
|
+
key = tokenParam;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
// Malformed URL — ignore
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (!key) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
return validateApiKey(key);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Load all API keys from the key store file.
|
|
141
|
+
* Returns an array of ApiKeyEntry objects.
|
|
142
|
+
*/
|
|
143
|
+
export function loadApiKeys(filePath) {
|
|
144
|
+
const resolved = filePath ?? DEFAULT_KEY_PATH;
|
|
145
|
+
const store = readStore(resolved);
|
|
146
|
+
return store.keys;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Delete an API key from the store.
|
|
150
|
+
* Returns true if the key was found and removed.
|
|
151
|
+
*/
|
|
152
|
+
export function revokeApiKey(key, filePath) {
|
|
153
|
+
const resolved = filePath ?? DEFAULT_KEY_PATH;
|
|
154
|
+
const store = readStore(resolved);
|
|
155
|
+
const index = store.keys.findIndex((e) => e.key === key);
|
|
156
|
+
if (index === -1)
|
|
157
|
+
return false;
|
|
158
|
+
store.keys.splice(index, 1);
|
|
159
|
+
writeStore(store, resolved);
|
|
160
|
+
invalidateCache();
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Check whether a given key entry has a specific scope.
|
|
165
|
+
*/
|
|
166
|
+
export function hasScope(entry, scope) {
|
|
167
|
+
return entry.scopes.includes(scope);
|
|
168
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zoe Remote Server — Entry Point
|
|
3
|
+
*
|
|
4
|
+
* Creates an HTTP server with REST endpoints and WebSocket support
|
|
5
|
+
* for real-time streaming conversations with LLM providers.
|
|
6
|
+
*
|
|
7
|
+
* Default port: 7337
|
|
8
|
+
*/
|
|
9
|
+
import * as http from "http";
|
|
10
|
+
import type { PermissionLevel } from "../../core/types.js";
|
|
11
|
+
export interface ServerOptions {
|
|
12
|
+
/** Port to listen on (default: ZOE_PORT, PORT, or 7337) */
|
|
13
|
+
port?: number;
|
|
14
|
+
/** Host to bind to (default: "0.0.0.0") */
|
|
15
|
+
host?: string;
|
|
16
|
+
/** Enable CORS headers (default: true) */
|
|
17
|
+
cors?: boolean;
|
|
18
|
+
/** Session TTL in seconds (default: 86400 = 24 hours) */
|
|
19
|
+
sessionTTL?: number;
|
|
20
|
+
/** Default permission level for REST endpoints (default: "moderate") */
|
|
21
|
+
permissionLevel?: PermissionLevel;
|
|
22
|
+
/** Maximum permission level clients can request (caps WebSocket messages) */
|
|
23
|
+
maxPermissionLevel?: PermissionLevel;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Initialize the skill registry and cache the skill metadata list.
|
|
27
|
+
* Called once during server startup.
|
|
28
|
+
*/
|
|
29
|
+
export declare function initializeSkills(): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Create and return the Zoe HTTP server (not yet listening).
|
|
32
|
+
*
|
|
33
|
+
* This sets up REST endpoints, WebSocket upgrade handling,
|
|
34
|
+
* session management, and CORS support.
|
|
35
|
+
*/
|
|
36
|
+
export declare function createServer(options?: ServerOptions): Promise<http.Server>;
|
|
37
|
+
/**
|
|
38
|
+
* Create and start listening. Returns the running server.
|
|
39
|
+
*/
|
|
40
|
+
export declare function startServer(options?: ServerOptions): Promise<http.Server>;
|