agent-accelerator 0.1.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.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1220 -0
  3. package/SYSTEM_PROMPT.md +14 -0
  4. package/SYSTEM_PROMPT_AGENT.md +34 -0
  5. package/SYSTEM_PROMPT_TOOLS.md +9 -0
  6. package/bunfig.toml +2 -0
  7. package/package.json +59 -0
  8. package/src/agent/agent.ts +615 -0
  9. package/src/agent/context.ts +161 -0
  10. package/src/agent/delegation.ts +481 -0
  11. package/src/agent/loop.ts +569 -0
  12. package/src/agent/subagent.ts +83 -0
  13. package/src/ai-sdk/converters.ts +342 -0
  14. package/src/ai-sdk/errors.ts +122 -0
  15. package/src/ai-sdk/executor.ts +454 -0
  16. package/src/ai-sdk/index.ts +55 -0
  17. package/src/ai-sdk/model-provider.ts +303 -0
  18. package/src/ai-sdk/options.ts +306 -0
  19. package/src/ai-sdk/provider.ts +415 -0
  20. package/src/ai-sdk/registry.ts +416 -0
  21. package/src/data/README.md +84 -0
  22. package/src/index.ts +190 -0
  23. package/src/models/catalog-cache.ts +273 -0
  24. package/src/models/catalog.ts +503 -0
  25. package/src/streaming/event-stream.ts +211 -0
  26. package/src/streaming/sse-parser.ts +97 -0
  27. package/src/tokens/counter.ts +136 -0
  28. package/src/tools/executor.ts +365 -0
  29. package/src/tools/schema.ts +221 -0
  30. package/src/tools/tool.ts +101 -0
  31. package/src/types/agent.ts +87 -0
  32. package/src/types/core.ts +86 -0
  33. package/src/types/message.ts +115 -0
  34. package/src/types/model.ts +212 -0
  35. package/src/types/provider-payloads.ts +434 -0
  36. package/src/types/response.ts +158 -0
  37. package/src/types/tool.ts +61 -0
  38. package/src/utils/base64.ts +27 -0
  39. package/src/utils/cache.ts +146 -0
  40. package/src/utils/env.ts +78 -0
  41. package/src/utils/headers.ts +110 -0
  42. package/src/utils/media.ts +137 -0
  43. package/src/utils/serialization.ts +91 -0
  44. package/src/utils/session.ts +26 -0
  45. package/src/utils/thought-signature.ts +27 -0
  46. package/tsconfig.json +31 -0
