@strands-agents/sdk 1.0.0 → 1.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 (245) hide show
  1. package/dist/src/__fixtures__/agent-helpers.d.ts +16 -1
  2. package/dist/src/__fixtures__/agent-helpers.d.ts.map +1 -1
  3. package/dist/src/__fixtures__/agent-helpers.js +42 -0
  4. package/dist/src/__fixtures__/agent-helpers.js.map +1 -1
  5. package/dist/src/__fixtures__/tool-helpers.d.ts +2 -1
  6. package/dist/src/__fixtures__/tool-helpers.d.ts.map +1 -1
  7. package/dist/src/__fixtures__/tool-helpers.js +20 -3
  8. package/dist/src/__fixtures__/tool-helpers.js.map +1 -1
  9. package/dist/src/__tests__/interrupt.test.d.ts +2 -0
  10. package/dist/src/__tests__/interrupt.test.d.ts.map +1 -0
  11. package/dist/src/__tests__/interrupt.test.js +259 -0
  12. package/dist/src/__tests__/interrupt.test.js.map +1 -0
  13. package/dist/src/__tests__/mcp.test.js +226 -0
  14. package/dist/src/__tests__/mcp.test.js.map +1 -1
  15. package/dist/src/agent/__tests__/agent.hook.test.js +551 -1
  16. package/dist/src/agent/__tests__/agent.hook.test.js.map +1 -1
  17. package/dist/src/agent/__tests__/agent.interrupt.test.d.ts +2 -0
  18. package/dist/src/agent/__tests__/agent.interrupt.test.d.ts.map +1 -0
  19. package/dist/src/agent/__tests__/agent.interrupt.test.js +730 -0
  20. package/dist/src/agent/__tests__/agent.interrupt.test.js.map +1 -0
  21. package/dist/src/agent/__tests__/agent.model-retry.test.d.ts +2 -0
  22. package/dist/src/agent/__tests__/agent.model-retry.test.d.ts.map +1 -0
  23. package/dist/src/agent/__tests__/agent.model-retry.test.js +161 -0
  24. package/dist/src/agent/__tests__/agent.model-retry.test.js.map +1 -0
  25. package/dist/src/agent/__tests__/agent.test.js +118 -0
  26. package/dist/src/agent/__tests__/agent.test.js.map +1 -1
  27. package/dist/src/agent/__tests__/snapshot.test.js +50 -4
  28. package/dist/src/agent/__tests__/snapshot.test.js.map +1 -1
  29. package/dist/src/agent/agent.d.ts +35 -4
  30. package/dist/src/agent/agent.d.ts.map +1 -1
  31. package/dist/src/agent/agent.js +548 -222
  32. package/dist/src/agent/agent.js.map +1 -1
  33. package/dist/src/agent/snapshot.d.ts +2 -2
  34. package/dist/src/agent/snapshot.d.ts.map +1 -1
  35. package/dist/src/agent/snapshot.js +14 -2
  36. package/dist/src/agent/snapshot.js.map +1 -1
  37. package/dist/src/conversation-manager/__tests__/conversation-manager.test.js +230 -9
  38. package/dist/src/conversation-manager/__tests__/conversation-manager.test.js.map +1 -1
  39. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.js +19 -6
  40. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.js.map +1 -1
  41. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.js +51 -2
  42. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.js.map +1 -1
  43. package/dist/src/conversation-manager/__tests__/summarizing-conversation-manager.test.js +75 -1
  44. package/dist/src/conversation-manager/__tests__/summarizing-conversation-manager.test.js.map +1 -1
  45. package/dist/src/conversation-manager/conversation-manager.d.ts +67 -22
  46. package/dist/src/conversation-manager/conversation-manager.d.ts.map +1 -1
  47. package/dist/src/conversation-manager/conversation-manager.js +65 -13
  48. package/dist/src/conversation-manager/conversation-manager.js.map +1 -1
  49. package/dist/src/conversation-manager/index.d.ts +1 -1
  50. package/dist/src/conversation-manager/index.d.ts.map +1 -1
  51. package/dist/src/conversation-manager/index.js +1 -1
  52. package/dist/src/conversation-manager/index.js.map +1 -1
  53. package/dist/src/conversation-manager/sliding-window-conversation-manager.d.ts +17 -3
  54. package/dist/src/conversation-manager/sliding-window-conversation-manager.d.ts.map +1 -1
  55. package/dist/src/conversation-manager/sliding-window-conversation-manager.js +10 -4
  56. package/dist/src/conversation-manager/sliding-window-conversation-manager.js.map +1 -1
  57. package/dist/src/conversation-manager/summarizing-conversation-manager.d.ts +23 -1
  58. package/dist/src/conversation-manager/summarizing-conversation-manager.d.ts.map +1 -1
  59. package/dist/src/conversation-manager/summarizing-conversation-manager.js +39 -17
  60. package/dist/src/conversation-manager/summarizing-conversation-manager.js.map +1 -1
  61. package/dist/src/hooks/__tests__/events.test.js +99 -12
  62. package/dist/src/hooks/__tests__/events.test.js.map +1 -1
  63. package/dist/src/hooks/__tests__/registry.test.js +166 -2
  64. package/dist/src/hooks/__tests__/registry.test.js.map +1 -1
  65. package/dist/src/hooks/events.d.ts +102 -30
  66. package/dist/src/hooks/events.d.ts.map +1 -1
  67. package/dist/src/hooks/events.js +87 -6
  68. package/dist/src/hooks/events.js.map +1 -1
  69. package/dist/src/hooks/index.d.ts +3 -2
  70. package/dist/src/hooks/index.d.ts.map +1 -1
  71. package/dist/src/hooks/index.js +1 -0
  72. package/dist/src/hooks/index.js.map +1 -1
  73. package/dist/src/hooks/registry.d.ts +12 -12
  74. package/dist/src/hooks/registry.d.ts.map +1 -1
  75. package/dist/src/hooks/registry.js +55 -15
  76. package/dist/src/hooks/registry.js.map +1 -1
  77. package/dist/src/hooks/types.d.ts +23 -0
  78. package/dist/src/hooks/types.d.ts.map +1 -1
  79. package/dist/src/hooks/types.js +17 -1
  80. package/dist/src/hooks/types.js.map +1 -1
  81. package/dist/src/index.d.ts +9 -5
  82. package/dist/src/index.d.ts.map +1 -1
  83. package/dist/src/index.js +4 -1
  84. package/dist/src/index.js.map +1 -1
  85. package/dist/src/interrupt.d.ts +220 -0
  86. package/dist/src/interrupt.d.ts.map +1 -0
  87. package/dist/src/interrupt.js +274 -0
  88. package/dist/src/interrupt.js.map +1 -0
  89. package/dist/src/mcp.d.ts +23 -2
  90. package/dist/src/mcp.d.ts.map +1 -1
  91. package/dist/src/mcp.js +77 -18
  92. package/dist/src/mcp.js.map +1 -1
  93. package/dist/src/models/__tests__/anthropic.test.js +55 -0
  94. package/dist/src/models/__tests__/anthropic.test.js.map +1 -1
  95. package/dist/src/models/__tests__/bedrock.test.js +115 -0
  96. package/dist/src/models/__tests__/bedrock.test.js.map +1 -1
  97. package/dist/src/models/__tests__/defaults.test.d.ts +2 -0
  98. package/dist/src/models/__tests__/defaults.test.d.ts.map +1 -0
  99. package/dist/src/models/__tests__/defaults.test.js +36 -0
  100. package/dist/src/models/__tests__/defaults.test.js.map +1 -0
  101. package/dist/src/models/__tests__/google.test.js +58 -0
  102. package/dist/src/models/__tests__/google.test.js.map +1 -1
  103. package/dist/src/models/anthropic.d.ts +8 -0
  104. package/dist/src/models/anthropic.d.ts.map +1 -1
  105. package/dist/src/models/anthropic.js +4 -2
  106. package/dist/src/models/anthropic.js.map +1 -1
  107. package/dist/src/models/bedrock.d.ts +15 -0
  108. package/dist/src/models/bedrock.d.ts.map +1 -1
  109. package/dist/src/models/bedrock.js +58 -4
  110. package/dist/src/models/bedrock.js.map +1 -1
  111. package/dist/src/models/defaults.d.ts +10 -0
  112. package/dist/src/models/defaults.d.ts.map +1 -1
  113. package/dist/src/models/defaults.js +129 -0
  114. package/dist/src/models/defaults.js.map +1 -1
  115. package/dist/src/models/google/model.d.ts.map +1 -1
  116. package/dist/src/models/google/model.js +4 -2
  117. package/dist/src/models/google/model.js.map +1 -1
  118. package/dist/src/models/google/types.d.ts +8 -0
  119. package/dist/src/models/google/types.d.ts.map +1 -1
  120. package/dist/src/models/model.d.ts +15 -0
  121. package/dist/src/models/model.d.ts.map +1 -1
  122. package/dist/src/models/model.js +18 -0
  123. package/dist/src/models/model.js.map +1 -1
  124. package/dist/src/models/openai/__tests__/chat.test.js +45 -0
  125. package/dist/src/models/openai/__tests__/chat.test.js.map +1 -1
  126. package/dist/src/models/openai/model.d.ts.map +1 -1
  127. package/dist/src/models/openai/model.js +2 -2
  128. package/dist/src/models/openai/model.js.map +1 -1
  129. package/dist/src/multiagent/__tests__/graph.test.js +69 -0
  130. package/dist/src/multiagent/__tests__/graph.test.js.map +1 -1
  131. package/dist/src/multiagent/__tests__/nodes.test.js +13 -0
  132. package/dist/src/multiagent/__tests__/nodes.test.js.map +1 -1
  133. package/dist/src/multiagent/__tests__/swarm.test.js +77 -0
  134. package/dist/src/multiagent/__tests__/swarm.test.js.map +1 -1
  135. package/dist/src/multiagent/graph.d.ts +22 -2
  136. package/dist/src/multiagent/graph.d.ts.map +1 -1
  137. package/dist/src/multiagent/graph.js +42 -3
  138. package/dist/src/multiagent/graph.js.map +1 -1
  139. package/dist/src/multiagent/multiagent.d.ts +5 -3
  140. package/dist/src/multiagent/multiagent.d.ts.map +1 -1
  141. package/dist/src/multiagent/nodes.d.ts +18 -0
  142. package/dist/src/multiagent/nodes.d.ts.map +1 -1
  143. package/dist/src/multiagent/nodes.js +14 -1
  144. package/dist/src/multiagent/nodes.js.map +1 -1
  145. package/dist/src/multiagent/swarm.d.ts +15 -1
  146. package/dist/src/multiagent/swarm.d.ts.map +1 -1
  147. package/dist/src/multiagent/swarm.js +46 -3
  148. package/dist/src/multiagent/swarm.js.map +1 -1
  149. package/dist/src/registry/__tests__/tool-registry.test.js +11 -0
  150. package/dist/src/registry/__tests__/tool-registry.test.js.map +1 -1
  151. package/dist/src/registry/tool-registry.d.ts +4 -0
  152. package/dist/src/registry/tool-registry.d.ts.map +1 -1
  153. package/dist/src/registry/tool-registry.js +6 -0
  154. package/dist/src/registry/tool-registry.js.map +1 -1
  155. package/dist/src/retry/__tests__/backoff-strategy.test.d.ts +2 -0
  156. package/dist/src/retry/__tests__/backoff-strategy.test.d.ts.map +1 -0
  157. package/dist/src/retry/__tests__/backoff-strategy.test.js +116 -0
  158. package/dist/src/retry/__tests__/backoff-strategy.test.js.map +1 -0
  159. package/dist/src/retry/__tests__/default-model-retry-strategy.test.d.ts +2 -0
  160. package/dist/src/retry/__tests__/default-model-retry-strategy.test.d.ts.map +1 -0
  161. package/dist/src/retry/__tests__/default-model-retry-strategy.test.js +225 -0
  162. package/dist/src/retry/__tests__/default-model-retry-strategy.test.js.map +1 -0
  163. package/dist/src/retry/backoff-strategy.d.ts +108 -0
  164. package/dist/src/retry/backoff-strategy.d.ts.map +1 -0
  165. package/dist/src/retry/backoff-strategy.js +86 -0
  166. package/dist/src/retry/backoff-strategy.js.map +1 -0
  167. package/dist/src/retry/default-model-retry-strategy.d.ts +76 -0
  168. package/dist/src/retry/default-model-retry-strategy.d.ts.map +1 -0
  169. package/dist/src/retry/default-model-retry-strategy.js +104 -0
  170. package/dist/src/retry/default-model-retry-strategy.js.map +1 -0
  171. package/dist/src/retry/index.d.ts +8 -0
  172. package/dist/src/retry/index.d.ts.map +1 -0
  173. package/dist/src/retry/index.js +7 -0
  174. package/dist/src/retry/index.js.map +1 -0
  175. package/dist/src/retry/model-retry-strategy.d.ts +80 -0
  176. package/dist/src/retry/model-retry-strategy.d.ts.map +1 -0
  177. package/dist/src/retry/model-retry-strategy.js +85 -0
  178. package/dist/src/retry/model-retry-strategy.js.map +1 -0
  179. package/dist/src/retry/retry-strategy.d.ts +34 -0
  180. package/dist/src/retry/retry-strategy.d.ts.map +1 -0
  181. package/dist/src/retry/retry-strategy.js +25 -0
  182. package/dist/src/retry/retry-strategy.js.map +1 -0
  183. package/dist/src/session/__tests__/session-manager.test.js +39 -0
  184. package/dist/src/session/__tests__/session-manager.test.js.map +1 -1
  185. package/dist/src/session/session-manager.d.ts +6 -0
  186. package/dist/src/session/session-manager.d.ts.map +1 -1
  187. package/dist/src/session/session-manager.js +8 -0
  188. package/dist/src/session/session-manager.js.map +1 -1
  189. package/dist/src/tools/__tests__/tool.test.js +24 -1
  190. package/dist/src/tools/__tests__/tool.test.js.map +1 -1
  191. package/dist/src/tools/function-tool.d.ts.map +1 -1
  192. package/dist/src/tools/function-tool.js +6 -1
  193. package/dist/src/tools/function-tool.js.map +1 -1
  194. package/dist/src/tools/tool.d.ts +10 -1
  195. package/dist/src/tools/tool.d.ts.map +1 -1
  196. package/dist/src/tools/tool.js +12 -0
  197. package/dist/src/tools/tool.js.map +1 -1
  198. package/dist/src/tsconfig.tsbuildinfo +1 -1
  199. package/dist/src/types/agent.d.ts +22 -3
  200. package/dist/src/types/agent.d.ts.map +1 -1
  201. package/dist/src/types/agent.js +8 -0
  202. package/dist/src/types/agent.js.map +1 -1
  203. package/dist/src/types/interrupt.d.ts +103 -0
  204. package/dist/src/types/interrupt.d.ts.map +1 -0
  205. package/dist/src/types/interrupt.js +63 -0
  206. package/dist/src/types/interrupt.js.map +1 -0
  207. package/dist/src/types/messages.d.ts +2 -1
  208. package/dist/src/types/messages.d.ts.map +1 -1
  209. package/dist/src/types/messages.js.map +1 -1
  210. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.d.ts +2 -0
  211. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.d.ts.map +1 -0
  212. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.js +292 -0
  213. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.js.map +1 -0
  214. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.d.ts +2 -0
  215. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.d.ts.map +1 -0
  216. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.js +148 -0
  217. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.js.map +1 -0
  218. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.node.d.ts +2 -0
  219. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.node.d.ts.map +1 -0
  220. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.node.js +78 -0
  221. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.node.js.map +1 -0
  222. package/dist/src/vended-plugins/context-offloader/index.d.ts +23 -0
  223. package/dist/src/vended-plugins/context-offloader/index.d.ts.map +1 -0
  224. package/dist/src/vended-plugins/context-offloader/index.js +21 -0
  225. package/dist/src/vended-plugins/context-offloader/index.js.map +1 -0
  226. package/dist/src/vended-plugins/context-offloader/plugin.d.ts +48 -0
  227. package/dist/src/vended-plugins/context-offloader/plugin.d.ts.map +1 -0
  228. package/dist/src/vended-plugins/context-offloader/plugin.js +244 -0
  229. package/dist/src/vended-plugins/context-offloader/plugin.js.map +1 -0
  230. package/dist/src/vended-plugins/context-offloader/storage.d.ts +114 -0
  231. package/dist/src/vended-plugins/context-offloader/storage.d.ts.map +1 -0
  232. package/dist/src/vended-plugins/context-offloader/storage.js +204 -0
  233. package/dist/src/vended-plugins/context-offloader/storage.js.map +1 -0
  234. package/dist/src/vended-plugins/skills/__tests__/agent-skills.test.node.js +12 -0
  235. package/dist/src/vended-plugins/skills/__tests__/agent-skills.test.node.js.map +1 -1
  236. package/dist/src/vended-tools/bash/__tests__/bash.test.node.js +3 -0
  237. package/dist/src/vended-tools/bash/__tests__/bash.test.node.js.map +1 -1
  238. package/dist/src/vended-tools/bash/bash.d.ts.map +1 -1
  239. package/dist/src/vended-tools/bash/bash.js +0 -3
  240. package/dist/src/vended-tools/bash/bash.js.map +1 -1
  241. package/dist/src/vended-tools/file-editor/__tests__/file-editor.test.node.js +3 -0
  242. package/dist/src/vended-tools/file-editor/__tests__/file-editor.test.node.js.map +1 -1
  243. package/dist/src/vended-tools/notebook/__tests__/notebook.test.js +3 -0
  244. package/dist/src/vended-tools/notebook/__tests__/notebook.test.js.map +1 -1
  245. package/package.json +9 -5
