@aws-blocks/bb-agent 0.3.1 → 0.3.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
package/dist/agent.js CHANGED
@@ -6,13 +6,10 @@ import { Realtime } from '@aws-blocks/bb-realtime';
6
6
  import { AsyncJob } from '@aws-blocks/bb-async-job';
7
7
  import { FileBucket } from '@aws-blocks/bb-file-bucket';
8
8
  import { Logger } from '@aws-blocks/bb-logger';
9
- import { Agent as StrandsAgent, tool, SessionManager, ModelStreamUpdateEvent, AfterToolCallEvent, BeforeToolCallEvent, AgentResultEvent } from '@strands-agents/sdk';
10
- import { InterruptResponseContent } from '@strands-agents/sdk';
11
9
  import { z } from 'zod';
12
10
  import { createStrandsModel, checkModelHealth } from './model-factory.js';
13
11
  import { messageSchema, conversationSchema, agentStreamChunkSchema } from './schemas.js';
14
12
  import { AgentErrors, blocksAgentError, InterruptError } from './errors.js';
15
- import { SlidingWindowConversationManager, SummarizingConversationManager } from '@strands-agents/sdk';
16
13
  import { BB_NAME, BB_VERSION } from './version.js';
17
14
  import { ulid } from 'ulid';
18
15
  /** Payload submitted to the internal AsyncJob BB. */
@@ -28,6 +25,25 @@ const jobPayloadSchema = z.object({
28
25
  });
29
26
  /** Key under which the per-call tool context is threaded through Strands `invocationState`. */
30
27
  const TOOL_CONTEXT_KEY = '__bbAgentToolContext';
28
+ /**
29
+ * Lazily import the Strands SDK runtime, caching the module after the first load.
30
+ *
31
+ * Importing the Agent BB must not eagerly evaluate `@strands-agents/sdk`: the
32
+ * `@aws-blocks/blocks` umbrella re-exports `Agent` statically, so a static top-level
33
+ * import here would load Strands — and its non-optional `@modelcontextprotocol/sdk`
34
+ * and `@opentelemetry/api` peers — for every app that touches the umbrella, even
35
+ * ones that never create an agent (see issue #153). Deferring the import to first
36
+ * agent execution keeps those packages off the load path for non-agent apps.
37
+ */
38
+ let strandsModulePromise;
39
+ function loadStrands() {
40
+ strandsModulePromise ??= import('@strands-agents/sdk').catch((err) => {
41
+ // Don't cache a rejected import — clear the slot so a later call can retry.
42
+ strandsModulePromise = undefined;
43
+ return Promise.reject(err);
44
+ });
45
+ return strandsModulePromise;
46
+ }
31
47
  /**
32
48
  * The per-call tool factory handed to the `tools` callback. At runtime it's an identity
33
49
  * function whose only job is to give TypeScript a single call site per tool where it can
@@ -54,7 +70,8 @@ function resolveTools(toolsConfig) {
54
70
  * Controls how message history is trimmed in-memory before sending to the model. Does not handle persistence.
55
71
  * @see https://strandsagents.com/docs/user-guide/concepts/agents/conversation-management/
56
72
  */