@@ -0,0 +1,87 @@
1
+ import type { ProviderId, ModelSpec } from "./model.ts";
2
+ import type { ToolDefinition } from "./tool.ts";
3
+ import type {
4
+ ThinkingLevel,
5
+ CacheConfig,
6
+ ServiceTier,
7
+ } from "./core.ts";
8
+ import type { ModelProviderInstance } from "../ai-sdk/registry.ts";
9
+ import type { Agent } from "../agent/agent.ts";
10
+
11
+ /** Configuration used to construct an {@link Agent}. */
12
+ export interface AgentConfig {
13
+ /** Display name used in tool and sub-agent metadata. */
14
+ name?: string;
15
+ /** Human-readable description used when this agent is delegated to. */
16
+ description?: string;
17
+ /** Stable system instructions for the agent. */
18
+ instructions?: string;
19
+ /** Model string (`provider/model`), catalog spec, or ModelProvider helper result. */
20
+ model?: string | ModelSpec | ModelProviderInstance;
21
+ /** Developer-only model for dynamically spawned sub-agents. Never exposed to the Main Agent LLM. */
22
+ subagentModel?: string | ModelSpec | ModelProviderInstance;
23
+ /** Dynamic sub-agent spawning policy. `subagents` lists pre-defined workers; this enables LLM-spawned stateless workers. */
24
+ dynamicSubagents?: DynamicSubagentsConfig;
25
+ /** Per-agent API key override. */
26
+ apiKey?: string;
27
+ /** Per-agent provider base URL override. */
28
+ baseUrl?: string;
29
+ /** Tools exposed to the model, keyed by name or supplied as an array. */
30
+ tools?: Record<string, ToolDefinition> | ToolDefinition[];
31
+ /** Requested reasoning level, validated against the model catalog. */
32
+ thinkingLevel?: ThinkingLevel;
33
+ /** Prompt-cache retention and session-affinity settings. */
34
+ cache?: CacheConfig;
35
+ /** Provider service tier, when supported. */
36
+ serviceTier?: ServiceTier;
37
+ /** Stable conversation/cache session ID. */
38
+ sessionId?: string;
39
+ /** Headers merged into every provider request. */
40
+ headers?: Record<string, string>;
41
+ /** Maximum model/tool turns per run. Defaults to 10. */
42
+ maxTurns?: number;
43
+ /** Fixed worker agents exposed as delegation tools. */
44
+ subagents?: (Agent | { name: string; description: string; agent: Agent })[];
45
+ /** Clears conversation state before and after every run. */
46
+ stateless?: boolean;
47
+ }
48
+
49
+ /** Developer-configured policy for LLM-spawned dynamic sub-agents. */
50
+ export interface DynamicSubagentsConfig {
51
+ /** Enables the automatic `spawn_subagents` tool. Defaults to true when the object is present. */
52
+ enabled?: boolean;
53
+ /** Developer-only worker model override. Never choosable by the Main Agent LLM. Falls back to top-level `subagentModel`, then `SUB_AGENT_MODEL` env, then the parent model. */
54
+ model?: string | ModelSpec | ModelProviderInstance;
55
+ /** Max workers the Main Agent may spawn in a single `spawn_subagents` call. Extras are trimmed safely. Defaults to 4. */
56
+ maxSpawn?: number;
57
+ /** Fixed reasoning level for all dynamic workers. The Main Agent cannot override it. Falls back to the parent level when omitted. */
58
+ thinkingLevel?: ThinkingLevel;
59
+ /** Tool pool available to dynamic workers. Workers receive zero tools unless the Main Agent grants a per-task `tools` subset by name. */
60
+ tools?: Record<string, ToolDefinition> | ToolDefinition[];
61
+ /** Per-worker timeout in ms. `0` (default) = no limit. `-1` = the Main Agent sets a per-task `timeoutMs`. `>0` = fixed timeout for every worker. */
62
+ timeout?: number;
63
+ }
64
+
65
+ /** Per-run overrides for {@link Agent.run}, {@link Agent.ask}, and {@link Agent.stream}. */
66
+ export interface AgentRunOptions {
67
+ /** Per-run reasoning-level override, validated against the selected model. */
68
+ thinkingLevel?: ThinkingLevel;
69
+ /** Return a streaming object instead of waiting for a final response. */
70
+ stream?: boolean;
71
+ /** Cancels provider, tool, and sub-agent work. */
72
+ signal?: AbortSignal;
73
+ /** Overrides the agent session for this run. */
74
+ sessionId?: string;
75
+ /** Context added only to this user turn, preserving the stable system prompt. */
76
+ additionalContext?: string;
77
+ /** Headers merged for this run only. */
78
+ headers?: Record<string, string>;
79
+ /** Called for each text delta as it streams (only when stream:true). */
80
+ onDelta?: (delta: string, event: import("./response.ts").StreamEvent) => void;
81
+ /** Called for each thinking/reasoning delta (only when stream:true). */
82
+ onThinkingDelta?: (delta: string, event: import("./response.ts").StreamEvent) => void;
83
+ /** Called for every stream event (text_delta, thinking_delta, tool_call_complete, subagent_complete, etc.). */
84
+ onEvent?: (event: import("./response.ts").StreamEvent) => void;
85
+ /** When true, wraps reasoning stream as <think>\n...\n</think>\n\n — no manual isThinking needed. */
86
+ wrapThinking?: boolean;
87
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Level-based reasoning — single flag for all levels (bloatfree)
3
+ */
4
+ /** Public reasoning control accepted by AgentConfig. */
5
+ export type ThinkingLevel =
6
+ | "none"
7
+ | "dynamic"
8
+ | "minimal"
9
+ | "low"
10
+ | "medium"
11
+ | "high"
12
+ | "xhigh";
13
+
14
+ // Internal normalized config (SDK-internal, not exposed as Agent flag)
15
+ /** Internal normalized reasoning configuration passed to providers. */
16
+ export interface ThinkingConfig {
17
+ enabled?: boolean;
18
+ level?: ThinkingLevel;
19
+ budgetTokens?: number;
20
+ budget?: number;
21
+ thinking_budget?: number;
22
+ includeThoughts?: boolean;
23
+ }
24
+
25
+ /**
26
+ * Cache retention:
27
+ * - "implicit": automatic prefix caching ($0.00 storage fee, session affinity preserved)
28
+ * - "short": 5 minutes explicit TTL
29
+ * - "medium": 1 hour explicit TTL
30
+ * - "long": 12 hours explicit TTL
31
+ * - undefined: no explicit caching enforced (implicit may still happen)
32
+ */
33
+ /** Prompt-cache retention policy. */
34
+ export type CacheRetention = "implicit" | "short" | "medium" | "long";
35
+
36
+ /** Prompt-cache IDs, retention, TTL, and session-affinity settings. */
37
+ export interface CacheConfig {
38
+ /**
39
+ * Retention duration:
40
+ * - "implicit": automatic prefix caching ($0.00 storage fee, no explicit cloud cache entities created)
41
+ * - "short": 5 minutes TTL
42
+ * - "medium": 1 hour TTL
43
+ * - "long": 12 hours TTL
44
+ * - undefined: no explicit caching enforced (implicit may still happen)
45
+ */
46
+ retention?: CacheRetention;
47
+ /**
48
+ * Explicit cache ID / reference if using pre-created context cache
49
+ */
50
+ cachedContentId?: string;
51
+ /**
52
+ * Session ID for cache affinity routing (e.g. x-session-id, x-opencode-session)
53
+ */
54
+ sessionId?: string;
55
+ /**
56
+ * Explicit TTL in seconds for created caches (overrides retention mapping)
57
+ */
58
+ ttlSeconds?: number;
59
+ }
60
+
61
+ /**
62
+ * Service tier controls — bloatfree: only flex / priority (standard is default, no flag needed)
63
+ */
64
+ /** Optional provider service-priority routing tier. */
65
+ export type ServiceTier = "flex" | "priority";
66
+
67
+ /**
68
+ * Token and cost usage — actual provider values, not heuristic
69
+ */
70
+ /** Normalized provider usage and optional calculated cost. */
71
+ export interface TokenUsage {
72
+ inputTokens: number;
73
+ outputTokens: number;
74
+ totalTokens: number;
75
+ cachedTokens?: number;
76
+ cacheReadTokens?: number;
77
+ cacheWriteTokens?: number;
78
+ thinkingTokens?: number;
79
+ cost?: {
80
+ inputCost?: number;
81
+ outputCost?: number;
82
+ cacheReadCost?: number;
83
+ cacheWriteCost?: number;
84
+ totalCost?: number;
85
+ };
86
+ }
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Multimodal input modalities supported: Text, Image, Audio, Video, File
3
+ */
4
+
5
+ /** Text content within a multimodal message. */
6
+ export interface TextPart {
7
+ type: "text";
8
+ text: string;
9
+ thoughtSignature?: string;
10
+ }
11
+
12
+ /** Image content accepted as a URL, data, path, or binary value. */
13
+ export interface ImagePart {
14
+ type: "image";
15
+ /**
16
+ * Raw base64 data, data URL (data:image/...;base64,...), remote URL (https://...), or local file path
17
+ */
18
+ image: string | Uint8Array | ArrayBuffer;
19
+ mimeType?: string;
20
+ }
21
+
22
+ /** Audio content accepted as a URL, data, path, or binary value. */
23
+ export interface AudioPart {
24
+ type: "audio";
25
+ /**
26
+ * Raw base64 data, data URL (data:audio/...;base64,...), remote URL, or local file path
27
+ */
28
+ audio: string | Uint8Array | ArrayBuffer;
29
+ mimeType?: string;
30
+ }
31
+
32
+ /** File/document content (PDF, text, etc.) accepted as a URL, data, path, or binary value. */
33
+ export interface FilePart {
34
+ type: "file";
35
+ /**
36
+ * Raw base64 data, data URL (data:...;base64,...), remote URL (https://...), or local file path
37
+ */
38
+ file: string | Uint8Array | ArrayBuffer;
39
+ mimeType?: string;
40
+ filename?: string;
41
+ }
42
+
43
+ /** Video content accepted as a URL, data, path, or binary value. */
44
+ export interface VideoPart {
45
+ type: "video";
46
+ /**
47
+ * Raw base64 data, data URL (data:video/...;base64,...), remote URL, or local file path
48
+ */
49
+ video: string | Uint8Array | ArrayBuffer;
50
+ mimeType?: string;
51
+ }
52
+
53
+ /** Assistant-generated structured tool invocation. */
54
+ export interface ToolCallPart {
55
+ type: "tool_call";
56
+ id: string;
57
+ name: string;
58
+ arguments: Record<string, unknown>;
59
+ /**
60
+ * Raw stringified arguments if available
61
+ */
62
+ rawArguments?: string;
63
+ /**
64
+ * Optional Gemini thought signature associated with this tool call
65
+ */
66
+ thoughtSignature?: string;
67
+ }
68
+
69
+ /** Tool execution result returned to the model context. */
70
+ export interface ToolResultPart {
71
+ type: "tool_result";
72
+ id: string;
73
+ name: string;
74
+ result: unknown;
75
+ isError?: boolean;
76
+ }
77
+
78
+ /** Provider reasoning/thinking content. */
79
+ export interface ThinkingPart {
80
+ type: "thinking";
81
+ thinking: string;
82
+ thoughtSignature?: string;
83
+ }
84
+
85
+ /** Any supported text, media, reasoning, tool-call, or tool-result part. */
86
+ export type ContentPart =
87
+ | TextPart
88
+ | ImagePart
89
+ | AudioPart
90
+ | VideoPart
91
+ | FilePart
92
+ | ToolCallPart
93
+ | ToolResultPart
94
+ | ThinkingPart;
95
+
96
+ export type MessageRole = "system" | "user" | "assistant" | "tool";
97
+
98
+ /** Normalized conversation message. */
99
+ export interface Message {
100
+ role: MessageRole;
101
+ content: string | ContentPart[];
102
+ name?: string;
103
+ thoughtSignature?: string;
104
+ }
105
+
106
+ /**
107
+ * Normalized input context passed to AI providers
108
+ */
109
+ /** Provider-neutral prompt context passed into generate/stream calls. */
110
+ export interface ProviderContext {
111
+ systemPrompt?: string;
112
+ messages: Message[];
113
+ tools?: Record<string, unknown>[];
114
+ cachedContentId?: string;
115
+ }
@@ -0,0 +1,212 @@
1
+ import type { ThinkingConfig, CacheConfig, ServiceTier, TokenUsage } from "./core.ts";
2
+ import type { ProviderContext, Message, ContentPart } from "./message.ts";
3
+ import type { StandardToolDeclaration, ToolCallRecord } from "./tool.ts";
4
+ import type { AssistantMessageEventStream } from "../streaming/event-stream.ts";
5
+
6
+ // ---------------------------------------------------------------------------
7
+ // Provider identity — battle-tested: matches models.dev provider keys
8
+ // Known first-class: google | opencode | openrouter, plus aliases. Allow string for future.
9
+ // ---------------------------------------------------------------------------
10
+ /** Supported provider IDs plus arbitrary custom prefixes. */
11
+ export type ProviderId = "google" | "opencode" | "opencode-go" | "openrouter" | "openai" | (string & {});
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // Raw models.dev shapes — battle-tested, 1:1 with https://models.dev/api.json
15
+ // ---------------------------------------------------------------------------
16
+ export interface ModelLimit {
17
+ /** Total context window (input + output). Canonical field: limit.context */
18
+ context: number;
19
+ /** Max output tokens. Canonical: limit.output */
20
+ output: number;
21
+ /** Optional extra limits (e.g. input) */
22
+ input?: number;
23
+ [k: string]: unknown;
24
+ }
25
+
26
+ export interface ModelCost {
27
+ input?: number; // $ per 1M input tokens
28
+ output?: number; // $ per 1M output tokens
29
+ cache_read?: number;
30
+ cache_write?: number;
31
+ // provider-specific: input_audio, etc.
32
+ input_audio?: number;
33
+ // tiered pricing when context > threshold
34
+ tiers?: Array<{
35
+ tier: { type: string; size: number };
36
+ input: number;
37
+ output: number;
38
+ cache_read?: number;
39
+ }>;
40
+ context_over_200k?: { input: number; output: number; cache_read: number };
41
+ [k: string]: unknown;
42
+ }
43
+
44
+ export interface ModelModalities {
45
+ input: Array<"text" | "image" | "audio" | "video" | "pdf">;
46
+ output: Array<"text" | "image" | "audio" | "video">;
47
+ }
48
+
49
+ export type ReasoningOption =
50
+ | { type: "toggle" }
51
+ | { type: "effort"; values: string[] }
52
+ | { type: "budget_tokens"; min: number; max: number };
53
+
54
+ export interface RawModelData {
55
+ id: string;
56
+ name: string;
57
+ description?: string;
58
+ family?: string;
59
+ attachment?: boolean;
60
+ reasoning?: boolean;
61
+ reasoning_options?: ReasoningOption[];
62
+ tool_call?: boolean;
63
+ structured_output?: boolean;
64
+ temperature?: boolean;
65
+ knowledge?: string;
66
+ release_date?: string;
67
+ last_updated?: string;
68
+ status?: string;
69
+ open_weights?: boolean;
70
+ modalities?: ModelModalities;
71
+ limit?: ModelLimit;
72
+ cost?: ModelCost;
73
+ provider?: { npm?: string; api?: string };
74
+ api?: string;
75
+ [k: string]: unknown;
76
+ }
77
+
78
+ // ---------------------------------------------------------------------------
79
+ // Capabilities — normalized, battle-tested from raw flags
80
+ // ---------------------------------------------------------------------------
81
+ export interface ModelCapabilities {
82
+ supportsThinking?: boolean;
83
+ supportsThinkingBudget?: boolean;
84
+ supportsThinkingLevel?: boolean;
85
+ supportsImplicitCaching?: boolean;
86
+ supportsExplicitCaching?: boolean;
87
+ supportsLongCacheRetention?: boolean;
88
+ supportsParallelToolCalls?: boolean;
89
+ supportsStreaming?: boolean;
90
+ modalities?: ("text" | "image" | "audio" | "video" | "pdf")[];
91
+ // derived
92
+ supportsReasoningToggle?: boolean;
93
+ supportsReasoningEffort?: boolean;
94
+ }
95
+
96
+ // ---------------------------------------------------------------------------
97
+ // Pricing — normalized per-1M
98
+ // ---------------------------------------------------------------------------
99
+ export interface ModelPricing {
100
+ inputPerMillion?: number;
101
+ outputPerMillion?: number;
102
+ cacheReadPerMillion?: number;
103
+ cacheWritePerMillion?: number;
104
+ inputAudioPerMillion?: number;
105
+ }
106
+
107
+ // ---------------------------------------------------------------------------
108
+ // ModelSpec — battle-tested, single source from models.dev
109
+ // Keep legacy aliases contextWindow/maxOutputTokens for BC, plus full raw.
110
+ // ---------------------------------------------------------------------------
111
+ /** Normalized model catalog entry used for routing, validation, and pricing. */
112
+ export interface ModelSpec {
113
+ id: string;
114
+ provider: ProviderId;
115
+ name: string;
116
+ description?: string;
117
+ family?: string;
118
+ api?: string; // agent-accel-style: openai-completions | openai-responses | anthropic-messages | google-generative-ai etc.
119
+ /** @deprecated alias for limit.context */
120
+ contextWindow: number;
121
+ /** @deprecated alias for limit.output */
122
+ maxOutputTokens: number;
123
+ // Full battle-tested fields (optional for BC with stale per-provider files, required when from catalog)
124
+ limit?: ModelLimit;
125
+ cost?: ModelCost;
126
+ modalities?: ModelModalities;
127
+ reasoning?: boolean;
128
+ reasoning_options?: ReasoningOption[];
129
+ tool_call?: boolean;
130
+ attachment?: boolean;
131
+ knowledge?: string;
132
+ release_date?: string;
133
+ last_updated?: string;
134
+ capabilities: ModelCapabilities;
135
+ pricing?: ModelPricing;
136
+ compat?: Record<string, unknown>;
137
+ // raw passthrough for advanced checks
138
+ raw?: RawModelData;
139
+ }
140
+
141
+ // ---------------------------------------------------------------------------
142
+ // Provider plumbing — unchanged API
143
+ // ---------------------------------------------------------------------------
144
+ /** Request controls passed from Agent to a provider implementation. */
145
+ export interface ProviderRequestOptions {
146
+ apiKey?: string;
147
+ baseUrl?: string;
148
+ headers?: Record<string, string>;
149
+ thinking?: ThinkingConfig;
150
+ cache?: CacheConfig;
151
+ serviceTier?: ServiceTier;
152
+ tools?: StandardToolDeclaration[];
153
+ toolChoice?: "auto" | "none" | "required" | { type: "function"; function: { name: string } };
154
+ signal?: AbortSignal;
155
+ sessionId?: string;
156
+ env?: Record<string, string>;
157
+ maxRetries?: number;
158
+ maxRetryDelayMs?: number;
159
+ }
160
+
161
+ /** Auditable request/response wire payload captured in AgentResponse. */
162
+ export interface ProviderRawData {
163
+ request: {
164
+ url: string;
165
+ method: string;
166
+ headers: Record<string, string>;
167
+ body: unknown;
168
+ };
169
+ response?: {
170
+ status: number;
171
+ statusText: string;
172
+ headers: Record<string, string>;
173
+ body: unknown;
174
+ };
175
+ }
176
+
177
+ /** Normalized single provider generation result. */
178
+ export interface ProviderGenerateResult {
179
+ text: string;
180
+ thinking?: string;
181
+ thoughtSignature?: string;
182
+ toolCalls?: ToolCallRecord[];
183
+ usage: TokenUsage;
184
+ finishReason?: string;
185
+ responseId?: string;
186
+ model: string;
187
+ provider: ProviderId;
188
+ raw: ProviderRawData;
189
+ durationMs: number;
190
+ }
191
+
192
+ /** Provider contract implemented by the AI-SDK transport layer. */
193
+ export interface Provider {
194
+ id: ProviderId;
195
+ name: string;
196
+ models: ModelSpec[];
197
+ getModel(modelId: string): ModelSpec | undefined;
198
+ generate(
199
+ model: string | ModelSpec,
200
+ context: ProviderContext,
201
+ options?: ProviderRequestOptions
202
+ ): Promise<ProviderGenerateResult>;
203
+ stream(
204
+ model: string | ModelSpec,
205
+ context: ProviderContext,
206
+ options?: ProviderRequestOptions
207
+ ): AssistantMessageEventStream;
208
+ countTokens(
209
+ model: string | ModelSpec,
210
+ context: ProviderContext
211
+ ): Promise<number>;
212
+ }