@pencil-agent/nano-pencil 2.0.0-beta.2 → 2.0.0-beta.3
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/dist/build-meta.json +3 -3
- package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-continuations.d.ts +17 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-continuations.js +60 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-stream-events.d.ts +19 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-stream-events.js +55 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-tool-results.d.ts +10 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-tool-results.js +137 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-tool-summaries.d.ts +22 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-tool-summaries.js +64 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop.d.ts +26 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop.js +913 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/agent-run-result.d.ts +9 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/agent-run-result.js +32 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/agent.d.ts +215 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/agent.js +522 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/errors.d.ts +62 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/errors.js +146 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/index.d.ts +14 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/index.js +19 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/proxy.d.ts +91 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/proxy.js +279 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/structured-adaptive-agent-loop.d.ts +15 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/structured-adaptive-agent-loop.js +625 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/structured-adaptive-streaming-tool-executor.d.ts +33 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/structured-adaptive-streaming-tool-executor.js +189 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/structured-adaptive-tool-orchestration.d.ts +35 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/structured-adaptive-tool-orchestration.js +319 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/types.d.ts +417 -0
- package/dist/node_modules/@pencil-agent/agent-core/dist/types.js +13 -0
- package/dist/node_modules/@pencil-agent/agent-core/package.json +28 -0
- package/dist/node_modules/@pencil-agent/ai/dist/api-registry.d.ts +27 -0
- package/dist/node_modules/@pencil-agent/ai/dist/api-registry.js +152 -0
- package/dist/node_modules/@pencil-agent/ai/dist/cli.d.ts +2 -0
- package/dist/node_modules/@pencil-agent/ai/dist/cli.js +121 -0
- package/dist/node_modules/@pencil-agent/ai/dist/config-path.d.ts +1 -0
- package/dist/node_modules/@pencil-agent/ai/dist/config-path.js +17 -0
- package/dist/node_modules/@pencil-agent/ai/dist/debug-logger.d.ts +94 -0
- package/dist/node_modules/@pencil-agent/ai/dist/debug-logger.js +218 -0
- package/dist/node_modules/@pencil-agent/ai/dist/env-api-keys.d.ts +8 -0
- package/dist/node_modules/@pencil-agent/ai/dist/env-api-keys.js +107 -0
- package/dist/node_modules/@pencil-agent/ai/dist/env.d.ts +7 -0
- package/dist/node_modules/@pencil-agent/ai/dist/env.js +7 -0
- package/dist/node_modules/@pencil-agent/ai/dist/events.d.ts +8 -0
- package/dist/node_modules/@pencil-agent/ai/dist/events.js +7 -0
- package/dist/node_modules/@pencil-agent/ai/dist/index.d.ts +27 -0
- package/dist/node_modules/@pencil-agent/ai/dist/index.js +20 -0
- package/dist/node_modules/@pencil-agent/ai/dist/json.d.ts +7 -0
- package/dist/node_modules/@pencil-agent/ai/dist/json.js +7 -0
- package/dist/node_modules/@pencil-agent/ai/dist/models.d.ts +31 -0
- package/dist/node_modules/@pencil-agent/ai/dist/models.generated.d.ts +15159 -0
- package/dist/node_modules/@pencil-agent/ai/dist/models.generated.js +14928 -0
- package/dist/node_modules/@pencil-agent/ai/dist/models.js +60 -0
- package/dist/node_modules/@pencil-agent/ai/dist/overflow.d.ts +7 -0
- package/dist/node_modules/@pencil-agent/ai/dist/overflow.js +7 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/amazon-bedrock.d.ts +20 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/amazon-bedrock.js +606 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/anthropic.d.ts +38 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/anthropic.js +737 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/azure-openai-responses.d.ts +21 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/azure-openai-responses.js +193 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/github-copilot-headers.d.ts +13 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/github-copilot-headers.js +34 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/google-gemini-cli.d.ts +79 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/google-gemini-cli.js +753 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/google-shared.d.ts +70 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/google-shared.js +311 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/google-vertex.d.ts +20 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/google-vertex.js +380 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/google.d.ts +18 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/google.js +360 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-codex-responses.d.ts +8 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-codex-responses.js +704 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-completions.d.ts +20 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-completions.js +870 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-responses-shared.d.ts +22 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-responses-shared.js +432 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-responses.d.ts +19 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-responses.js +207 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/register-builtins.d.ts +8 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/register-builtins.js +86 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/simple-options.d.ts +13 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/simple-options.js +40 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/transform-messages.d.ts +13 -0
- package/dist/node_modules/@pencil-agent/ai/dist/providers/transform-messages.js +175 -0
- package/dist/node_modules/@pencil-agent/ai/dist/registry.d.ts +8 -0
- package/dist/node_modules/@pencil-agent/ai/dist/registry.js +8 -0
- package/dist/node_modules/@pencil-agent/ai/dist/schema.d.ts +10 -0
- package/dist/node_modules/@pencil-agent/ai/dist/schema.js +9 -0
- package/dist/node_modules/@pencil-agent/ai/dist/stream.d.ts +25 -0
- package/dist/node_modules/@pencil-agent/ai/dist/stream.js +324 -0
- package/dist/node_modules/@pencil-agent/ai/dist/types.d.ts +306 -0
- package/dist/node_modules/@pencil-agent/ai/dist/types.js +7 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/event-stream-types.d.ts +12 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/event-stream-types.js +7 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/event-stream.d.ts +31 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/event-stream.js +98 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/http-proxy.d.ts +13 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/http-proxy.js +20 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/json-parse.d.ts +14 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/json-parse.js +34 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/anthropic.d.ts +22 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/anthropic.js +109 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/decode-credential.d.ts +12 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/decode-credential.js +25 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/github-copilot.d.ts +35 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/github-copilot.js +286 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/google-antigravity.d.ts +31 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/google-antigravity.js +378 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/google-gemini-cli.d.ts +31 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/google-gemini-cli.js +483 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/index.d.ts +60 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/index.js +131 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/openai-codex.d.ts +39 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/openai-codex.js +385 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/pkce.d.ts +18 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/pkce.js +36 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/types.d.ts +52 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/types.js +7 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/overflow.d.ts +57 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/overflow.js +120 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/sanitize-unicode.d.ts +16 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/sanitize-unicode.js +20 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/typebox-helpers.d.ts +22 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/typebox-helpers.js +26 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/validation.d.ts +23 -0
- package/dist/node_modules/@pencil-agent/ai/dist/utils/validation.js +78 -0
- package/dist/node_modules/@pencil-agent/ai/package.json +94 -0
- package/dist/node_modules/@pencil-agent/tui/dist/autocomplete.d.ts +62 -0
- package/dist/node_modules/@pencil-agent/tui/dist/autocomplete.js +624 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/box.d.ts +27 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/box.js +109 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/cancellable-loader.d.ts +27 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/cancellable-loader.js +40 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/editor.d.ts +218 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/editor.js +1697 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/image.d.ts +33 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/image.js +74 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/input.d.ts +42 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/input.js +438 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/loader.d.ts +26 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/loader.js +54 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/markdown.d.ts +100 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/markdown.js +634 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/select-list.d.ts +37 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/select-list.js +157 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/settings-list.d.ts +55 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/settings-list.js +190 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/spacer.d.ts +17 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/spacer.js +28 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/text.d.ts +24 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/text.js +94 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/truncated-text.d.ts +18 -0
- package/dist/node_modules/@pencil-agent/tui/dist/components/truncated-text.js +56 -0
- package/dist/node_modules/@pencil-agent/tui/dist/editor-component.d.ts +51 -0
- package/dist/node_modules/@pencil-agent/tui/dist/editor-component.js +7 -0
- package/dist/node_modules/@pencil-agent/tui/dist/fuzzy.d.ts +32 -0
- package/dist/node_modules/@pencil-agent/tui/dist/fuzzy.js +152 -0
- package/dist/node_modules/@pencil-agent/tui/dist/index.d.ts +28 -0
- package/dist/node_modules/@pencil-agent/tui/dist/index.js +37 -0
- package/dist/node_modules/@pencil-agent/tui/dist/keybindings.d.ts +44 -0
- package/dist/node_modules/@pencil-agent/tui/dist/keybindings.js +119 -0
- package/dist/node_modules/@pencil-agent/tui/dist/keys.d.ts +149 -0
- package/dist/node_modules/@pencil-agent/tui/dist/keys.js +948 -0
- package/dist/node_modules/@pencil-agent/tui/dist/kill-ring.d.ts +33 -0
- package/dist/node_modules/@pencil-agent/tui/dist/kill-ring.js +49 -0
- package/dist/node_modules/@pencil-agent/tui/dist/stdin-buffer.d.ts +38 -0
- package/dist/node_modules/@pencil-agent/tui/dist/stdin-buffer.js +307 -0
- package/dist/node_modules/@pencil-agent/tui/dist/terminal-image.d.ts +73 -0
- package/dist/node_modules/@pencil-agent/tui/dist/terminal-image.js +287 -0
- package/dist/node_modules/@pencil-agent/tui/dist/terminal.d.ts +86 -0
- package/dist/node_modules/@pencil-agent/tui/dist/terminal.js +266 -0
- package/dist/node_modules/@pencil-agent/tui/dist/tui.d.ts +219 -0
- package/dist/node_modules/@pencil-agent/tui/dist/tui.js +1001 -0
- package/dist/node_modules/@pencil-agent/tui/dist/undo-stack.d.ts +22 -0
- package/dist/node_modules/@pencil-agent/tui/dist/undo-stack.js +30 -0
- package/dist/node_modules/@pencil-agent/tui/dist/utils.d.ts +83 -0
- package/dist/node_modules/@pencil-agent/tui/dist/utils.js +811 -0
- package/dist/node_modules/@pencil-agent/tui/package.json +37 -0
- package/package.json +3 -2
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [WHO]: AgentError hierarchy — AgentError, NetworkError, ContextOverflowError, ToolExecutionError, ValidationError, ExtensionError
|
|
3
|
+
* [FROM]: No external dependencies
|
|
4
|
+
* [TO]: Consumed by agent-loop, agent, proxy, and downstream consumers
|
|
5
|
+
* [HERE]: core/lib/agent-core/src/errors.ts - unified error type system
|
|
6
|
+
*/
|
|
7
|
+
// =============================================================================
|
|
8
|
+
// Base Error
|
|
9
|
+
// =============================================================================
|
|
10
|
+
/**
|
|
11
|
+
* Base error class for all agent-related errors.
|
|
12
|
+
* Provides structured error info (code, retriable flag) for consistent handling.
|
|
13
|
+
*/
|
|
14
|
+
export class AgentError extends Error {
|
|
15
|
+
code;
|
|
16
|
+
retriable;
|
|
17
|
+
details;
|
|
18
|
+
constructor(message, code, retriable = false, details) {
|
|
19
|
+
super(message);
|
|
20
|
+
this.name = "AgentError";
|
|
21
|
+
this.code = code;
|
|
22
|
+
this.retriable = retriable;
|
|
23
|
+
this.details = details;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// =============================================================================
|
|
27
|
+
// Network Errors (retriable)
|
|
28
|
+
// =============================================================================
|
|
29
|
+
export class NetworkError extends AgentError {
|
|
30
|
+
statusCode;
|
|
31
|
+
constructor(message, statusCode, details) {
|
|
32
|
+
super(message, "NETWORK_ERROR", true, details);
|
|
33
|
+
this.name = "NetworkError";
|
|
34
|
+
this.statusCode = statusCode;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export class RateLimitError extends NetworkError {
|
|
38
|
+
retryAfterMs;
|
|
39
|
+
constructor(message, retryAfterMs) {
|
|
40
|
+
super(message, 429);
|
|
41
|
+
this.name = "RateLimitError";
|
|
42
|
+
this.retryAfterMs = retryAfterMs;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export class TimeoutError extends NetworkError {
|
|
46
|
+
constructor(message, details) {
|
|
47
|
+
super(message, undefined, details);
|
|
48
|
+
this.name = "TimeoutError";
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export class ConnectionError extends NetworkError {
|
|
52
|
+
constructor(message, details) {
|
|
53
|
+
super(message, undefined, details);
|
|
54
|
+
this.name = "ConnectionError";
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// =============================================================================
|
|
58
|
+
// Context Errors
|
|
59
|
+
// =============================================================================
|
|
60
|
+
export class ContextOverflowError extends AgentError {
|
|
61
|
+
estimatedTokens;
|
|
62
|
+
contextWindow;
|
|
63
|
+
constructor(message, estimatedTokens, contextWindow) {
|
|
64
|
+
super(message, "CONTEXT_OVERFLOW", false, { estimatedTokens, contextWindow });
|
|
65
|
+
this.name = "ContextOverflowError";
|
|
66
|
+
this.estimatedTokens = estimatedTokens;
|
|
67
|
+
this.contextWindow = contextWindow;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// =============================================================================
|
|
71
|
+
// Tool Errors
|
|
72
|
+
// =============================================================================
|
|
73
|
+
export class ToolExecutionError extends AgentError {
|
|
74
|
+
toolName;
|
|
75
|
+
toolCallId;
|
|
76
|
+
constructor(message, toolName, toolCallId) {
|
|
77
|
+
super(message, "TOOL_EXECUTION_ERROR", false, { toolName, toolCallId });
|
|
78
|
+
this.name = "ToolExecutionError";
|
|
79
|
+
this.toolName = toolName;
|
|
80
|
+
this.toolCallId = toolCallId;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
export class ToolTimeoutError extends ToolExecutionError {
|
|
84
|
+
constructor(toolName, toolCallId, timeoutMs) {
|
|
85
|
+
super(`Tool "${toolName}" timed out after ${timeoutMs}ms`, toolName, toolCallId);
|
|
86
|
+
this.name = "ToolTimeoutError";
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
export class ToolNotFoundError extends ToolExecutionError {
|
|
90
|
+
constructor(toolName) {
|
|
91
|
+
super(`Tool "${toolName}" not found`, toolName);
|
|
92
|
+
this.name = "ToolNotFoundError";
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// =============================================================================
|
|
96
|
+
// Validation Errors (non-retriable)
|
|
97
|
+
// =============================================================================
|
|
98
|
+
export class ValidationError extends AgentError {
|
|
99
|
+
constructor(message, details) {
|
|
100
|
+
super(message, "VALIDATION_ERROR", false, details);
|
|
101
|
+
this.name = "ValidationError";
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// =============================================================================
|
|
105
|
+
// Extension Errors (isolated — should not crash the agent)
|
|
106
|
+
// =============================================================================
|
|
107
|
+
export class ExtensionError extends AgentError {
|
|
108
|
+
extensionName;
|
|
109
|
+
constructor(message, extensionName) {
|
|
110
|
+
super(message, "EXTENSION_ERROR", false, { extensionName });
|
|
111
|
+
this.name = "ExtensionError";
|
|
112
|
+
this.extensionName = extensionName;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// =============================================================================
|
|
116
|
+
// Helpers
|
|
117
|
+
// =============================================================================
|
|
118
|
+
/** Type guard: is the error retriable? */
|
|
119
|
+
export function isRetriableError(error) {
|
|
120
|
+
return error instanceof AgentError && error.retriable;
|
|
121
|
+
}
|
|
122
|
+
/** Type guard: is this a context overflow error? */
|
|
123
|
+
export function isContextOverflowError(error) {
|
|
124
|
+
return error instanceof ContextOverflowError;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Classify an HTTP-like error (status code + message) into the appropriate AgentError subclass.
|
|
128
|
+
* Useful for normalizing raw provider errors into the typed hierarchy.
|
|
129
|
+
*/
|
|
130
|
+
export function classifyApiError(statusCode, message) {
|
|
131
|
+
if (statusCode === 429) {
|
|
132
|
+
const match = message.match(/retry[_-]after[:\s]+(\d+)/i);
|
|
133
|
+
const retryAfterMs = match ? parseInt(match[1], 10) * 1000 : undefined;
|
|
134
|
+
return new RateLimitError(message, retryAfterMs);
|
|
135
|
+
}
|
|
136
|
+
if (statusCode === 413 || (statusCode === 400 && /context|token|prompt.*too long|overflow/i.test(message))) {
|
|
137
|
+
return new ContextOverflowError(message);
|
|
138
|
+
}
|
|
139
|
+
if (statusCode !== undefined && statusCode >= 500) {
|
|
140
|
+
return new NetworkError(message, statusCode);
|
|
141
|
+
}
|
|
142
|
+
if (statusCode !== undefined && statusCode >= 400) {
|
|
143
|
+
return new ValidationError(message, { statusCode });
|
|
144
|
+
}
|
|
145
|
+
return new NetworkError(message, statusCode);
|
|
146
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [WHO]: agent-core barrel exports
|
|
3
|
+
* [FROM]: Depends on agent.js, agent-loop.js, structured-adaptive-agent-loop.js, structured-adaptive-tool-orchestration.js, structured-adaptive-streaming-tool-executor.js, proxy.js, types.js
|
|
4
|
+
* [TO]: Consumed by @pencil-agent/agent-core package consumers
|
|
5
|
+
* [HERE]: core/lib/agent-core/src/index.ts - agent-core entry point
|
|
6
|
+
*/
|
|
7
|
+
export * from "./agent.js";
|
|
8
|
+
export * from "./agent-loop.js";
|
|
9
|
+
export * from "./structured-adaptive-agent-loop.js";
|
|
10
|
+
export * from "./structured-adaptive-tool-orchestration.js";
|
|
11
|
+
export * from "./structured-adaptive-streaming-tool-executor.js";
|
|
12
|
+
export * from "./proxy.js";
|
|
13
|
+
export * from "./types.js";
|
|
14
|
+
export * from "./errors.js";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [WHO]: agent-core barrel exports
|
|
3
|
+
* [FROM]: Depends on agent.js, agent-loop.js, structured-adaptive-agent-loop.js, structured-adaptive-tool-orchestration.js, structured-adaptive-streaming-tool-executor.js, proxy.js, types.js
|
|
4
|
+
* [TO]: Consumed by @pencil-agent/agent-core package consumers
|
|
5
|
+
* [HERE]: core/lib/agent-core/src/index.ts - agent-core entry point
|
|
6
|
+
*/
|
|
7
|
+
// Core Agent
|
|
8
|
+
export * from "./agent.js";
|
|
9
|
+
// Loop functions
|
|
10
|
+
export * from "./agent-loop.js";
|
|
11
|
+
export * from "./structured-adaptive-agent-loop.js";
|
|
12
|
+
export * from "./structured-adaptive-tool-orchestration.js";
|
|
13
|
+
export * from "./structured-adaptive-streaming-tool-executor.js";
|
|
14
|
+
// Proxy utilities
|
|
15
|
+
export * from "./proxy.js";
|
|
16
|
+
// Types
|
|
17
|
+
export * from "./types.js";
|
|
18
|
+
// Errors
|
|
19
|
+
export * from "./errors.js";
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proxy stream function for apps that route LLM calls through a server.
|
|
3
|
+
* The server manages auth and proxies requests to LLM providers.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* [WHO]: ProxyStreamOptions, streamProxy
|
|
7
|
+
* [FROM]: No external dependencies
|
|
8
|
+
* [TO]: Consumed by core/lib/agent-core/src/index.ts
|
|
9
|
+
* [HERE]: core/lib/agent-core/src/proxy.ts -
|
|
10
|
+
*/
|
|
11
|
+
import { type AssistantMessage, type AssistantMessageEvent, type Context, type Model, type SimpleStreamOptions, type StopReason } from "@pencil-agent/ai/types";
|
|
12
|
+
import { EventStream } from "@pencil-agent/ai/events";
|
|
13
|
+
declare class ProxyMessageEventStream extends EventStream<AssistantMessageEvent, AssistantMessage> {
|
|
14
|
+
constructor();
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Proxy event types - server sends these with partial field stripped to reduce bandwidth.
|
|
18
|
+
*/
|
|
19
|
+
export type ProxyAssistantMessageEvent = {
|
|
20
|
+
type: "start";
|
|
21
|
+
} | {
|
|
22
|
+
type: "text_start";
|
|
23
|
+
contentIndex: number;
|
|
24
|
+
} | {
|
|
25
|
+
type: "text_delta";
|
|
26
|
+
contentIndex: number;
|
|
27
|
+
delta: string;
|
|
28
|
+
} | {
|
|
29
|
+
type: "text_end";
|
|
30
|
+
contentIndex: number;
|
|
31
|
+
contentSignature?: string;
|
|
32
|
+
} | {
|
|
33
|
+
type: "thinking_start";
|
|
34
|
+
contentIndex: number;
|
|
35
|
+
} | {
|
|
36
|
+
type: "thinking_delta";
|
|
37
|
+
contentIndex: number;
|
|
38
|
+
delta: string;
|
|
39
|
+
} | {
|
|
40
|
+
type: "thinking_end";
|
|
41
|
+
contentIndex: number;
|
|
42
|
+
contentSignature?: string;
|
|
43
|
+
} | {
|
|
44
|
+
type: "toolcall_start";
|
|
45
|
+
contentIndex: number;
|
|
46
|
+
id: string;
|
|
47
|
+
toolName: string;
|
|
48
|
+
} | {
|
|
49
|
+
type: "toolcall_delta";
|
|
50
|
+
contentIndex: number;
|
|
51
|
+
delta: string;
|
|
52
|
+
} | {
|
|
53
|
+
type: "toolcall_end";
|
|
54
|
+
contentIndex: number;
|
|
55
|
+
} | {
|
|
56
|
+
type: "done";
|
|
57
|
+
reason: Extract<StopReason, "stop" | "length" | "toolUse">;
|
|
58
|
+
usage: AssistantMessage["usage"];
|
|
59
|
+
} | {
|
|
60
|
+
type: "error";
|
|
61
|
+
reason: Extract<StopReason, "aborted" | "error">;
|
|
62
|
+
errorMessage?: string;
|
|
63
|
+
usage: AssistantMessage["usage"];
|
|
64
|
+
};
|
|
65
|
+
export interface ProxyStreamOptions extends SimpleStreamOptions {
|
|
66
|
+
/** Auth token for the proxy server */
|
|
67
|
+
authToken: string;
|
|
68
|
+
/** Proxy server URL (e.g., "https://genai.example.com") */
|
|
69
|
+
proxyUrl: string;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Stream function that proxies through a server instead of calling LLM providers directly.
|
|
73
|
+
* The server strips the partial field from delta events to reduce bandwidth.
|
|
74
|
+
* We reconstruct the partial message client-side.
|
|
75
|
+
*
|
|
76
|
+
* Use this as the `streamFn` option when creating an Agent that needs to go through a proxy.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* const agent = new Agent({
|
|
81
|
+
* streamFn: (model, context, options) =>
|
|
82
|
+
* streamProxy(model, context, {
|
|
83
|
+
* ...options,
|
|
84
|
+
* authToken: await getAuthToken(),
|
|
85
|
+
* proxyUrl: "https://genai.example.com",
|
|
86
|
+
* }),
|
|
87
|
+
* });
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export declare function streamProxy(model: Model<any>, context: Context, options: ProxyStreamOptions): ProxyMessageEventStream;
|
|
91
|
+
export {};
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proxy stream function for apps that route LLM calls through a server.
|
|
3
|
+
* The server manages auth and proxies requests to LLM providers.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* [WHO]: ProxyStreamOptions, streamProxy
|
|
7
|
+
* [FROM]: No external dependencies
|
|
8
|
+
* [TO]: Consumed by core/lib/agent-core/src/index.ts
|
|
9
|
+
* [HERE]: core/lib/agent-core/src/proxy.ts -
|
|
10
|
+
*/
|
|
11
|
+
import { EventStream } from "@pencil-agent/ai/events";
|
|
12
|
+
import { parseStreamingJson } from "@pencil-agent/ai/json";
|
|
13
|
+
// Create stream class matching ProxyMessageEventStream
|
|
14
|
+
class ProxyMessageEventStream extends EventStream {
|
|
15
|
+
constructor() {
|
|
16
|
+
super((event) => event.type === "done" || event.type === "error", (event) => {
|
|
17
|
+
if (event.type === "done")
|
|
18
|
+
return event.message;
|
|
19
|
+
if (event.type === "error")
|
|
20
|
+
return event.error;
|
|
21
|
+
throw new Error("Unexpected event type");
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function isStreamingToolCall(content) {
|
|
26
|
+
return (content?.type === "toolCall" &&
|
|
27
|
+
typeof content.partialJson === "string");
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Stream function that proxies through a server instead of calling LLM providers directly.
|
|
31
|
+
* The server strips the partial field from delta events to reduce bandwidth.
|
|
32
|
+
* We reconstruct the partial message client-side.
|
|
33
|
+
*
|
|
34
|
+
* Use this as the `streamFn` option when creating an Agent that needs to go through a proxy.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const agent = new Agent({
|
|
39
|
+
* streamFn: (model, context, options) =>
|
|
40
|
+
* streamProxy(model, context, {
|
|
41
|
+
* ...options,
|
|
42
|
+
* authToken: await getAuthToken(),
|
|
43
|
+
* proxyUrl: "https://genai.example.com",
|
|
44
|
+
* }),
|
|
45
|
+
* });
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export function streamProxy(model, context, options) {
|
|
49
|
+
const stream = new ProxyMessageEventStream();
|
|
50
|
+
(async () => {
|
|
51
|
+
// Initialize the partial message that we'll build up from events
|
|
52
|
+
const partial = {
|
|
53
|
+
role: "assistant",
|
|
54
|
+
stopReason: "stop",
|
|
55
|
+
content: [],
|
|
56
|
+
api: model.api,
|
|
57
|
+
provider: model.provider,
|
|
58
|
+
model: model.id,
|
|
59
|
+
usage: {
|
|
60
|
+
input: 0,
|
|
61
|
+
output: 0,
|
|
62
|
+
cacheRead: 0,
|
|
63
|
+
cacheWrite: 0,
|
|
64
|
+
totalTokens: 0,
|
|
65
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
66
|
+
},
|
|
67
|
+
timestamp: Date.now(),
|
|
68
|
+
};
|
|
69
|
+
let reader;
|
|
70
|
+
const abortHandler = () => {
|
|
71
|
+
if (reader) {
|
|
72
|
+
reader.cancel("Request aborted by user").catch(() => { });
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
if (options.signal) {
|
|
76
|
+
options.signal.addEventListener("abort", abortHandler, { once: true });
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
const response = await fetch(`${options.proxyUrl}/api/stream`, {
|
|
80
|
+
method: "POST",
|
|
81
|
+
headers: {
|
|
82
|
+
Authorization: `Bearer ${options.authToken}`,
|
|
83
|
+
"Content-Type": "application/json",
|
|
84
|
+
},
|
|
85
|
+
body: JSON.stringify({
|
|
86
|
+
model,
|
|
87
|
+
context,
|
|
88
|
+
options: {
|
|
89
|
+
temperature: options.temperature,
|
|
90
|
+
maxTokens: options.maxTokens,
|
|
91
|
+
reasoning: options.reasoning,
|
|
92
|
+
},
|
|
93
|
+
}),
|
|
94
|
+
signal: options.signal,
|
|
95
|
+
});
|
|
96
|
+
if (!response.ok) {
|
|
97
|
+
let errorMessage = `Proxy error: ${response.status} ${response.statusText}`;
|
|
98
|
+
try {
|
|
99
|
+
const errorData = (await response.json());
|
|
100
|
+
if (errorData.error) {
|
|
101
|
+
errorMessage = `Proxy error: ${errorData.error}`;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// Couldn't parse error response
|
|
106
|
+
}
|
|
107
|
+
throw new Error(errorMessage);
|
|
108
|
+
}
|
|
109
|
+
reader = response.body.getReader();
|
|
110
|
+
const decoder = new TextDecoder();
|
|
111
|
+
let buffer = "";
|
|
112
|
+
while (true) {
|
|
113
|
+
const { done, value } = await reader.read();
|
|
114
|
+
if (done)
|
|
115
|
+
break;
|
|
116
|
+
if (options.signal?.aborted) {
|
|
117
|
+
throw new Error("Request aborted by user");
|
|
118
|
+
}
|
|
119
|
+
buffer += decoder.decode(value, { stream: true });
|
|
120
|
+
const lines = buffer.split("\n");
|
|
121
|
+
buffer = lines.pop() || "";
|
|
122
|
+
for (const line of lines) {
|
|
123
|
+
if (line.startsWith("data: ")) {
|
|
124
|
+
const data = line.slice(6).trim();
|
|
125
|
+
if (data) {
|
|
126
|
+
const proxyEvent = JSON.parse(data);
|
|
127
|
+
const event = processProxyEvent(proxyEvent, partial);
|
|
128
|
+
if (event) {
|
|
129
|
+
stream.push(event);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (options.signal?.aborted) {
|
|
136
|
+
throw new Error("Request aborted by user");
|
|
137
|
+
}
|
|
138
|
+
stream.end();
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
142
|
+
const reason = options.signal?.aborted ? "aborted" : "error";
|
|
143
|
+
partial.stopReason = reason;
|
|
144
|
+
partial.errorMessage = errorMessage;
|
|
145
|
+
stream.push({
|
|
146
|
+
type: "error",
|
|
147
|
+
reason,
|
|
148
|
+
error: partial,
|
|
149
|
+
});
|
|
150
|
+
stream.end();
|
|
151
|
+
}
|
|
152
|
+
finally {
|
|
153
|
+
if (options.signal) {
|
|
154
|
+
options.signal.removeEventListener("abort", abortHandler);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
})();
|
|
158
|
+
return stream;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Process a proxy event and update the partial message.
|
|
162
|
+
*/
|
|
163
|
+
function processProxyEvent(proxyEvent, partial) {
|
|
164
|
+
switch (proxyEvent.type) {
|
|
165
|
+
case "start":
|
|
166
|
+
return { type: "start", partial };
|
|
167
|
+
case "text_start":
|
|
168
|
+
partial.content[proxyEvent.contentIndex] = { type: "text", text: "" };
|
|
169
|
+
return { type: "text_start", contentIndex: proxyEvent.contentIndex, partial };
|
|
170
|
+
case "text_delta": {
|
|
171
|
+
const content = partial.content[proxyEvent.contentIndex];
|
|
172
|
+
if (content?.type === "text") {
|
|
173
|
+
content.text += proxyEvent.delta;
|
|
174
|
+
return {
|
|
175
|
+
type: "text_delta",
|
|
176
|
+
contentIndex: proxyEvent.contentIndex,
|
|
177
|
+
delta: proxyEvent.delta,
|
|
178
|
+
partial,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
throw new Error("Received text_delta for non-text content");
|
|
182
|
+
}
|
|
183
|
+
case "text_end": {
|
|
184
|
+
const content = partial.content[proxyEvent.contentIndex];
|
|
185
|
+
if (content?.type === "text") {
|
|
186
|
+
content.textSignature = proxyEvent.contentSignature;
|
|
187
|
+
return {
|
|
188
|
+
type: "text_end",
|
|
189
|
+
contentIndex: proxyEvent.contentIndex,
|
|
190
|
+
content: content.text,
|
|
191
|
+
partial,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
throw new Error("Received text_end for non-text content");
|
|
195
|
+
}
|
|
196
|
+
case "thinking_start":
|
|
197
|
+
partial.content[proxyEvent.contentIndex] = { type: "thinking", thinking: "" };
|
|
198
|
+
return { type: "thinking_start", contentIndex: proxyEvent.contentIndex, partial };
|
|
199
|
+
case "thinking_delta": {
|
|
200
|
+
const content = partial.content[proxyEvent.contentIndex];
|
|
201
|
+
if (content?.type === "thinking") {
|
|
202
|
+
content.thinking += proxyEvent.delta;
|
|
203
|
+
return {
|
|
204
|
+
type: "thinking_delta",
|
|
205
|
+
contentIndex: proxyEvent.contentIndex,
|
|
206
|
+
delta: proxyEvent.delta,
|
|
207
|
+
partial,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
throw new Error("Received thinking_delta for non-thinking content");
|
|
211
|
+
}
|
|
212
|
+
case "thinking_end": {
|
|
213
|
+
const content = partial.content[proxyEvent.contentIndex];
|
|
214
|
+
if (content?.type === "thinking") {
|
|
215
|
+
content.thinkingSignature = proxyEvent.contentSignature;
|
|
216
|
+
return {
|
|
217
|
+
type: "thinking_end",
|
|
218
|
+
contentIndex: proxyEvent.contentIndex,
|
|
219
|
+
content: content.thinking,
|
|
220
|
+
partial,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
throw new Error("Received thinking_end for non-thinking content");
|
|
224
|
+
}
|
|
225
|
+
case "toolcall_start": {
|
|
226
|
+
const toolCall = {
|
|
227
|
+
type: "toolCall",
|
|
228
|
+
id: proxyEvent.id,
|
|
229
|
+
name: proxyEvent.toolName,
|
|
230
|
+
arguments: {},
|
|
231
|
+
partialJson: "",
|
|
232
|
+
};
|
|
233
|
+
partial.content[proxyEvent.contentIndex] = toolCall;
|
|
234
|
+
return { type: "toolcall_start", contentIndex: proxyEvent.contentIndex, partial };
|
|
235
|
+
}
|
|
236
|
+
case "toolcall_delta": {
|
|
237
|
+
const content = partial.content[proxyEvent.contentIndex];
|
|
238
|
+
if (isStreamingToolCall(content)) {
|
|
239
|
+
content.partialJson += proxyEvent.delta;
|
|
240
|
+
content.arguments = parseStreamingJson(content.partialJson) || {};
|
|
241
|
+
partial.content[proxyEvent.contentIndex] = { ...content }; // Trigger reactivity
|
|
242
|
+
return {
|
|
243
|
+
type: "toolcall_delta",
|
|
244
|
+
contentIndex: proxyEvent.contentIndex,
|
|
245
|
+
delta: proxyEvent.delta,
|
|
246
|
+
partial,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
throw new Error("Received toolcall_delta for non-toolCall content");
|
|
250
|
+
}
|
|
251
|
+
case "toolcall_end": {
|
|
252
|
+
const content = partial.content[proxyEvent.contentIndex];
|
|
253
|
+
if (isStreamingToolCall(content)) {
|
|
254
|
+
const { partialJson: _partialJson, ...toolCall } = content;
|
|
255
|
+
partial.content[proxyEvent.contentIndex] = toolCall;
|
|
256
|
+
return {
|
|
257
|
+
type: "toolcall_end",
|
|
258
|
+
contentIndex: proxyEvent.contentIndex,
|
|
259
|
+
toolCall,
|
|
260
|
+
partial,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
return undefined;
|
|
264
|
+
}
|
|
265
|
+
case "done":
|
|
266
|
+
partial.stopReason = proxyEvent.reason;
|
|
267
|
+
partial.usage = proxyEvent.usage;
|
|
268
|
+
return { type: "done", reason: proxyEvent.reason, message: partial };
|
|
269
|
+
case "error":
|
|
270
|
+
partial.stopReason = proxyEvent.reason;
|
|
271
|
+
partial.errorMessage = proxyEvent.errorMessage;
|
|
272
|
+
partial.usage = proxyEvent.usage;
|
|
273
|
+
return { type: "error", reason: proxyEvent.reason, error: partial };
|
|
274
|
+
default: {
|
|
275
|
+
// Exhaustive check - unhandled event types are silently skipped
|
|
276
|
+
return undefined;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured-adaptive agent loop for nanoPencil.
|
|
3
|
+
* Keeps the public AgentMessage/EventStream contract while using a query-loop
|
|
4
|
+
* state machine with ordered tool-result pairing and safe tool batching.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* [WHO]: structuredAdaptiveAgentLoop, structuredAdaptiveAgentLoopContinue
|
|
8
|
+
* [FROM]: Depends on @pencil-agent/ai, ./types, ./errors, structured-adaptive tool executors, and shared loop helpers.
|
|
9
|
+
* [TO]: Consumed by core/lib/agent-core/src/agent.ts and index.ts
|
|
10
|
+
* [HERE]: core/lib/agent-core/src/structured-adaptive-agent-loop.ts - selectable structured-adaptive query loop framework with recovered-error tombstoning
|
|
11
|
+
*/
|
|
12
|
+
import { EventStream } from "@pencil-agent/ai/events";
|
|
13
|
+
import type { AgentContext, AgentEvent, AgentLoopConfig, AgentMessage, StreamFn } from "./types.js";
|
|
14
|
+
export declare function structuredAdaptiveAgentLoop(prompts: AgentMessage[], context: AgentContext, config: AgentLoopConfig, signal?: AbortSignal, streamFn?: StreamFn): EventStream<AgentEvent, AgentMessage[]>;
|
|
15
|
+
export declare function structuredAdaptiveAgentLoopContinue(context: AgentContext, config: AgentLoopConfig, signal?: AbortSignal, streamFn?: StreamFn): EventStream<AgentEvent, AgentMessage[]>;
|