@@ -0,0 +1,274 @@
1
+ /**
2
+ * Human-in-the-loop interrupt system for agent workflows.
3
+ *
4
+ * Interrupt Flow:
5
+ * 1. Hook or tool calls `event.interrupt()` or `context.interrupt()`
6
+ * 2. If resuming (response exists), the response is returned
7
+ * 3. Otherwise, agent execution halts with `stopReason: 'interrupt'`
8
+ * 4. User resumes by invoking agent with `interruptResponse` content blocks
9
+ * 5. On resume, `interrupt()` returns the user's response
10
+ */
11
+ import { InterruptResponseContent } from './types/interrupt.js';
12
+ import { Message, ToolResultBlock } from './types/messages.js';
13
+ /**
14
+ * Represents an interrupt that can pause agent execution for human-in-the-loop workflows.
15
+ */
16
+ export class Interrupt {
17
+ /**
18
+ * Unique identifier for this interrupt.
19
+ */
20
+ id;
21
+ /**
22
+ * User-defined name for the interrupt.
23
+ */
24
+ name;
25
+ /**
26
+ * User-provided reason for raising the interrupt.
27
+ */
28
+ reason;
29
+ /**
30
+ * Human response provided when resuming the agent after an interrupt.
31
+ */
32
+ response;
33
+ constructor(data) {
34
+ this.id = data.id;
35
+ this.name = data.name;
36
+ if (data.reason !== undefined) {
37
+ this.reason = data.reason;
38
+ }
39
+ if (data.response !== undefined) {
40
+ this.response = data.response;
41
+ }
42
+ }
43
+ /**
44
+ * Serializes the interrupt to a JSON-compatible object.
45
+ */
46
+ toJSON() {
47
+ return {
48
+ id: this.id,
49
+ name: this.name,
50
+ ...(this.reason !== undefined && { reason: this.reason }),
51
+ ...(this.response !== undefined && { response: this.response }),
52
+ };
53
+ }
54
+ /**
55
+ * Creates an Interrupt instance from a JSON object.
56
+ *
57
+ * @param data - JSON data to deserialize
58
+ * @returns Interrupt instance
59
+ */
60
+ static fromJSON(data) {
61
+ return new Interrupt(data);
62
+ }
63
+ }
64
+ /**
65
+ * Error thrown when human input is required to continue agent execution.
66
+ * Caught by the agent loop to trigger an interrupt stop.
67
+ */
68
+ export class InterruptError extends Error {
69
+ /**
70
+ * The interrupts that caused this error.
71
+ */
72
+ interrupts;
73
+ constructor(interrupt) {
74
+ const all = Array.isArray(interrupt) ? interrupt : [interrupt];
75
+ const message = all.length === 1
76
+ ? `Interrupt raised: ${all[0].name}`
77
+ : `${all.length} interrupts raised: ${all.map((i) => i.name).join(', ')}`;
78
+ super(message);
79
+ this.name = 'InterruptError';
80
+ this.interrupts = all;
81
+ }
82
+ }
83
+ /**
84
+ * Tracks the state of interrupt events raised during agent execution.
85
+ *
86
+ * Interrupt state is cleared after resuming.
87
+ */
88
+ export class InterruptState {
89
+ /** Record of interrupt IDs to Interrupt instances. */
90
+ interrupts;
91
+ /** Resume responses provided when resuming from an interrupt. */
92
+ resumeResponses;
93
+ /** Whether the agent is in an interrupted state. */
94
+ activated;
95
+ /** Pending tool execution state for resume. */
96
+ pendingToolExecution;
97
+ constructor() {
98
+ this.interrupts = {};
99
+ this.resumeResponses = undefined;
100
+ this.activated = false;
101
+ this.pendingToolExecution = undefined;
102
+ }
103
+ /**
104
+ * Gets the pending tool execution state with reconstructed Message and ToolResultBlock objects.
105
+ * Returns undefined if there is no pending execution.
106
+ */
107
+ getPendingExecution() {
108
+ if (!this.pendingToolExecution) {
109
+ return undefined;
110
+ }
111
+ const assistantMessage = Message.fromMessageData(this.pendingToolExecution.assistantMessageData);
112
+ const completedToolResults = new Map();
113
+ for (const [toolUseId, resultData] of Object.entries(this.pendingToolExecution.completedToolResults)) {
114
+ completedToolResults.set(toolUseId, ToolResultBlock.fromJSON(resultData));
115
+ }
116
+ return { assistantMessage, completedToolResults };
117
+ }
118
+ /**
119
+ * Sets the pending tool execution state.
120
+ */
121
+ setPendingToolExecution(pending) {
122
+ this.pendingToolExecution = pending;
123
+ }
124
+ /**
125
+ * Clears the pending tool execution state.
126
+ */
127
+ clearPendingToolExecution() {
128
+ this.pendingToolExecution = undefined;
129
+ }
130
+ /**
131
+ * Returns the list of interrupts as an array.
132
+ */
133
+ getInterruptsList() {
134
+ return Object.values(this.interrupts);
135
+ }
136
+ /**
137
+ * Returns all interrupts that have no response (i.e., were raised but not yet answered).
138
+ */
139
+ getUnansweredInterrupts() {
140
+ return Object.values(this.interrupts).filter((interrupt) => interrupt.response === undefined);
141
+ }
142
+ /**
143
+ * Returns the first interrupt that has no response (i.e., was raised but not yet answered).
144
+ */
145
+ getUnansweredInterrupt() {
146
+ for (const interrupt of Object.values(this.interrupts)) {
147
+ if (interrupt.response === undefined) {
148
+ return interrupt;
149
+ }
150
+ }
151
+ return undefined;
152
+ }
153
+ /**
154
+ * Activates the interrupt state.
155
+ */
156
+ activate() {
157
+ this.activated = true;
158
+ }
159
+ /**
160
+ * Deactivates the interrupt state and clears all interrupts and context.
161
+ */
162
+ deactivate() {
163
+ this.interrupts = {};
164
+ this.resumeResponses = undefined;
165
+ this.activated = false;
166
+ this.pendingToolExecution = undefined;
167
+ }
168
+ /**
169
+ * Configures the interrupt state for resuming from an interrupt.
170
+ * Populates interrupt responses from the provided content blocks.
171
+ *
172
+ * @param responses - Array of interrupt response content blocks
173
+ * @throws Error if an interrupt ID is not found
174
+ */
175
+ resume(responses) {
176
+ if (!this.activated) {
177
+ return;
178
+ }
179
+ for (const content of responses) {
180
+ const interruptId = content.interruptResponse.interruptId;
181
+ const response = content.interruptResponse.response;
182
+ const interrupt = this.interrupts[interruptId];
183
+ if (!interrupt) {
184
+ throw new Error(`interrupt_id=<${interruptId}> | no interrupt found`);
185
+ }
186
+ interrupt.response = response;
187
+ }
188
+ this.resumeResponses = responses;
189
+ }
190
+ /**
191
+ * Gets or creates an interrupt with the given ID.
192
+ * If the interrupt already exists, returns it (potentially with a response).
193
+ * If a preemptive response is provided and the interrupt is new, the response
194
+ * is stored on the interrupt so it returns immediately without halting execution.
195
+ *
196
+ * @param id - Unique identifier for the interrupt
197
+ * @param name - User-defined name for the interrupt
198
+ * @param reason - Optional reason for the interrupt
199
+ * @param response - Optional preemptive response to skip the interrupt
200
+ * @returns The interrupt (may have a response if resuming or preemptive)
201
+ */
202
+ getOrCreateInterrupt(id, name, reason, response) {
203
+ const existing = this.interrupts[id];
204
+ if (existing) {
205
+ return existing;
206
+ }
207
+ const interrupt = new Interrupt({
208
+ id,
209
+ name,
210
+ ...(reason !== undefined && { reason }),
211
+ ...(response !== undefined && { response }),
212
+ });
213
+ this.interrupts[id] = interrupt;
214
+ return interrupt;
215
+ }
216
+ /**
217
+ * Serializes the interrupt state to a JSON-compatible object.
218
+ */
219
+ toJSON() {
220
+ const interrupts = {};
221
+ for (const [id, interrupt] of Object.entries(this.interrupts)) {
222
+ interrupts[id] = interrupt.toJSON();
223
+ }
224
+ return {
225
+ interrupts,
226
+ ...(this.resumeResponses && { resumeResponses: this.resumeResponses }),
227
+ activated: this.activated,
228
+ ...(this.pendingToolExecution && { pendingToolExecution: this.pendingToolExecution }),
229
+ };
230
+ }
231
+ /**
232
+ * Creates an InterruptState instance from a JSON object.
233
+ *
234
+ * @param data - JSON data to deserialize
235
+ * @returns InterruptState instance
236
+ */
237
+ static fromJSON(data) {
238
+ const state = new InterruptState();
239
+ state.activated = data.activated;
240
+ for (const [id, interruptData] of Object.entries(data.interrupts)) {
241
+ state.interrupts[id] = Interrupt.fromJSON(interruptData);
242
+ }
243
+ if (data.resumeResponses) {
244
+ state.resumeResponses = data.resumeResponses.map((r) => InterruptResponseContent.fromJSON(r));
245
+ }
246
+ if (data.pendingToolExecution) {
247
+ state.pendingToolExecution = data.pendingToolExecution;
248
+ }
249
+ return state;
250
+ }
251
+ }
252
+ /**
253
+ * Shared interrupt logic that accesses the agent's interrupt state to register or resume an interrupt.
254
+ *
255
+ * @param agent - The agent whose interrupt state to access
256
+ * @param interruptId - Unique identifier for this interrupt instance
257
+ * @param params - Interrupt parameters including name and optional reason
258
+ * @returns The user's response when resuming from an interrupt
259
+ * @throws InterruptError when no response is available (first invocation)
260
+ *
261
+ * @internal
262
+ */
263
+ export function interruptFromAgent(agent, interruptId, params) {
264
+ const interruptState = agent._interruptState;
265
+ if (!interruptState) {
266
+ throw new Error('Interrupt state not available');
267
+ }
268
+ const interrupt = interruptState.getOrCreateInterrupt(interruptId, params.name, params.reason, params.response);
269
+ if (interrupt.response !== undefined) {
270
+ return interrupt.response;
271
+ }
272
+ throw new InterruptError(interrupt);
273
+ }
274
+ //# sourceMappingURL=interrupt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interrupt.js","sourceRoot":"","sources":["../../src/interrupt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,wBAAwB,EAA2D,MAAM,sBAAsB,CAAA;AAGxH,OAAO,EAAE,OAAO,EAAE,eAAe,EAA8C,MAAM,qBAAqB,CAAA;AAE1G;;GAEG;AACH,MAAM,OAAO,SAAS;IACpB;;OAEG;IACM,EAAE,CAAQ;IAEnB;;OAEG;IACM,IAAI,CAAQ;IAErB;;OAEG;IACM,MAAM,CAAY;IAE3B;;OAEG;IACH,QAAQ,CAAY;IAEpB,YAAY,IAA4E;QACtF,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAA;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;QACrB,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC9B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QAC3B,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC/B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO;YACL,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;YACzD,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;SAChE,CAAA;IACH,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,CAAC,IAA4E;QAC1F,OAAO,IAAI,SAAS,CAAC,IAAI,CAAC,CAAA;IAC5B,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC;;OAEG;IACM,UAAU,CAAa;IAEhC,YAAY,SAAkC;QAC5C,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;QAC9D,MAAM,OAAO,GACX,GAAG,CAAC,MAAM,KAAK,CAAC;YACd,CAAC,CAAC,qBAAqB,GAAG,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE;YACrC,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,uBAAuB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;QAC7E,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAA;QAC5B,IAAI,CAAC,UAAU,GAAG,GAAG,CAAA;IACvB,CAAC;CACF;AA4CD;;;;GAIG;AACH,MAAM,OAAO,cAAc;IACzB,sDAAsD;IACtD,UAAU,CAA2B;IAErC,iEAAiE;IACjE,eAAe,CAAyC;IAExD,oDAAoD;IACpD,SAAS,CAAS;IAElB,+CAA+C;IAC/C,oBAAoB,CAAmC;IAEvD;QACE,IAAI,CAAC,UAAU,GAAG,EAAE,CAAA;QACpB,IAAI,CAAC,eAAe,GAAG,SAAS,CAAA;QAChC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAA;QACtB,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAA;IACvC,CAAC;IAED;;;OAGG;IACH,mBAAmB;QACjB,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC/B,OAAO,SAAS,CAAA;QAClB,CAAC;QAED,MAAM,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,oBAAoB,CAAC,oBAAoB,CAAC,CAAA;QAEhG,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAA2B,CAAA;QAC/D,KAAK,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,oBAAoB,CAAC,EAAE,CAAC;YACrG,oBAAoB,CAAC,GAAG,CAAC,SAAS,EAAE,eAAe,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAA;QAC3E,CAAC;QAED,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,CAAA;IACnD,CAAC;IAED;;OAEG;IACH,uBAAuB,CAAC,OAA6B;QACnD,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAA;IACrC,CAAC;IAED;;OAEG;IACH,yBAAyB;QACvB,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAA;IACvC,CAAC;IAED;;OAEG;IACH,iBAAiB;QACf,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACvC,CAAC;IAED;;OAEG;IACH,uBAAuB;QACrB,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAA;IAC/F,CAAC;IAED;;OAEG;IACH,sBAAsB;QACpB,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YACvD,IAAI,SAAS,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;gBACrC,OAAO,SAAS,CAAA;YAClB,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAA;IAClB,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,IAAI,CAAC,SAAS,GAAG,IAAI,CAAA;IACvB,CAAC;IAED;;OAEG;IACH,UAAU;QACR,IAAI,CAAC,UAAU,GAAG,EAAE,CAAA;QACpB,IAAI,CAAC,eAAe,GAAG,SAAS,CAAA;QAChC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAA;QACtB,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAA;IACvC,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,SAAqC;QAC1C,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAM;QACR,CAAC;QAED,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,CAAC;YAChC,MAAM,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAA;YACzD,MAAM,QAAQ,GAAG,OAAO,CAAC,iBAAiB,CAAC,QAAQ,CAAA;YAEnD,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;YAC9C,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,iBAAiB,WAAW,wBAAwB,CAAC,CAAA;YACvE,CAAC;YAED,SAAS,CAAC,QAAQ,GAAG,QAAQ,CAAA;QAC/B,CAAC;QAED,IAAI,CAAC,eAAe,GAAG,SAAS,CAAA;IAClC,CAAC;IAED;;;;;;;;;;;OAWG;IACH,oBAAoB,CAAC,EAAU,EAAE,IAAY,EAAE,MAAkB,EAAE,QAAoB;QACrF,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;QACpC,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,QAAQ,CAAA;QACjB,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC;YAC9B,EAAE;YACF,IAAI;YACJ,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,CAAC;YACvC,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,CAAC;SAC5C,CAAC,CAAA;QACF,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,SAAS,CAAA;QAC/B,OAAO,SAAS,CAAA;IAClB,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,MAAM,UAAU,GAA2F,EAAE,CAAA;QAC7G,KAAK,MAAM,CAAC,EAAE,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9D,UAAU,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAA;QACrC,CAAC;QAED,OAAO;YACL,UAAU;YACV,GAAG,CAAC,IAAI,CAAC,eAAe,IAAI,EAAE,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC;YACtE,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,GAAG,CAAC,IAAI,CAAC,oBAAoB,IAAI,EAAE,oBAAoB,EAAE,IAAI,CAAC,oBAAoB,EAAE,CAAC;SACtF,CAAA;IACH,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAwB;QACtC,MAAM,KAAK,GAAG,IAAI,cAAc,EAAE,CAAA;QAClC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAA;QAEhC,KAAK,MAAM,CAAC,EAAE,EAAE,aAAa,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YAClE,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAA;QAC1D,CAAC;QAED,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,KAAK,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,wBAAwB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;QAC/F,CAAC;QAED,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC9B,KAAK,CAAC,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,CAAA;QACxD,CAAC;QAED,OAAO,KAAK,CAAA;IACd,CAAC;CACF;AAUD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAAI,KAAiB,EAAE,WAAmB,EAAE,MAAuB;IACnG,MAAM,cAAc,GAAI,KAAyD,CAAC,eAAe,CAAA;IACjG,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAA;IAClD,CAAC;IAED,MAAM,SAAS,GAAG,cAAc,CAAC,oBAAoB,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAA;IAE/G,IAAI,SAAS,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACrC,OAAO,SAAS,CAAC,QAAa,CAAA;IAChC,CAAC;IAED,MAAM,IAAI,cAAc,CAAC,SAAS,CAAC,CAAA;AACrC,CAAC"}
package/dist/src/mcp.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
2
  import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
