@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.
Files changed (179) hide show
  1. package/dist/build-meta.json +3 -3
  2. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-continuations.d.ts +17 -0
  3. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-continuations.js +60 -0
  4. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-stream-events.d.ts +19 -0
  5. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-stream-events.js +55 -0
  6. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-tool-results.d.ts +10 -0
  7. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-tool-results.js +137 -0
  8. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-tool-summaries.d.ts +22 -0
  9. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-tool-summaries.js +64 -0
  10. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop.d.ts +26 -0
  11. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop.js +913 -0
  12. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-run-result.d.ts +9 -0
  13. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-run-result.js +32 -0
  14. package/dist/node_modules/@pencil-agent/agent-core/dist/agent.d.ts +215 -0
  15. package/dist/node_modules/@pencil-agent/agent-core/dist/agent.js +522 -0
  16. package/dist/node_modules/@pencil-agent/agent-core/dist/errors.d.ts +62 -0
  17. package/dist/node_modules/@pencil-agent/agent-core/dist/errors.js +146 -0
  18. package/dist/node_modules/@pencil-agent/agent-core/dist/index.d.ts +14 -0
  19. package/dist/node_modules/@pencil-agent/agent-core/dist/index.js +19 -0
  20. package/dist/node_modules/@pencil-agent/agent-core/dist/proxy.d.ts +91 -0
  21. package/dist/node_modules/@pencil-agent/agent-core/dist/proxy.js +279 -0
  22. package/dist/node_modules/@pencil-agent/agent-core/dist/structured-adaptive-agent-loop.d.ts +15 -0
  23. package/dist/node_modules/@pencil-agent/agent-core/dist/structured-adaptive-agent-loop.js +625 -0
  24. package/dist/node_modules/@pencil-agent/agent-core/dist/structured-adaptive-streaming-tool-executor.d.ts +33 -0
  25. package/dist/node_modules/@pencil-agent/agent-core/dist/structured-adaptive-streaming-tool-executor.js +189 -0
  26. package/dist/node_modules/@pencil-agent/agent-core/dist/structured-adaptive-tool-orchestration.d.ts +35 -0
  27. package/dist/node_modules/@pencil-agent/agent-core/dist/structured-adaptive-tool-orchestration.js +319 -0
  28. package/dist/node_modules/@pencil-agent/agent-core/dist/types.d.ts +417 -0
  29. package/dist/node_modules/@pencil-agent/agent-core/dist/types.js +13 -0
  30. package/dist/node_modules/@pencil-agent/agent-core/package.json +28 -0
  31. package/dist/node_modules/@pencil-agent/ai/dist/api-registry.d.ts +27 -0
  32. package/dist/node_modules/@pencil-agent/ai/dist/api-registry.js +152 -0
  33. package/dist/node_modules/@pencil-agent/ai/dist/cli.d.ts +2 -0
  34. package/dist/node_modules/@pencil-agent/ai/dist/cli.js +121 -0
  35. package/dist/node_modules/@pencil-agent/ai/dist/config-path.d.ts +1 -0
  36. package/dist/node_modules/@pencil-agent/ai/dist/config-path.js +17 -0
  37. package/dist/node_modules/@pencil-agent/ai/dist/debug-logger.d.ts +94 -0
  38. package/dist/node_modules/@pencil-agent/ai/dist/debug-logger.js +218 -0
  39. package/dist/node_modules/@pencil-agent/ai/dist/env-api-keys.d.ts +8 -0
  40. package/dist/node_modules/@pencil-agent/ai/dist/env-api-keys.js +107 -0
  41. package/dist/node_modules/@pencil-agent/ai/dist/env.d.ts +7 -0
  42. package/dist/node_modules/@pencil-agent/ai/dist/env.js +7 -0
  43. package/dist/node_modules/@pencil-agent/ai/dist/events.d.ts +8 -0
  44. package/dist/node_modules/@pencil-agent/ai/dist/events.js +7 -0
  45. package/dist/node_modules/@pencil-agent/ai/dist/index.d.ts +27 -0
  46. package/dist/node_modules/@pencil-agent/ai/dist/index.js +20 -0
  47. package/dist/node_modules/@pencil-agent/ai/dist/json.d.ts +7 -0
  48. package/dist/node_modules/@pencil-agent/ai/dist/json.js +7 -0
  49. package/dist/node_modules/@pencil-agent/ai/dist/models.d.ts +31 -0
  50. package/dist/node_modules/@pencil-agent/ai/dist/models.generated.d.ts +15159 -0
  51. package/dist/node_modules/@pencil-agent/ai/dist/models.generated.js +14928 -0
  52. package/dist/node_modules/@pencil-agent/ai/dist/models.js +60 -0
  53. package/dist/node_modules/@pencil-agent/ai/dist/overflow.d.ts +7 -0
  54. package/dist/node_modules/@pencil-agent/ai/dist/overflow.js +7 -0
  55. package/dist/node_modules/@pencil-agent/ai/dist/providers/amazon-bedrock.d.ts +20 -0
  56. package/dist/node_modules/@pencil-agent/ai/dist/providers/amazon-bedrock.js +606 -0
  57. package/dist/node_modules/@pencil-agent/ai/dist/providers/anthropic.d.ts +38 -0
  58. package/dist/node_modules/@pencil-agent/ai/dist/providers/anthropic.js +737 -0
  59. package/dist/node_modules/@pencil-agent/ai/dist/providers/azure-openai-responses.d.ts +21 -0
  60. package/dist/node_modules/@pencil-agent/ai/dist/providers/azure-openai-responses.js +193 -0
  61. package/dist/node_modules/@pencil-agent/ai/dist/providers/github-copilot-headers.d.ts +13 -0
  62. package/dist/node_modules/@pencil-agent/ai/dist/providers/github-copilot-headers.js +34 -0
  63. package/dist/node_modules/@pencil-agent/ai/dist/providers/google-gemini-cli.d.ts +79 -0
  64. package/dist/node_modules/@pencil-agent/ai/dist/providers/google-gemini-cli.js +753 -0
  65. package/dist/node_modules/@pencil-agent/ai/dist/providers/google-shared.d.ts +70 -0
  66. package/dist/node_modules/@pencil-agent/ai/dist/providers/google-shared.js +311 -0
  67. package/dist/node_modules/@pencil-agent/ai/dist/providers/google-vertex.d.ts +20 -0
  68. package/dist/node_modules/@pencil-agent/ai/dist/providers/google-vertex.js +380 -0
  69. package/dist/node_modules/@pencil-agent/ai/dist/providers/google.d.ts +18 -0
  70. package/dist/node_modules/@pencil-agent/ai/dist/providers/google.js +360 -0
  71. package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-codex-responses.d.ts +8 -0
  72. package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-codex-responses.js +704 -0
  73. package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-completions.d.ts +20 -0
  74. package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-completions.js +870 -0
  75. package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-responses-shared.d.ts +22 -0
  76. package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-responses-shared.js +432 -0
  77. package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-responses.d.ts +19 -0
  78. package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-responses.js +207 -0
  79. package/dist/node_modules/@pencil-agent/ai/dist/providers/register-builtins.d.ts +8 -0
  80. package/dist/node_modules/@pencil-agent/ai/dist/providers/register-builtins.js +86 -0
  81. package/dist/node_modules/@pencil-agent/ai/dist/providers/simple-options.d.ts +13 -0
  82. package/dist/node_modules/@pencil-agent/ai/dist/providers/simple-options.js +40 -0
  83. package/dist/node_modules/@pencil-agent/ai/dist/providers/transform-messages.d.ts +13 -0
  84. package/dist/node_modules/@pencil-agent/ai/dist/providers/transform-messages.js +175 -0
  85. package/dist/node_modules/@pencil-agent/ai/dist/registry.d.ts +8 -0
  86. package/dist/node_modules/@pencil-agent/ai/dist/registry.js +8 -0
  87. package/dist/node_modules/@pencil-agent/ai/dist/schema.d.ts +10 -0
  88. package/dist/node_modules/@pencil-agent/ai/dist/schema.js +9 -0
  89. package/dist/node_modules/@pencil-agent/ai/dist/stream.d.ts +25 -0
  90. package/dist/node_modules/@pencil-agent/ai/dist/stream.js +324 -0
  91. package/dist/node_modules/@pencil-agent/ai/dist/types.d.ts +306 -0
  92. package/dist/node_modules/@pencil-agent/ai/dist/types.js +7 -0
  93. package/dist/node_modules/@pencil-agent/ai/dist/utils/event-stream-types.d.ts +12 -0
  94. package/dist/node_modules/@pencil-agent/ai/dist/utils/event-stream-types.js +7 -0
  95. package/dist/node_modules/@pencil-agent/ai/dist/utils/event-stream.d.ts +31 -0
  96. package/dist/node_modules/@pencil-agent/ai/dist/utils/event-stream.js +98 -0
  97. package/dist/node_modules/@pencil-agent/ai/dist/utils/http-proxy.d.ts +13 -0
  98. package/dist/node_modules/@pencil-agent/ai/dist/utils/http-proxy.js +20 -0
  99. package/dist/node_modules/@pencil-agent/ai/dist/utils/json-parse.d.ts +14 -0
  100. package/dist/node_modules/@pencil-agent/ai/dist/utils/json-parse.js +34 -0
  101. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/anthropic.d.ts +22 -0
  102. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/anthropic.js +109 -0
  103. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/decode-credential.d.ts +12 -0
  104. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/decode-credential.js +25 -0
  105. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/github-copilot.d.ts +35 -0
  106. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/github-copilot.js +286 -0
  107. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/google-antigravity.d.ts +31 -0
  108. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/google-antigravity.js +378 -0
  109. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/google-gemini-cli.d.ts +31 -0
  110. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/google-gemini-cli.js +483 -0
  111. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/index.d.ts +60 -0
  112. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/index.js +131 -0
  113. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/openai-codex.d.ts +39 -0
  114. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/openai-codex.js +385 -0
  115. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/pkce.d.ts +18 -0
  116. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/pkce.js +36 -0
  117. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/types.d.ts +52 -0
  118. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/types.js +7 -0
  119. package/dist/node_modules/@pencil-agent/ai/dist/utils/overflow.d.ts +57 -0
  120. package/dist/node_modules/@pencil-agent/ai/dist/utils/overflow.js +120 -0
  121. package/dist/node_modules/@pencil-agent/ai/dist/utils/sanitize-unicode.d.ts +16 -0
  122. package/dist/node_modules/@pencil-agent/ai/dist/utils/sanitize-unicode.js +20 -0
  123. package/dist/node_modules/@pencil-agent/ai/dist/utils/typebox-helpers.d.ts +22 -0
  124. package/dist/node_modules/@pencil-agent/ai/dist/utils/typebox-helpers.js +26 -0
  125. package/dist/node_modules/@pencil-agent/ai/dist/utils/validation.d.ts +23 -0
  126. package/dist/node_modules/@pencil-agent/ai/dist/utils/validation.js +78 -0
  127. package/dist/node_modules/@pencil-agent/ai/package.json +94 -0
  128. package/dist/node_modules/@pencil-agent/tui/dist/autocomplete.d.ts +62 -0
  129. package/dist/node_modules/@pencil-agent/tui/dist/autocomplete.js +624 -0
  130. package/dist/node_modules/@pencil-agent/tui/dist/components/box.d.ts +27 -0
  131. package/dist/node_modules/@pencil-agent/tui/dist/components/box.js +109 -0
  132. package/dist/node_modules/@pencil-agent/tui/dist/components/cancellable-loader.d.ts +27 -0
  133. package/dist/node_modules/@pencil-agent/tui/dist/components/cancellable-loader.js +40 -0
  134. package/dist/node_modules/@pencil-agent/tui/dist/components/editor.d.ts +218 -0
  135. package/dist/node_modules/@pencil-agent/tui/dist/components/editor.js +1697 -0
  136. package/dist/node_modules/@pencil-agent/tui/dist/components/image.d.ts +33 -0
  137. package/dist/node_modules/@pencil-agent/tui/dist/components/image.js +74 -0
  138. package/dist/node_modules/@pencil-agent/tui/dist/components/input.d.ts +42 -0
  139. package/dist/node_modules/@pencil-agent/tui/dist/components/input.js +438 -0
  140. package/dist/node_modules/@pencil-agent/tui/dist/components/loader.d.ts +26 -0
  141. package/dist/node_modules/@pencil-agent/tui/dist/components/loader.js +54 -0
  142. package/dist/node_modules/@pencil-agent/tui/dist/components/markdown.d.ts +100 -0
  143. package/dist/node_modules/@pencil-agent/tui/dist/components/markdown.js +634 -0
  144. package/dist/node_modules/@pencil-agent/tui/dist/components/select-list.d.ts +37 -0
  145. package/dist/node_modules/@pencil-agent/tui/dist/components/select-list.js +157 -0
  146. package/dist/node_modules/@pencil-agent/tui/dist/components/settings-list.d.ts +55 -0
  147. package/dist/node_modules/@pencil-agent/tui/dist/components/settings-list.js +190 -0
  148. package/dist/node_modules/@pencil-agent/tui/dist/components/spacer.d.ts +17 -0
  149. package/dist/node_modules/@pencil-agent/tui/dist/components/spacer.js +28 -0
  150. package/dist/node_modules/@pencil-agent/tui/dist/components/text.d.ts +24 -0
  151. package/dist/node_modules/@pencil-agent/tui/dist/components/text.js +94 -0
  152. package/dist/node_modules/@pencil-agent/tui/dist/components/truncated-text.d.ts +18 -0
  153. package/dist/node_modules/@pencil-agent/tui/dist/components/truncated-text.js +56 -0
  154. package/dist/node_modules/@pencil-agent/tui/dist/editor-component.d.ts +51 -0
  155. package/dist/node_modules/@pencil-agent/tui/dist/editor-component.js +7 -0
  156. package/dist/node_modules/@pencil-agent/tui/dist/fuzzy.d.ts +32 -0
  157. package/dist/node_modules/@pencil-agent/tui/dist/fuzzy.js +152 -0
  158. package/dist/node_modules/@pencil-agent/tui/dist/index.d.ts +28 -0
  159. package/dist/node_modules/@pencil-agent/tui/dist/index.js +37 -0
  160. package/dist/node_modules/@pencil-agent/tui/dist/keybindings.d.ts +44 -0
  161. package/dist/node_modules/@pencil-agent/tui/dist/keybindings.js +119 -0
  162. package/dist/node_modules/@pencil-agent/tui/dist/keys.d.ts +149 -0
  163. package/dist/node_modules/@pencil-agent/tui/dist/keys.js +948 -0
  164. package/dist/node_modules/@pencil-agent/tui/dist/kill-ring.d.ts +33 -0
  165. package/dist/node_modules/@pencil-agent/tui/dist/kill-ring.js +49 -0
  166. package/dist/node_modules/@pencil-agent/tui/dist/stdin-buffer.d.ts +38 -0
  167. package/dist/node_modules/@pencil-agent/tui/dist/stdin-buffer.js +307 -0
  168. package/dist/node_modules/@pencil-agent/tui/dist/terminal-image.d.ts +73 -0
  169. package/dist/node_modules/@pencil-agent/tui/dist/terminal-image.js +287 -0
  170. package/dist/node_modules/@pencil-agent/tui/dist/terminal.d.ts +86 -0
  171. package/dist/node_modules/@pencil-agent/tui/dist/terminal.js +266 -0
  172. package/dist/node_modules/@pencil-agent/tui/dist/tui.d.ts +219 -0
  173. package/dist/node_modules/@pencil-agent/tui/dist/tui.js +1001 -0
  174. package/dist/node_modules/@pencil-agent/tui/dist/undo-stack.d.ts +22 -0
  175. package/dist/node_modules/@pencil-agent/tui/dist/undo-stack.js +30 -0
  176. package/dist/node_modules/@pencil-agent/tui/dist/utils.d.ts +83 -0
  177. package/dist/node_modules/@pencil-agent/tui/dist/utils.js +811 -0
  178. package/dist/node_modules/@pencil-agent/tui/package.json +37 -0
  179. package/package.json +3 -2