57
- function createConversationManager(config) {
73
+ async function createConversationManager(config) {
74
+ const { SlidingWindowConversationManager, SummarizingConversationManager } = await loadStrands();
58
75
  if (!config || !config.strategy || config.strategy === 'sliding-window') {
59
76
  const windowSize = config && 'windowSize' in config ? config.windowSize : undefined;
60
77
  return new SlidingWindowConversationManager({ windowSize });
@@ -174,6 +191,7 @@ export class AgentBase extends Scope {
174
191
  * TODO add comments for args
175
192
  */
176
193
  async runAgent(message, conversationId, channelId, userId, interruptResponses, context) {
194
+ const { InterruptResponseContent, ModelStreamUpdateEvent, BeforeToolCallEvent, AfterToolCallEvent, AgentResultEvent } = await loadStrands();
177
195
  const strandsAgent = await this.createStrandsAgent(conversationId, context);
178
196
  const startTime = Date.now();
179
197
  // Only persist user message on initial path (not resume)
@@ -278,6 +296,7 @@ export class AgentBase extends Scope {
278
296
  await this.rt.publish('chunks', channelId, { type: 'done', text: fullText, usage });
279
297
  }
280
298
  async createStrandsAgent(conversationId, fallbackContext) {
299
+ const { Agent: StrandsAgent, tool, SessionManager, BeforeToolCallEvent } = await loadStrands();
281
300
  const toolDefs = [...this.toolMap.values()];
282
301
  // Validate mutual exclusivity of needsApproval/trustable and interrupt
283
302
  for (const t of toolDefs) {
@@ -328,7 +347,7 @@ export class AgentBase extends Scope {
328
347
  ...(this.config.description !== undefined && { description: this.config.description }),
329
348
  systemPrompt: this.config.systemPrompt,
330
349
  tools: strandsTools,
331
- conversationManager: createConversationManager(this.config.conversation),
350
+ conversationManager: await createConversationManager(this.config.conversation),
332
351
  sessionManager,
333
352
  printer: false, //disable Strands automatic printing
334
353
  });
@@ -1,5 +1,4 @@
1
- import { type Model } from '@strands-agents/sdk';
2
- import type { BaseModelConfig } from '@strands-agents/sdk';
1
+ import type { Model, BaseModelConfig } from '@strands-agents/sdk';
3
2
  import type { ChildLogger } from '@aws-blocks/bb-logger';
4
3
  import type { ModelConfig } from './types.js';
5
4
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"model-factory.d.ts","sourceRoot":"","sources":["../src/model-factory.ts"],"names":[],"mappings":"AAGA,OAAO,EAAgB,KAAK,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAK9C;;;;;;;GAOG;AACH,yDAAyD;AACzD,MAAM,WAAW,mBAAmB;IACnC,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CACjC;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CAqHjI;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAkDjH"}
1
+ {"version":3,"file":"model-factory.d.ts","sourceRoot":"","sources":["../src/model-factory.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAK9C;;;;;;;GAOG;AACH,yDAAyD;AACzD,MAAM,WAAW,mBAAmB;IACnC,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CACjC;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CAqHjI;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAwDjH"}
@@ -1,9 +1,5 @@
1
1
  // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
2
  // SPDX-License-Identifier: Apache-2.0
3
- import { BedrockModel } from '@strands-agents/sdk';
4
- import { OpenAIModel } from '@strands-agents/sdk/models/openai';
5
- import { CannedProvider } from './providers/canned.js';
6
- import { ThrowingProvider } from './providers/throwing.js';
7
3
  import { AgentErrors, blocksAgentError } from './errors.js';
8
4
  export async function checkModelHealth(config, log, _testClient) {
9
5
  if (!config || config.provider === 'canned') {
@@ -122,17 +118,21 @@ export async function checkModelHealth(config, log, _testClient) {
122
118
  * @see https://strandsagents.com/docs/user-guide/concepts/model-providers/
123
119
  */
124
120
  export async function createStrandsModel(config, log) {
125
- if (!config || config.provider === 'canned')
121
+ if (!config || config.provider === 'canned') {
122
+ const { CannedProvider } = await import('./providers/canned.js');
126
123
  return new CannedProvider();
124
+ }
127
125
  // Test-only provider — throws mid-stream to verify error handling
128
126
  if (config.provider === 'throwing') {
129
127
  log?.warn('ThrowingProvider is only for internal test purposes');
128
+ const { ThrowingProvider } = await import('./providers/throwing.js');
130
129
  return new ThrowingProvider();
131
130
  }
132
131
  if (config.provider === 'bedrock') {
133
132
  if (!config.modelId) {
134
133
  throw blocksAgentError(AgentErrors.InvalidModelConfig, "Model provider 'bedrock' requires modelId.");
135
134
  }
135
+ const { BedrockModel } = await import('@strands-agents/sdk');
136
136
  return new BedrockModel({
137
137
  modelId: config.modelId,
138
138
  ...(config.inferenceConfig && {
@@ -152,6 +152,7 @@ export async function createStrandsModel(config, log) {
152
152
  if (!apiKey && !process.env.OPENAI_API_KEY) {
153
153
  throw blocksAgentError(AgentErrors.InvalidModelConfig, "provider 'openai-api' requires apiKey or OPENAI_API_KEY environment variable.");
154
154
  }
155
+ const { OpenAIModel } = await import('@strands-agents/sdk/models/openai');
155
156
  return new OpenAIModel({
156
157
  api: 'chat',
157
158
  apiKey: apiKey ?? '',
package/dist/schemas.d.ts CHANGED
@@ -12,11 +12,11 @@ export declare const messageSchema: z.ZodObject<{
12
12
  conversationId: z.ZodString;
13
13
  messageId: z.ZodString;
14
14
  role: z.ZodEnum<{
15
- user: "user";
16
- assistant: "assistant";
17
- interrupt: "interrupt";
18
15
  "tool-call": "tool-call";
19
16
  "tool-result": "tool-result";
17
+ interrupt: "interrupt";
18
+ user: "user";
19
+ assistant: "assistant";
20
20
  approval: "approval";
21
21
  }>;
22
22
  content: z.ZodString;
@@ -34,12 +34,12 @@ export declare const messageSchema: z.ZodObject<{
34
34
  /** Schema for AgentStreamChunk — used by Realtime namespace validation. */
35
35
  export declare const agentStreamChunkSchema: z.ZodObject<{
36
36
  type: z.ZodEnum<{
37
- interrupt: "interrupt";
38
37
  "text-delta": "text-delta";
39
38
  "tool-call": "tool-call";
40
39
  "tool-result": "tool-result";
41
40
  done: "done";
42
41
  error: "error";
42
+ interrupt: "interrupt";
43
43
  }>;
44
44
  text: z.ZodOptional<z.ZodString>;
45
45
  toolName: z.ZodOptional<z.ZodString>;
package/dist/version.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export declare const BB_NAME = "Agent";
2
- export declare const BB_VERSION = "0.3.1";
2
+ export declare const BB_VERSION = "0.3.2";
3
3
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  // Auto-generated by scripts/generate-version.mjs — do not edit manually
2
2
  export const BB_NAME = 'Agent';
3
- export const BB_VERSION = '0.3.1';
3
+ export const BB_VERSION = '0.3.2';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aws-blocks/bb-agent",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "author": "Amazon Web Services",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -41,6 +41,7 @@
41
41
  "@aws-blocks/bb-realtime": "^0.1.2",
42
42
  "@aws-blocks/core": "^0.1.10",
43
43
  "@aws-sdk/client-bedrock": "^3.700.0",
44
+ "@opentelemetry/api": "^1.9.0",
44
45
  "@strands-agents/sdk": "~1.3.0",
45
46
  "openai": "^6.7.0",
46
47
  "ulid": "^2.3.0",
@@ -49,7 +50,6 @@
49
50
  "devDependencies": {
50
51
  "@aws-sdk/client-bedrock-runtime": "^3.700.0",
51
52
  "@modelcontextprotocol/sdk": "^1.12.1",
52
- "@opentelemetry/api": "^1.9.0",
53
53
  "@types/node": "^20.0.0",
54
54
  "typescript": "^5.3.0"
55
55
  },
package/src/agent.ts CHANGED
@@ -9,16 +9,14 @@ import { AsyncJob } from '@aws-blocks/bb-async-job';
9
9
  import { FileBucket } from '@aws-blocks/bb-file-bucket';
10
10
  import { Logger } from '@aws-blocks/bb-logger';
11
11
  import type { ChildLogger } from '@aws-blocks/bb-logger';
12
- import { Agent as StrandsAgent, tool, SessionManager, ModelStreamUpdateEvent, AfterToolCallEvent, BeforeToolCallEvent, AgentResultEvent, InterruptEvent } from '@strands-agents/sdk';
13
- import type { AgentResult } from '@strands-agents/sdk';
14
- import { InterruptResponseContent } from '@strands-agents/sdk';
12
+ // Runtime values from `@strands-agents/sdk` are deferred to loadStrands(); only types
13
+ // are imported here (erased at compile time). See loadStrands() / issue #153.
14
+ import type { Agent as StrandsAgent, SnapshotStorage } from '@strands-agents/sdk';
15
15
  import { z } from 'zod';
16
16
  import { createStrandsModel, checkModelHealth } from './model-factory.js';
17
- import type { SnapshotStorage } from '@strands-agents/sdk';
18
17
  import { messageSchema, conversationSchema, agentStreamChunkSchema } from './schemas.js';
19
18
  import type { AgentConfig, AgentStreamChunk, AgentStreamResult, StreamOptions, Message, Conversation, TokenUsage, ConversationManagerConfig, ModelConfig, JSONValue, InterruptResponse, DefaultToolContext, AgentTool, ToolDefinition } from './types.js';
20
19
  import { AgentErrors, blocksAgentError, InterruptError } from './errors.js';
21
- import { SlidingWindowConversationManager, SummarizingConversationManager } from '@strands-agents/sdk';
22
20
  import { BB_NAME, BB_VERSION } from './version.js';
23
21
  import { ulid } from 'ulid';
24
22
 
@@ -37,6 +35,26 @@ const jobPayloadSchema = z.object({
37
35
  /** Key under which the per-call tool context is threaded through Strands `invocationState`. */
38
36
  const TOOL_CONTEXT_KEY = '__bbAgentToolContext';
39
37
 
38
+ /**
39
+ * Lazily import the Strands SDK runtime, caching the module after the first load.
40
+ *
41
+ * Importing the Agent BB must not eagerly evaluate `@strands-agents/sdk`: the
42
+ * `@aws-blocks/blocks` umbrella re-exports `Agent` statically, so a static top-level
43
+ * import here would load Strands — and its non-optional `@modelcontextprotocol/sdk`
44
+ * and `@opentelemetry/api` peers — for every app that touches the umbrella, even
45
+ * ones that never create an agent (see issue #153). Deferring the import to first
46
+ * agent execution keeps those packages off the load path for non-agent apps.
47
+ */
48
+ let strandsModulePromise: Promise<typeof import('@strands-agents/sdk')> | undefined;
49
+ function loadStrands(): Promise<typeof import('@strands-agents/sdk')> {
50
+ strandsModulePromise ??= import('@strands-agents/sdk').catch((err) => {
51
+ // Don't cache a rejected import — clear the slot so a later call can retry.
52
+ strandsModulePromise = undefined;
53
+ return Promise.reject(err);
54
+ });
55
+ return strandsModulePromise;
56
+ }
57
+
40
58
  /**
41
59
  * The per-call tool factory handed to the `tools` callback. At runtime it's an identity
42
60
  * function whose only job is to give TypeScript a single call site per tool where it can
@@ -66,7 +84,8 @@ function resolveTools<TContext>(
66
84
  * Controls how message history is trimmed in-memory before sending to the model. Does not handle persistence.
67
85
  * @see https://strandsagents.com/docs/user-guide/concepts/agents/conversation-management/
68
86
  */
69
- function createConversationManager(config?: ConversationManagerConfig) {
87
+ async function createConversationManager(config?: ConversationManagerConfig) {
88
+ const { SlidingWindowConversationManager, SummarizingConversationManager } = await loadStrands();
70
89
  if (!config || !config.strategy || config.strategy === 'sliding-window') {
71
90
  const windowSize = config && 'windowSize' in config ? config.windowSize : undefined;
72
91
  return new SlidingWindowConversationManager({ windowSize });
@@ -192,6 +211,7 @@ export class AgentBase<TContext = DefaultToolContext> extends Scope {
192
211
  * TODO add comments for args
193
212
  */
194
213
  private async runAgent(message: string, conversationId: string | undefined, channelId: string, userId: string, interruptResponses?: Array<{ interruptId: string; response: string }>, context?: TContext): Promise<void> {
214
+ const { InterruptResponseContent, ModelStreamUpdateEvent, BeforeToolCallEvent, AfterToolCallEvent, AgentResultEvent } = await loadStrands();
195
215
  const strandsAgent = await this.createStrandsAgent(conversationId, context);
196
216
  const startTime = Date.now();
197
217
 
@@ -298,6 +318,7 @@ export class AgentBase<TContext = DefaultToolContext> extends Scope {
298
318
  }
299
319
 
300
320
  private async createStrandsAgent(conversationId?: string, fallbackContext?: TContext): Promise<StrandsAgent> {
321
+ const { Agent: StrandsAgent, tool, SessionManager, BeforeToolCallEvent } = await loadStrands();
301
322
  const toolDefs = [...this.toolMap.values()];
302
323
  // Validate mutual exclusivity of needsApproval/trustable and interrupt
303
324
  for (const t of toolDefs) {
@@ -351,7 +372,7 @@ export class AgentBase<TContext = DefaultToolContext> extends Scope {
351
372
  ...(this.config.description !== undefined && { description: this.config.description }),
352
373
  systemPrompt: this.config.systemPrompt,
353
374
  tools: strandsTools,
354
- conversationManager: createConversationManager(this.config.conversation),
375
+ conversationManager: await createConversationManager(this.config.conversation),
355
376
  sessionManager,
356
377
  printer: false, //disable Strands automatic printing
357
378
  });
@@ -1,12 +1,13 @@
1
1
  // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { BedrockModel, type Model } from '@strands-agents/sdk';
5
- import type { BaseModelConfig } from '@strands-agents/sdk';
6
- import { OpenAIModel } from '@strands-agents/sdk/models/openai';
4
+ // Strands runtime is loaded lazily inside createStrandsModel(); only types are
5
+ // imported here. See loadStrands() in agent.ts and issue #153.
6
+ import type { Model, BaseModelConfig } from '@strands-agents/sdk';
7
7
  import type { ChildLogger } from '@aws-blocks/bb-logger';
8
- import { CannedProvider } from './providers/canned.js';
9
- import { ThrowingProvider } from './providers/throwing.js';
8
+ // `./providers/canned` and `./providers/throwing` extend Strands' `Model`, so importing
9
+ // them would evaluate `@strands-agents/sdk` at load time — hence they're also loaded
10
+ // lazily inside createStrandsModel(). See issue #153.
10
11
  import type { ModelConfig } from './types.js';
11
12
  import { AgentErrors, blocksAgentError } from './errors.js';
12
13
 
@@ -152,11 +153,15 @@ export async function checkModelHealth(config: ModelConfig, log: ChildLogger, _t
152
153
  * @see https://strandsagents.com/docs/user-guide/concepts/model-providers/
153
154
  */
154
155
  export async function createStrandsModel(config?: ModelConfig, log?: ChildLogger): Promise<Model<BaseModelConfig>> {
155
- if (!config || config.provider === 'canned') return new CannedProvider();
156
+ if (!config || config.provider === 'canned') {
157
+ const { CannedProvider } = await import('./providers/canned.js');
158
+ return new CannedProvider();
159
+ }
156
160
 
157
161
  // Test-only provider — throws mid-stream to verify error handling
158
162
  if (config.provider === 'throwing' as string) {
159
163
  log?.warn('ThrowingProvider is only for internal test purposes');
164
+ const { ThrowingProvider } = await import('./providers/throwing.js');
160
165
  return new ThrowingProvider();
161
166
  }
162
167
 
@@ -164,6 +169,7 @@ export async function createStrandsModel(config?: ModelConfig, log?: ChildLogger
164
169
  if (!config.modelId) {
165
170
  throw blocksAgentError(AgentErrors.InvalidModelConfig, "Model provider 'bedrock' requires modelId.");
166
171
  }
172
+ const { BedrockModel } = await import('@strands-agents/sdk');
167
173
  return new BedrockModel({
168
174
  modelId: config.modelId,
169
175
  ...(config.inferenceConfig && {
@@ -184,6 +190,7 @@ export async function createStrandsModel(config?: ModelConfig, log?: ChildLogger
184
190
  if (!apiKey && !process.env.OPENAI_API_KEY) {
185
191
  throw blocksAgentError(AgentErrors.InvalidModelConfig, "provider 'openai-api' requires apiKey or OPENAI_API_KEY environment variable.");
186
192
  }
193
+ const { OpenAIModel } = await import('@strands-agents/sdk/models/openai');
187
194
  return new OpenAIModel({
188
195
  api: 'chat',
189
196
  apiKey: apiKey ?? '',
package/src/version.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  // Auto-generated by scripts/generate-version.mjs — do not edit manually
2
2
  export const BB_NAME = 'Agent';
3
- export const BB_VERSION = '0.3.1';
3
+ export const BB_VERSION = '0.3.2';