3
+ import { type ServerCapabilities, type Implementation, type LoggingMessageNotificationParams } from '@modelcontextprotocol/sdk/types.js';
3
4
  import type { JSONValue } from './types/json.js';
4
5
  import type { ElicitationCallback } from './types/elicitation.js';
5
6
  import { McpTool } from './tools/mcp-tool.js';
@@ -41,6 +42,8 @@ export interface TasksConfig {
41
42
  */
42
43
  pollTimeout?: number;
43
44
  }
45
+ /** Connection state of an MCP client. */
46
+ export type McpConnectionState = 'disconnected' | 'connected' | 'failed';
44
47
  /** Arguments for configuring an MCP Client. */
45
48
  export type McpClientConfig = RuntimeConfig & {
46
49
  transport: McpTransport;
@@ -58,6 +61,10 @@ export type McpClientConfig = RuntimeConfig & {
58
61
  * and routes incoming elicitation requests to this callback.
59
62
  */
60
63
  elicitationCallback?: ElicitationCallback;
64
+ /** When true, connection failures are logged as warnings instead of throwing. */
65
+ failOpen?: boolean;
66
+ /** Called when the server emits a log message. Defaults to routing through the Strands logger. */
67
+ logHandler?: (params: LoggingMessageNotificationParams) => void;
61
68
  };
62
69
  /** MCP Client for interacting with Model Context Protocol servers. */
63
70
  export declare class McpClient {
@@ -68,18 +75,27 @@ export declare class McpClient {
68
75
  private _clientName;
69
76
  private _clientVersion;
70
77
  private _transport;
71
- private _connected;
78
+ private _state;
72
79
  private _client;
80
+ private _failOpen;
81
+ private _logHandler;
73
82
  private _disableMcpInstrumentation;
74
83
  private _tasksConfig;
75
84
  private _elicitationCallback;
76
85
  constructor(args: McpClientConfig);
77
86
  get client(): Client;
87
+ get serverCapabilities(): ServerCapabilities | undefined;
88
+ get serverVersion(): Implementation | undefined;
89
+ get serverInstructions(): string | undefined;
90
+ get connectionState(): McpConnectionState;
78
91
  /**
79
92
  * Connects the MCP client to the server.
80
93
  *
81
- * This function is exposed to allow consumers to connect manually, but will be called lazily before any operations that require a connection.
94
+ * Called lazily before any operation that requires a connection. When `failOpen` is true,
95
+ * connection failures are swallowed and the client enters a `'failed'` state — subsequent
96
+ * calls are no-ops until `connect(true)` is called explicitly to retry.
82
97
  *
98
+ * @param reconnect - When true, forces a reconnect even if already connected or failed.
83
99
  * @returns A promise that resolves when the connection is established.
84
100
  */
85
101
  connect(reconnect?: boolean): Promise<void>;
@@ -89,6 +105,11 @@ export declare class McpClient {
89
105
  * @returns A promise that resolves when the disconnection is complete.
90
106
  */
91
107
  disconnect(): Promise<void>;
108
+ /**
109
+ * Enables the `await using` pattern for automatic resource cleanup.
110
+ * Delegates to {@link McpClient.disconnect}.
111
+ */
112
+ [Symbol.asyncDispose](): Promise<void>;
92
113
  /**
93
114
  * Lists the tools available on the server and returns them as executable McpTool instances.
94
115
  *
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAA;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAA;AAI9E,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC5D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAG7C;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAA;AAE5F,8CAA8C;AAC9C,MAAM,WAAW,aAAa;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IAEZ;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,+CAA+C;AAC/C,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG;IAC5C,SAAS,EAAE,YAAY,CAAA;IAEvB,iDAAiD;IACjD,yBAAyB,CAAC,EAAE,OAAO,CAAA;IAEnC;;;;OAIG;IACH,WAAW,CAAC,EAAE,WAAW,CAAA;IAEzB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,mBAAmB,CAAA;CAC1C,CAAA;AAED,sEAAsE;AACtE,qBAAa,SAAS;IACpB,iEAAiE;IACjE,gBAAuB,WAAW,SAAQ;IAE1C,4EAA4E;IAC5E,gBAAuB,oBAAoB,UAAS;IAEpD,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,UAAU,CAAW;IAC7B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,0BAA0B,CAAS;IAC3C,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,oBAAoB,CAAiC;gBAEjD,IAAI,EAAE,eAAe;IAkBjC,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;;;;;OAMG;IACU,OAAO,CAAC,SAAS,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAqB/D;;;;OAIG;IACU,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAOxC;;;;OAIG;IACU,SAAS,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAgB5C;;;;;;;;;;OAUG;IACU,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;CAqC1E"}
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAA;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAA;AAE9E,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,gCAAgC,EACtC,MAAM,oCAAoC,CAAA;AAE3C,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC5D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAG7C;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAA;AAE5F,8CAA8C;AAC9C,MAAM,WAAW,aAAa;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IAEZ;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,yCAAyC;AACzC,MAAM,MAAM,kBAAkB,GAAG,cAAc,GAAG,WAAW,GAAG,QAAQ,CAAA;AAExE,+CAA+C;AAC/C,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG;IAC5C,SAAS,EAAE,YAAY,CAAA;IAEvB,iDAAiD;IACjD,yBAAyB,CAAC,EAAE,OAAO,CAAA;IAEnC;;;;OAIG;IACH,WAAW,CAAC,EAAE,WAAW,CAAA;IAEzB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,mBAAmB,CAAA;IAEzC,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,CAAA;IAElB,kGAAkG;IAClG,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,gCAAgC,KAAK,IAAI,CAAA;CAChE,CAAA;AAED,sEAAsE;AACtE,qBAAa,SAAS;IACpB,iEAAiE;IACjE,gBAAuB,WAAW,SAAQ;IAE1C,4EAA4E;IAC5E,gBAAuB,oBAAoB,UAAS;IAEpD,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,UAAU,CAAW;IAC7B,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAoD;IACvE,OAAO,CAAC,0BAA0B,CAAS;IAC3C,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,oBAAoB,CAAiC;gBAEjD,IAAI,EAAE,eAAe;IAwBjC,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,kBAAkB,IAAI,kBAAkB,GAAG,SAAS,CAEvD;IAED,IAAI,aAAa,IAAI,cAAc,GAAG,SAAS,CAE9C;IAED,IAAI,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAE3C;IAED,IAAI,eAAe,IAAI,kBAAkB,CAExC;IAED;;;;;;;;;OASG;IACU,OAAO,CAAC,SAAS,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B/D;;;;OAIG;IACU,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAOxC;;;OAGG;IACG,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5C;;;;OAIG;IACU,SAAS,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IA4B5C;;;;;;;;;;OAUG;IACU,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;CAsC1E"}
package/dist/src/mcp.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
2
  import { takeResult } from '@modelcontextprotocol/sdk/shared/responseMessage.js';
3
- import { ElicitRequestSchema } from '@modelcontextprotocol/sdk/types.js';
3
+ import { ElicitRequestSchema, LoggingMessageNotificationSchema, } from '@modelcontextprotocol/sdk/types.js';
4
4
  import { context, propagation, trace } from '@opentelemetry/api';
5
5
  import { McpTool } from './tools/mcp-tool.js';
6
6
  import { logger } from './logging/index.js';
@@ -13,8 +13,10 @@ export class McpClient {
13
13
  _clientName;
14
14
  _clientVersion;
15
15
  _transport;
16
- _connected;
16
+ _state;
17
17
  _client;
18
+ _failOpen;
19
+ _logHandler;
18
20
  _disableMcpInstrumentation;
19
21
  _tasksConfig;
20
22
  _elicitationCallback;
@@ -22,32 +24,51 @@ export class McpClient {
22
24
  this._clientName = args.applicationName || 'strands-agents-ts-sdk';
23
25
  this._clientVersion = args.applicationVersion || '0.0.1';
24
26
  this._transport = args.transport;
25
- this._connected = false;
27
+ this._state = 'disconnected';
28
+ this._failOpen = args.failOpen ?? false;
29
+ this._logHandler = args.logHandler ?? defaultLogHandler;
26
30
  this._tasksConfig = args.tasksConfig;
27
31
  this._elicitationCallback = args.elicitationCallback;
28
32
  this._client = new Client({
29
33
  name: this._clientName,
30
34
  version: this._clientVersion,
31
35
  }, this._elicitationCallback ? { capabilities: { elicitation: { form: {}, url: {} } } } : undefined);
36
+ this._client.setNotificationHandler(LoggingMessageNotificationSchema, (notification) => {
37
+ this._logHandler(notification.params);
38
+ });
32
39
  this._disableMcpInstrumentation = args.disableMcpInstrumentation ?? false;
33
40
  }
34
41
  get client() {
35
42
  return this._client;
36
43
  }
44
+ get serverCapabilities() {
45
+ return this._client.getServerCapabilities();
46
+ }
47
+ get serverVersion() {
48
+ return this._client.getServerVersion();
49
+ }
50
+ get serverInstructions() {
51
+ return this._client.getInstructions();
52
+ }
53
+ get connectionState() {
54
+ return this._state;
55
+ }
37
56
  /**
38
57
  * Connects the MCP client to the server.
39
58
  *
40
- * This function is exposed to allow consumers to connect manually, but will be called lazily before any operations that require a connection.
59
+ * Called lazily before any operation that requires a connection. When `failOpen` is true,
60
+ * connection failures are swallowed and the client enters a `'failed'` state — subsequent
61
+ * calls are no-ops until `connect(true)` is called explicitly to retry.
41
62
  *
63
+ * @param reconnect - When true, forces a reconnect even if already connected or failed.
42
64
  * @returns A promise that resolves when the connection is established.
43
65
  */
44
66
  async connect(reconnect = false) {
45
- if (this._connected && !reconnect) {
67
+ if (this._state !== 'disconnected' && !reconnect)
46
68
  return;
47
- }
48
- if (this._connected && reconnect) {
69
+ if (this._state === 'connected' && reconnect) {
49
70
  await this._client.close();
50
- this._connected = false;
71
+ this._state = 'disconnected';
51
72
  }
52
73
  if (this._elicitationCallback) {
53
74
  const callback = this._elicitationCallback;
@@ -55,8 +76,16 @@ export class McpClient {
55
76
  return await callback(extra, request.params);
56
77
  });
57
78
  }
58
- await this._client.connect(this._transport);
59
- this._connected = true;
79
+ try {
80
+ await this._client.connect(this._transport);
81
+ this._state = 'connected';
82
+ }
83
+ catch (error) {
84
+ if (!this._failOpen)
85
+ throw error;
86
+ this._state = 'failed';
87
+ logger.warn(`client=<${this._clientName}>, error=<${error}> | MCP server failed to connect, continuing with failOpen`);
88
+ }
60
89
  }
61
90
  /**
62
91
  * Disconnects the MCP client from the server and cleans up resources.
@@ -67,7 +96,14 @@ export class McpClient {
67
96
  // Must be done sequentially
68
97
  await this._client.close();
69
98
  await this._transport.close();
70
- this._connected = false;
99
+ this._state = 'disconnected';
100
+ }
101
+ /**
102
+ * Enables the `await using` pattern for automatic resource cleanup.
103
+ * Delegates to {@link McpClient.disconnect}.
104
+ */
105
+ async [Symbol.asyncDispose]() {
106
+ await this.disconnect();
71
107
  }
72
108
  /**
73
109
  * Lists the tools available on the server and returns them as executable McpTool instances.
@@ -76,16 +112,21 @@ export class McpClient {
76
112
  */
77
113
  async listTools() {
78
114
  await this.connect();
79
- const result = await this._client.listTools();
80
- // Map the tool specifications to fully functional McpTool instances
81
- return result.tools.map((toolSpec) => {
82
- return new McpTool({
115
+ if (this._state === 'failed')
116
+ return [];
117
+ const tools = [];
118
+ let cursor;
119
+ do {
120
+ const result = await this._client.listTools(cursor ? { cursor } : undefined);
121
+ tools.push(...result.tools.map((toolSpec) => new McpTool({
83
122
  name: toolSpec.name,
84
- description: toolSpec.description ?? '',
123
+ description: toolSpec.description || `Tool which performs ${toolSpec.name}`,
85
124
  inputSchema: toolSpec.inputSchema,
86
125
  client: this,
87
- });
88
- });
126
+ })));
127
+ cursor = result.nextCursor;
128
+ } while (cursor);
129
+ return tools;
89
130
  }
90
131
  /**
91
132
  * Invoke a tool on the connected MCP server using an McpTool instance.
@@ -100,6 +141,8 @@ export class McpClient {
100
141
  */
101
142
  async callTool(tool, args) {
102
143
  await this.connect();
144
+ if (this._state === 'failed')
145
+ throw new Error('MCP server failed to connect. Call connect(true) to retry.');
103
146
  if (args === null || args === undefined) {
104
147
  return await this.callTool(tool, {});
105
148
  }
@@ -125,6 +168,22 @@ export class McpClient {
125
168
  return result;
126
169
  }
127
170
  }
171
+ function defaultLogHandler(params) {
172
+ const { level, logger: serverLogger, data } = params;
173
+ const message = `logger=<${serverLogger ?? 'mcp'}>, data=<${JSON.stringify(data)}> | MCP server log`;
174
+ if (level === 'debug') {
175
+ logger.debug(message);
176
+ }
177
+ else if (level === 'info' || level === 'notice') {
178
+ logger.info(message);
179
+ }
180
+ else if (level === 'warning') {
181
+ logger.warn(message);
182
+ }
183
+ else {
184
+ logger.error(message);
185
+ }
186
+ }
128
187
  /**
129
188
  * Injects OpenTelemetry trace context into MCP tool call arguments.
130
189
  * Returns the args with a `_meta` field containing W3C traceparent headers.
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/mcp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/mcp.ts"],"names":[],"mappings":"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"}
@@ -100,6 +100,41 @@ describe('AnthropicModel', () => {
100
100
  new AnthropicModel({ apiKey: 'sk-ant-test', modelId: 'claude-3-opus-20240229' });
101
101
  expect(warnOnce).not.toHaveBeenCalledWith(expect.objectContaining({ warn: expect.any(Function) }), expect.stringContaining('using default modelId'));
102
102
  });
103
+ it('auto-populates contextWindowLimit from model ID lookup', () => {
104
+ const provider = new AnthropicModel({ apiKey: 'sk-test', modelId: 'claude-sonnet-4-20250514' });
105
+ expect(provider.getConfig()).toStrictEqual({
106
+ modelId: 'claude-sonnet-4-20250514',
107
+ maxTokens: 64_000,
108
+ contextWindowLimit: 1_000_000,
109
+ });
110
+ });
111
+ it('auto-populates contextWindowLimit for default model ID', () => {
112
+ const provider = new AnthropicModel({ apiKey: 'sk-test' });
113
+ expect(provider.getConfig()).toStrictEqual({
114
+ modelId: 'claude-sonnet-4-6',
115
+ maxTokens: 64_000,
116
+ contextWindowLimit: 1_000_000,
117
+ });
118
+ });
119
+ it('does not override explicit contextWindowLimit', () => {
120
+ const provider = new AnthropicModel({
121
+ apiKey: 'sk-test',
122
+ modelId: 'claude-sonnet-4-20250514',
123
+ contextWindowLimit: 100_000,
124
+ });
125
+ expect(provider.getConfig()).toStrictEqual({
126
+ modelId: 'claude-sonnet-4-20250514',
127
+ maxTokens: 64_000,
128
+ contextWindowLimit: 100_000,
129
+ });
130
+ });
131
+ it('leaves contextWindowLimit undefined for unknown model IDs', () => {
132
+ const provider = new AnthropicModel({ apiKey: 'sk-test', modelId: 'unknown-model' });
133
+ expect(provider.getConfig()).toStrictEqual({
134
+ modelId: 'unknown-model',
135
+ maxTokens: 64_000,
136
+ });
137
+ });
103
138
  });
104
139
  describe('updateConfig', () => {
105
140
  it('merges new config with existing config', () => {
@@ -110,6 +145,18 @@ describe('AnthropicModel', () => {
110
145
  maxTokens: 8192,
111
146
  });
112
147
  });
148
+ it('re-resolves contextWindowLimit when modelId changes and it was auto-resolved', () => {
149
+ const provider = new AnthropicModel({ apiKey: 'sk-test' });
150
+ expect(provider.getConfig().contextWindowLimit).toBe(1_000_000); // claude-sonnet-4-6 default
151
+ provider.updateConfig({ modelId: 'claude-sonnet-4-20250514' });
152
+ expect(provider.getConfig().contextWindowLimit).toBe(1_000_000); // claude-sonnet-4-20250514 value
153
+ });
154
+ it('preserves explicit contextWindowLimit when modelId changes', () => {
155
+ const provider = new AnthropicModel({ apiKey: 'sk-test', contextWindowLimit: 50_000 });
156
+ expect(provider.getConfig().contextWindowLimit).toBe(50_000);
157
+ provider.updateConfig({ modelId: 'claude-sonnet-4-20250514' });
158
+ expect(provider.getConfig().contextWindowLimit).toBe(50_000); // preserved
159
+ });
113
160
  });
114
161
  describe('stream event handling', () => {
115
162
  it('yields correct event sequence for simple text response', async () => {
@@ -639,6 +686,14 @@ describe('AnthropicModel', () => {
639
686
  expect(typeof result).toBe('number');
640
687
  expect(result).toBeGreaterThanOrEqual(0);
641
688
  });
689
+ it('should skip native API and use heuristic when useNativeTokenCount is false', async () => {
690
+ const mockCountTokens = vi.fn();
691
+ const client = createCountTokensClient(mockCountTokens);
692
+ const model = new AnthropicModel({ client, modelId: 'claude-sonnet-4-6', useNativeTokenCount: false });
693
+ const result = await model.countTokens(messages);
694
+ expect(mockCountTokens).not.toHaveBeenCalled();
695
+ expect(result).toBe(2); // heuristic: Math.ceil('hello'.length / 4)
696
+ });
642
697
  });
643
698
  });
644
699
  //# sourceMappingURL=anthropic.test.js.map