@@ -0,0 +1,522 @@
1
+ /**
2
+ * Agent class that uses the agent-loop directly.
3
+ * No transport abstraction - calls streamSimple via the loop.
4
+ */
5
+ /**
6
+ * [WHO]: AgentOptions, Agent, and loop policy option plumbing
7
+ * [FROM]: Depends on ./agent-loop.js and ./structured-adaptive-agent-loop.js
8
+ * [TO]: Consumed by core/lib/agent-core/src/index.ts
9
+ * [HERE]: core/lib/agent-core/src/agent.ts -
10
+ */
11
+ import { getModel } from "@pencil-agent/ai/models";
12
+ import { streamSimple } from "@pencil-agent/ai/stream";
13
+ import { agentLoop, agentLoopContinue } from "./agent-loop.js";
14
+ import { structuredAdaptiveAgentLoop, structuredAdaptiveAgentLoopContinue } from "./structured-adaptive-agent-loop.js";
15
+ import { normalizeAgentLoopFramework } from "./types.js";
16
+ /**
17
+ * Default convertToLlm: Keep only LLM-compatible messages, convert attachments.
18
+ */
19
+ function defaultConvertToLlm(messages) {
20
+ return messages.filter((m) => m.role === "user" || m.role === "assistant" || m.role === "toolResult");
21
+ }
22
+ export class Agent {
23
+ _state = {
24
+ systemPrompt: "",
25
+ model: getModel("google", "gemini-2.5-flash-lite"),
26
+ thinkingLevel: "off",
27
+ tools: [],
28
+ messages: [],
29
+ isStreaming: false,
30
+ streamMessage: null,
31
+ pendingToolCalls: new Set(),
32
+ lastResult: undefined,
33
+ error: undefined,
34
+ };
35
+ listeners = new Set();
36
+ abortController;
37
+ convertToLlm;
38
+ transformContext;
39
+ steeringQueue = [];
40
+ followUpQueue = [];
41
+ steeringMode;
42
+ followUpMode;
43
+ streamFn;
44
+ _sessionId;
45
+ getApiKey;
46
+ runningPrompt;
47
+ resolveRunningPrompt;
48
+ _thinkingBudgets;
49
+ _transport;
50
+ _maxRetryDelayMs;
51
+ _agentLoopFramework;
52
+ canUseTool;
53
+ maxToolResultBatchSizeChars;
54
+ recoverModelError;
55
+ maxModelErrorRecoveryAttempts;
56
+ maxOutputTokenRecoveryAttempts;
57
+ outputTokenBudget;
58
+ runStopHooks;
59
+ maxStopHookContinuations;
60
+ createToolUseSummary;
61
+ maxToolConcurrency;
62
+ maxTurnsPerPrompt;
63
+ maxToolCallsPerPrompt;
64
+ constructor(opts = {}) {
65
+ this._state = { ...this._state, ...opts.initialState };
66
+ this.convertToLlm = opts.convertToLlm || defaultConvertToLlm;
67
+ this.transformContext = opts.transformContext;
68
+ this.steeringMode = opts.steeringMode || "one-at-a-time";
69
+ this.followUpMode = opts.followUpMode || "one-at-a-time";
70
+ this.streamFn = opts.streamFn || streamSimple;
71
+ this._sessionId = opts.sessionId;
72
+ this.getApiKey = opts.getApiKey;
73
+ this._thinkingBudgets = opts.thinkingBudgets;
74
+ this._transport = opts.transport ?? "sse";
75
+ this._maxRetryDelayMs = opts.maxRetryDelayMs;
76
+ this._agentLoopFramework = normalizeAgentLoopFramework(opts.agentLoopFramework);
77
+ this.canUseTool = opts.canUseTool;
78
+ this.maxToolResultBatchSizeChars = opts.maxToolResultBatchSizeChars;
79
+ this.recoverModelError = opts.recoverModelError;
80
+ this.maxModelErrorRecoveryAttempts = opts.maxModelErrorRecoveryAttempts;
81
+ this.maxOutputTokenRecoveryAttempts = opts.maxOutputTokenRecoveryAttempts;
82
+ this.outputTokenBudget = opts.outputTokenBudget;
83
+ this.runStopHooks = opts.runStopHooks;
84
+ this.maxStopHookContinuations = opts.maxStopHookContinuations;
85
+ this.createToolUseSummary = opts.createToolUseSummary;
86
+ this.maxToolConcurrency = opts.maxToolConcurrency;
87
+ this.maxTurnsPerPrompt = opts.maxTurnsPerPrompt;
88
+ this.maxToolCallsPerPrompt = opts.maxToolCallsPerPrompt;
89
+ }
90
+ /**
91
+ * Get the current session ID used for provider caching.
92
+ */
93
+ get sessionId() {
94
+ return this._sessionId;
95
+ }
96
+ /**
97
+ * Set the session ID for provider caching.
98
+ * Call this when switching sessions (new session, branch, resume).
99
+ */
100
+ set sessionId(value) {
101
+ this._sessionId = value;
102
+ }
103
+ /**
104
+ * Get the current thinking budgets.
105
+ */
106
+ get thinkingBudgets() {
107
+ return this._thinkingBudgets;
108
+ }
109
+ /**
110
+ * Set custom thinking budgets for token-based providers.
111
+ */
112
+ set thinkingBudgets(value) {
113
+ this._thinkingBudgets = value;
114
+ }
115
+ /**
116
+ * Get the current preferred transport.
117
+ */
118
+ get transport() {
119
+ return this._transport;
120
+ }
121
+ /**
122
+ * Set the preferred transport.
123
+ */
124
+ setTransport(value) {
125
+ this._transport = value;
126
+ }
127
+ /**
128
+ * Get the current max retry delay in milliseconds.
129
+ */
130
+ get maxRetryDelayMs() {
131
+ return this._maxRetryDelayMs;
132
+ }
133
+ /**
134
+ * Set the maximum delay to wait for server-requested retries.
135
+ * Set to 0 to disable the cap.
136
+ */
137
+ set maxRetryDelayMs(value) {
138
+ this._maxRetryDelayMs = value;
139
+ }
140
+ get agentLoopFramework() {
141
+ return normalizeAgentLoopFramework(this._agentLoopFramework ?? this._state.model.agentLoopFramework) ?? "standard";
142
+ }
143
+ setAgentLoopFramework(value) {
144
+ this._agentLoopFramework = normalizeAgentLoopFramework(value);
145
+ }
146
+ get state() {
147
+ return this._state;
148
+ }
149
+ subscribe(fn) {
150
+ this.listeners.add(fn);
151
+ return () => this.listeners.delete(fn);
152
+ }
153
+ // State mutators
154
+ setSystemPrompt(v) {
155
+ this._state.systemPrompt = v;
156
+ }
157
+ setModel(m) {
158
+ this._state.model = m;
159
+ }
160
+ setThinkingLevel(l) {
161
+ this._state.thinkingLevel = l;
162
+ }
163
+ setSteeringMode(mode) {
164
+ this.steeringMode = mode;
165
+ }
166
+ getSteeringMode() {
167
+ return this.steeringMode;
168
+ }
169
+ setFollowUpMode(mode) {
170
+ this.followUpMode = mode;
171
+ }
172
+ getFollowUpMode() {
173
+ return this.followUpMode;
174
+ }
175
+ setTools(t) {
176
+ this._state.tools = t;
177
+ }
178
+ setLoopPolicy(options) {
179
+ if ("canUseTool" in options)
180
+ this.canUseTool = options.canUseTool;
181
+ if ("maxToolResultBatchSizeChars" in options)
182
+ this.maxToolResultBatchSizeChars = options.maxToolResultBatchSizeChars;
183
+ if ("recoverModelError" in options)
184
+ this.recoverModelError = options.recoverModelError;
185
+ if ("maxModelErrorRecoveryAttempts" in options) {
186
+ this.maxModelErrorRecoveryAttempts = options.maxModelErrorRecoveryAttempts;
187
+ }
188
+ if ("maxOutputTokenRecoveryAttempts" in options) {
189
+ this.maxOutputTokenRecoveryAttempts = options.maxOutputTokenRecoveryAttempts;
190
+ }
191
+ if ("outputTokenBudget" in options)
192
+ this.outputTokenBudget = options.outputTokenBudget;
193
+ if ("runStopHooks" in options)
194
+ this.runStopHooks = options.runStopHooks;
195
+ if ("maxStopHookContinuations" in options)
196
+ this.maxStopHookContinuations = options.maxStopHookContinuations;
197
+ if ("createToolUseSummary" in options)
198
+ this.createToolUseSummary = options.createToolUseSummary;
199
+ if ("maxToolConcurrency" in options)
200
+ this.maxToolConcurrency = options.maxToolConcurrency;
201
+ if ("maxTurnsPerPrompt" in options)
202
+ this.maxTurnsPerPrompt = options.maxTurnsPerPrompt;
203
+ if ("maxToolCallsPerPrompt" in options)
204
+ this.maxToolCallsPerPrompt = options.maxToolCallsPerPrompt;
205
+ }
206
+ setModelErrorRecovery(recoverModelError) {
207
+ this.setLoopPolicy({ recoverModelError });
208
+ }
209
+ replaceMessages(ms) {
210
+ this._state.messages = ms.slice();
211
+ }
212
+ appendMessage(m) {
213
+ this._state.messages = [...this._state.messages, m];
214
+ }
215
+ /**
216
+ * Queue a steering message to interrupt the agent mid-run.
217
+ * Delivered after current tool execution, skips remaining tools.
218
+ */
219
+ steer(m) {
220
+ this.steeringQueue.push(m);
221
+ }
222
+ /**
223
+ * Queue a follow-up message to be processed after the agent finishes.
224
+ * Delivered only when agent has no more tool calls or steering messages.
225
+ */
226
+ followUp(m) {
227
+ this.followUpQueue.push(m);
228
+ }
229
+ clearSteeringQueue() {
230
+ this.steeringQueue = [];
231
+ }
232
+ clearFollowUpQueue() {
233
+ this.followUpQueue = [];
234
+ }
235
+ clearAllQueues() {
236
+ this.steeringQueue = [];
237
+ this.followUpQueue = [];
238
+ }
239
+ hasQueuedMessages() {
240
+ return this.steeringQueue.length > 0 || this.followUpQueue.length > 0;
241
+ }
242
+ dequeueSteeringMessages() {
243
+ if (this.steeringMode === "one-at-a-time") {
244
+ if (this.steeringQueue.length > 0) {
245
+ const first = this.steeringQueue[0];
246
+ this.steeringQueue = this.steeringQueue.slice(1);
247
+ return [first];
248
+ }
249
+ return [];
250
+ }
251
+ const steering = this.steeringQueue.slice();
252
+ this.steeringQueue = [];
253
+ return steering;
254
+ }
255
+ dequeueFollowUpMessages() {
256
+ if (this.followUpMode === "one-at-a-time") {
257
+ if (this.followUpQueue.length > 0) {
258
+ const first = this.followUpQueue[0];
259
+ this.followUpQueue = this.followUpQueue.slice(1);
260
+ return [first];
261
+ }
262
+ return [];
263
+ }
264
+ const followUp = this.followUpQueue.slice();
265
+ this.followUpQueue = [];
266
+ return followUp;
267
+ }
268
+ clearMessages() {
269
+ this._state.messages = [];
270
+ this._state.lastResult = undefined;
271
+ }
272
+ abort() {
273
+ this.abortController?.abort();
274
+ }
275
+ waitForIdle() {
276
+ return this.runningPrompt ?? Promise.resolve();
277
+ }
278
+ reset() {
279
+ this._state.messages = [];
280
+ this._state.isStreaming = false;
281
+ this._state.streamMessage = null;
282
+ this._state.pendingToolCalls = new Set();
283
+ this._state.lastResult = undefined;
284
+ this._state.error = undefined;
285
+ this.steeringQueue = [];
286
+ this.followUpQueue = [];
287
+ }
288
+ async prompt(input, images) {
289
+ if (this._state.isStreaming) {
290
+ throw new Error("Agent is already processing a prompt. Use steer() or followUp() to queue messages, or wait for completion.");
291
+ }
292
+ const model = this._state.model;
293
+ if (!model)
294
+ throw new Error("No model configured");
295
+ let msgs;
296
+ if (Array.isArray(input)) {
297
+ msgs = input;
298
+ }
299
+ else if (typeof input === "string") {
300
+ const content = [{ type: "text", text: input }];
301
+ if (images && images.length > 0) {
302
+ content.push(...images);
303
+ }
304
+ msgs = [
305
+ {
306
+ role: "user",
307
+ content,
308
+ timestamp: Date.now(),
309
+ },
310
+ ];
311
+ }
312
+ else {
313
+ msgs = [input];
314
+ }
315
+ await this._runLoop(msgs);
316
+ }
317
+ /**
318
+ * Continue from current context (used for retries and resuming queued messages).
319
+ */
320
+ async continue() {
321
+ if (this._state.isStreaming) {
322
+ throw new Error("Agent is already processing. Wait for completion before continuing.");
323
+ }
324
+ const messages = this._state.messages;
325
+ if (messages.length === 0) {
326
+ throw new Error("No messages to continue from");
327
+ }
328
+ if (messages[messages.length - 1].role === "assistant") {
329
+ const queuedSteering = this.dequeueSteeringMessages();
330
+ if (queuedSteering.length > 0) {
331
+ await this._runLoop(queuedSteering, { skipInitialSteeringPoll: true });
332
+ return;
333
+ }
334
+ const queuedFollowUp = this.dequeueFollowUpMessages();
335
+ if (queuedFollowUp.length > 0) {
336
+ await this._runLoop(queuedFollowUp);
337
+ return;
338
+ }
339
+ throw new Error("Cannot continue from message role: assistant");
340
+ }
341
+ await this._runLoop(undefined);
342
+ }
343
+ /**
344
+ * Run the agent loop.
345
+ * If messages are provided, starts a new conversation turn with those messages.
346
+ * Otherwise, continues from existing context.
347
+ */
348
+ async _runLoop(messages, options) {
349
+ const model = this._state.model;
350
+ if (!model)
351
+ throw new Error("No model configured");
352
+ this.runningPrompt = new Promise((resolve) => {
353
+ this.resolveRunningPrompt = resolve;
354
+ });
355
+ this.abortController = new AbortController();
356
+ this._state.isStreaming = true;
357
+ this._state.streamMessage = null;
358
+ this._state.lastResult = undefined;
359
+ this._state.error = undefined;
360
+ const reasoning = this._state.thinkingLevel === "off" ? undefined : this._state.thinkingLevel;
361
+ const context = {
362
+ systemPrompt: this._state.systemPrompt,
363
+ messages: this._state.messages.slice(),
364
+ tools: this._state.tools,
365
+ };
366
+ let skipInitialSteeringPoll = options?.skipInitialSteeringPoll === true;
367
+ const config = {
368
+ model,
369
+ loopFramework: this.agentLoopFramework,
370
+ reasoning,
371
+ sessionId: this._sessionId,
372
+ transport: this._transport,
373
+ thinkingBudgets: this._thinkingBudgets,
374
+ maxRetryDelayMs: this._maxRetryDelayMs,
375
+ convertToLlm: this.convertToLlm,
376
+ transformContext: this.transformContext,
377
+ getApiKey: this.getApiKey,
378
+ canUseTool: this.canUseTool,
379
+ maxToolResultBatchSizeChars: this.maxToolResultBatchSizeChars,
380
+ recoverModelError: this.recoverModelError,
381
+ maxModelErrorRecoveryAttempts: this.maxModelErrorRecoveryAttempts,
382
+ maxOutputTokenRecoveryAttempts: this.maxOutputTokenRecoveryAttempts,
383
+ outputTokenBudget: this.outputTokenBudget,
384
+ runStopHooks: this.runStopHooks,
385
+ maxStopHookContinuations: this.maxStopHookContinuations,
386
+ createToolUseSummary: this.createToolUseSummary,
387
+ maxToolConcurrency: this.maxToolConcurrency,
388
+ maxTurnsPerPrompt: this.maxTurnsPerPrompt,
389
+ maxToolCallsPerPrompt: this.maxToolCallsPerPrompt,
390
+ getSteeringMessages: async () => {
391
+ if (skipInitialSteeringPoll) {
392
+ skipInitialSteeringPoll = false;
393
+ return [];
394
+ }
395
+ return this.dequeueSteeringMessages();
396
+ },
397
+ getFollowUpMessages: async () => this.dequeueFollowUpMessages(),
398
+ };
399
+ let partial = null;
400
+ try {
401
+ const useStructuredAdaptiveLoop = config.loopFramework === "weak-model-compatible";
402
+ const stream = messages
403
+ ? useStructuredAdaptiveLoop
404
+ ? structuredAdaptiveAgentLoop(messages, context, config, this.abortController.signal, this.streamFn)
405
+ : agentLoop(messages, context, config, this.abortController.signal, this.streamFn)
406
+ : useStructuredAdaptiveLoop
407
+ ? structuredAdaptiveAgentLoopContinue(context, config, this.abortController.signal, this.streamFn)
408
+ : agentLoopContinue(context, config, this.abortController.signal, this.streamFn);
409
+ for await (const event of stream) {
410
+ // Update internal state based on events
411
+ switch (event.type) {
412
+ case "message_start":
413
+ partial = event.message;
414
+ this._state.streamMessage = event.message;
415
+ break;
416
+ case "message_update":
417
+ partial = event.message;
418
+ this._state.streamMessage = event.message;
419
+ break;
420
+ case "message_end":
421
+ partial = null;
422
+ this._state.streamMessage = null;
423
+ this.appendMessage(event.message);
424
+ break;
425
+ case "tool_execution_start": {
426
+ const s = new Set(this._state.pendingToolCalls);
427
+ s.add(event.toolCallId);
428
+ this._state.pendingToolCalls = s;
429
+ break;
430
+ }
431
+ case "tool_execution_end": {
432
+ const s = new Set(this._state.pendingToolCalls);
433
+ s.delete(event.toolCallId);
434
+ this._state.pendingToolCalls = s;
435
+ break;
436
+ }
437
+ case "turn_end":
438
+ if (event.message.role === "assistant" && event.message.errorMessage) {
439
+ this._state.error = event.message.errorMessage;
440
+ }
441
+ break;
442
+ case "agent_result":
443
+ this._state.lastResult = {
444
+ stopReason: event.stopReason,
445
+ loopFramework: event.loopFramework,
446
+ loopPolicy: event.loopPolicy,
447
+ turnCount: event.turnCount,
448
+ toolCallCount: event.toolCallCount,
449
+ durationMs: event.durationMs,
450
+ usage: event.usage,
451
+ permissionDenialCount: event.permissionDenialCount,
452
+ permissionDenials: event.permissionDenials,
453
+ transitions: event.transitions,
454
+ lastTransition: event.lastTransition,
455
+ errorMessage: event.errorMessage,
456
+ errorSubtype: event.errorSubtype,
457
+ };
458
+ break;
459
+ case "agent_end":
460
+ this._state.isStreaming = false;
461
+ this._state.streamMessage = null;
462
+ break;
463
+ }
464
+ // Emit to listeners
465
+ this.emit(event);
466
+ }
467
+ // Handle any remaining partial message
468
+ if (partial && partial.role === "assistant" && partial.content.length > 0) {
469
+ const onlyEmpty = !partial.content.some((c) => (c.type === "thinking" && c.thinking.trim().length > 0) ||
470
+ (c.type === "text" && c.text.trim().length > 0) ||
471
+ (c.type === "toolCall" && c.name.trim().length > 0));
472
+ if (!onlyEmpty) {
473
+ this.appendMessage(partial);
474
+ }
475
+ else {
476
+ if (this.abortController?.signal.aborted) {
477
+ throw new Error("Request was aborted");
478
+ }
479
+ }
480
+ }
481
+ }
482
+ catch (err) {
483
+ const errorMsg = {
484
+ role: "assistant",
485
+ content: [{ type: "text", text: "" }],
486
+ api: model.api,
487
+ provider: model.provider,
488
+ model: model.id,
489
+ usage: {
490
+ input: 0,
491
+ output: 0,
492
+ cacheRead: 0,
493
+ cacheWrite: 0,
494
+ totalTokens: 0,
495
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
496
+ },
497
+ stopReason: this.abortController?.signal.aborted ? "aborted" : "error",
498
+ errorMessage: err?.message || String(err),
499
+ timestamp: Date.now(),
500
+ };
501
+ this.appendMessage(errorMsg);
502
+ this._state.error = err?.message || String(err);
503
+ this.emit({ type: "message_start", message: errorMsg });
504
+ this.emit({ type: "message_end", message: errorMsg });
505
+ this.emit({ type: "agent_end", messages: [errorMsg] });
506
+ }
507
+ finally {
508
+ this._state.isStreaming = false;
509
+ this._state.streamMessage = null;
510
+ this._state.pendingToolCalls = new Set();
511
+ this.abortController = undefined;
512
+ this.resolveRunningPrompt?.();
513
+ this.runningPrompt = undefined;
514
+ this.resolveRunningPrompt = undefined;
515
+ }
516
+ }
517
+ emit(e) {
518
+ for (const listener of this.listeners) {
519
+ listener(e);
520
+ }
521
+ }
522
+ }
@@ -0,0 +1,62 @@
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 class for all agent-related errors.
9
+ * Provides structured error info (code, retriable flag) for consistent handling.
10
+ */
11
+ export declare class AgentError extends Error {
12
+ readonly code: string;
13
+ readonly retriable: boolean;
14
+ readonly details?: unknown;
15
+ constructor(message: string, code: string, retriable?: boolean, details?: unknown);
16
+ }
17
+ export declare class NetworkError extends AgentError {
18
+ readonly statusCode?: number;
19
+ constructor(message: string, statusCode?: number, details?: unknown);
20
+ }
21
+ export declare class RateLimitError extends NetworkError {
22
+ readonly retryAfterMs?: number;
23
+ constructor(message: string, retryAfterMs?: number);
24
+ }
25
+ export declare class TimeoutError extends NetworkError {
26
+ constructor(message: string, details?: unknown);
27
+ }
28
+ export declare class ConnectionError extends NetworkError {
29
+ constructor(message: string, details?: unknown);
30
+ }
31
+ export declare class ContextOverflowError extends AgentError {
32
+ readonly estimatedTokens?: number;
33
+ readonly contextWindow?: number;
34
+ constructor(message: string, estimatedTokens?: number, contextWindow?: number);
35
+ }
36
+ export declare class ToolExecutionError extends AgentError {
37
+ readonly toolName: string;
38
+ readonly toolCallId?: string;
39
+ constructor(message: string, toolName: string, toolCallId?: string);
40
+ }
41
+ export declare class ToolTimeoutError extends ToolExecutionError {
42
+ constructor(toolName: string, toolCallId: string, timeoutMs: number);
43
+ }
44
+ export declare class ToolNotFoundError extends ToolExecutionError {
45
+ constructor(toolName: string);
46
+ }
47
+ export declare class ValidationError extends AgentError {
48
+ constructor(message: string, details?: unknown);
49
+ }
50
+ export declare class ExtensionError extends AgentError {
51
+ readonly extensionName?: string;
52
+ constructor(message: string, extensionName?: string);
53
+ }
54
+ /** Type guard: is the error retriable? */
55
+ export declare function isRetriableError(error: unknown): boolean;
56
+ /** Type guard: is this a context overflow error? */
57
+ export declare function isContextOverflowError(error: unknown): boolean;
58
+ /**
59
+ * Classify an HTTP-like error (status code + message) into the appropriate AgentError subclass.
60
+ * Useful for normalizing raw provider errors into the typed hierarchy.
61
+ */
62
+ export declare function classifyApiError(statusCode: number | undefined, message: string): AgentError;