@opperai/agents 0.7.0 → 0.8.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.
package/dist/index.cjs CHANGED
@@ -945,6 +945,10 @@ var BaseAgent = class {
945
945
  * Whether streaming is enabled
946
946
  */
947
947
  enableStreaming;
948
+ /**
949
+ * Whether to execute tool calls in parallel
950
+ */
951
+ parallelToolExecution;
948
952
  /**
949
953
  * Memory instance for persistent storage (null if disabled or initialization failed)
950
954
  */
@@ -1009,6 +1013,7 @@ var BaseAgent = class {
1009
1013
  this.outputSchema = config.outputSchema;
1010
1014
  this.enableMemory = config.enableMemory ?? false;
1011
1015
  this.enableStreaming = config.enableStreaming ?? false;
1016
+ this.parallelToolExecution = config.parallelToolExecution ?? false;
1012
1017
  this.metadata = { ...config.metadata ?? {} };
1013
1018
  this.hooks = new HookManager();
1014
1019
  this.tools = /* @__PURE__ */ new Map();
@@ -1656,7 +1661,7 @@ var mergeSchemaDefaults = (schema, value) => {
1656
1661
 
1657
1662
  // package.json
1658
1663
  var package_default = {
1659
- version: "0.7.0"};
1664
+ version: "0.8.0"};
1660
1665
 
1661
1666
  // src/utils/version.ts
1662
1667
  var SDK_NAME = "@opperai/agents";
@@ -1692,7 +1697,8 @@ var extractCost = (response) => {
1692
1697
  };
1693
1698
  };
1694
1699
  var DEFAULT_RETRY_CONFIG = {
1695
- maxRetries: 3,
1700
+ maxRetries: 0,
1701
+ // Retries are handled in the opper-node sdk
1696
1702
  initialDelayMs: 1e3,
1697
1703
  backoffMultiplier: 2,
1698
1704
  maxDelayMs: 1e4
@@ -1705,7 +1711,8 @@ var OpperClient = class {
1705
1711
  this.client = new opperai.Opper({
1706
1712
  httpBearer: apiKey ?? process.env["OPPER_HTTP_BEARER"] ?? "",
1707
1713
  userAgent: getUserAgent(),
1708
- ...options.baseUrl && { serverURL: options.baseUrl }
1714
+ ...options.baseUrl && { serverURL: options.baseUrl },
1715
+ retryConfig: { strategy: "backoff" }
1709
1716
  });
1710
1717
  this.logger = options.logger ?? getDefaultLogger();
1711
1718
  this.retryConfig = {
@@ -2646,89 +2653,105 @@ The memory you write persists across all process() calls on this agent.`;
2646
2653
  return [];
2647
2654
  }
2648
2655
  this.log(`Executing ${decision.toolCalls.length} tool call(s)`);
2656
+ if (this.parallelToolExecution && decision.toolCalls.length > 1) {
2657
+ this.log("Executing tool calls in parallel");
2658
+ return Promise.all(
2659
+ decision.toolCalls.map(
2660
+ (toolCall) => this.executeSingleToolCall(toolCall, context, parentSpanId)
2661
+ )
2662
+ );
2663
+ }
2649
2664
  const results = [];
2650
2665
  for (const toolCall of decision.toolCalls) {
2651
- this.log(`Action: ${toolCall.toolName}`, {
2652
- parameters: toolCall.arguments
2653
- });
2654
- const startTime = /* @__PURE__ */ new Date();
2655
- const tool2 = this.tools.get(toolCall.toolName);
2656
- const isAgentTool = tool2?.metadata?.["isAgent"] === true;
2657
- const spanType = isAgentTool ? "\u{1F916} agent" : "\u{1F527} tool";
2658
- const toolSpan = await this.opperClient.createSpan({
2659
- name: `tool_${toolCall.toolName}`,
2660
- input: toolCall.arguments,
2661
- type: spanType,
2662
- ...parentSpanId ? { parentSpanId } : context.parentSpanId ? { parentSpanId: context.parentSpanId } : {}
2663
- });
2664
- try {
2665
- const result = await this.executeTool(
2666
- toolCall.toolName,
2667
- toolCall.arguments,
2668
- context,
2669
- { spanId: toolSpan.id }
2670
- );
2671
- if (result.usage) {
2672
- context.updateUsageWithSource(toolCall.toolName, result.usage);
2673
- }
2674
- const endTime = /* @__PURE__ */ new Date();
2675
- const durationMs = endTime.getTime() - startTime.getTime();
2676
- if (result.success) {
2677
- this.queueSpanUpdate(context, {
2678
- spanId: toolSpan.id,
2679
- output: result.output,
2680
- startTime,
2681
- endTime,
2682
- meta: { durationMs }
2683
- });
2684
- } else {
2685
- this.queueSpanUpdate(context, {
2686
- spanId: toolSpan.id,
2687
- error: result.error instanceof Error ? result.error.message : String(result.error),
2688
- startTime,
2689
- endTime,
2690
- meta: { durationMs }
2691
- });
2692
- }
2693
- const summary = {
2694
- toolName: toolCall.toolName,
2695
- success: result.success,
2696
- ...result.success && { output: result.output },
2697
- ...!result.success && {
2698
- error: result.error instanceof Error ? result.error.message : String(result.error)
2699
- }
2700
- };
2701
- results.push(ToolExecutionSummarySchema.parse(summary));
2702
- this.log(
2703
- `Tool ${toolCall.toolName} ${result.success ? "succeeded" : "failed"}`,
2704
- {
2705
- success: result.success,
2706
- durationMs
2707
- }
2708
- );
2709
- } catch (error) {
2710
- const endTime = /* @__PURE__ */ new Date();
2711
- const durationMs = endTime.getTime() - startTime.getTime();
2666
+ results.push(
2667
+ await this.executeSingleToolCall(toolCall, context, parentSpanId)
2668
+ );
2669
+ }
2670
+ return results;
2671
+ }
2672
+ /**
2673
+ * Execute a single tool call with span tracking and error handling
2674
+ */
2675
+ async executeSingleToolCall(toolCall, context, parentSpanId) {
2676
+ this.log(`Action: ${toolCall.toolName}`, {
2677
+ parameters: toolCall.arguments
2678
+ });
2679
+ const startTime = /* @__PURE__ */ new Date();
2680
+ const tool2 = this.tools.get(toolCall.toolName);
2681
+ const isAgentTool = tool2?.metadata?.["isAgent"] === true;
2682
+ const spanType = isAgentTool ? "\u{1F916} agent" : "\u{1F527} tool";
2683
+ const toolSpan = await this.opperClient.createSpan({
2684
+ name: `tool_${toolCall.toolName}`,
2685
+ input: toolCall.arguments,
2686
+ type: spanType,
2687
+ ...parentSpanId ? { parentSpanId } : context.parentSpanId ? { parentSpanId: context.parentSpanId } : {}
2688
+ });
2689
+ try {
2690
+ const result = await this.executeTool(
2691
+ toolCall.toolName,
2692
+ toolCall.arguments,
2693
+ context,
2694
+ { spanId: toolSpan.id }
2695
+ );
2696
+ if (result.usage) {
2697
+ context.updateUsageWithSource(toolCall.toolName, result.usage);
2698
+ }
2699
+ const endTime = /* @__PURE__ */ new Date();
2700
+ const durationMs = endTime.getTime() - startTime.getTime();
2701
+ if (result.success) {
2712
2702
  this.queueSpanUpdate(context, {
2713
2703
  spanId: toolSpan.id,
2714
- error: error instanceof Error ? error.message : String(error),
2704
+ output: result.output,
2715
2705
  startTime,
2716
2706
  endTime,
2717
2707
  meta: { durationMs }
2718
2708
  });
2719
- const summary = {
2720
- toolName: toolCall.toolName,
2721
- success: false,
2722
- error: error instanceof Error ? error.message : String(error)
2723
- };
2724
- results.push(ToolExecutionSummarySchema.parse(summary));
2725
- this.logger.warn(`Tool ${toolCall.toolName} threw error`, {
2726
- error: error instanceof Error ? error.message : String(error),
2727
- durationMs
2709
+ } else {
2710
+ this.queueSpanUpdate(context, {
2711
+ spanId: toolSpan.id,
2712
+ error: result.error instanceof Error ? result.error.message : String(result.error),
2713
+ startTime,
2714
+ endTime,
2715
+ meta: { durationMs }
2728
2716
  });
2729
2717
  }
2718
+ const summary = {
2719
+ toolName: toolCall.toolName,
2720
+ success: result.success,
2721
+ ...result.success && { output: result.output },
2722
+ ...!result.success && {
2723
+ error: result.error instanceof Error ? result.error.message : String(result.error)
2724
+ }
2725
+ };
2726
+ this.log(
2727
+ `Tool ${toolCall.toolName} ${result.success ? "succeeded" : "failed"}`,
2728
+ {
2729
+ success: result.success,
2730
+ durationMs
2731
+ }
2732
+ );
2733
+ return ToolExecutionSummarySchema.parse(summary);
2734
+ } catch (error) {
2735
+ const endTime = /* @__PURE__ */ new Date();
2736
+ const durationMs = endTime.getTime() - startTime.getTime();
2737
+ this.queueSpanUpdate(context, {
2738
+ spanId: toolSpan.id,
2739
+ error: error instanceof Error ? error.message : String(error),
2740
+ startTime,
2741
+ endTime,
2742
+ meta: { durationMs }
2743
+ });
2744
+ const summary = {
2745
+ toolName: toolCall.toolName,
2746
+ success: false,
2747
+ error: error instanceof Error ? error.message : String(error)
2748
+ };
2749
+ this.logger.warn(`Tool ${toolCall.toolName} threw error`, {
2750
+ error: error instanceof Error ? error.message : String(error),
2751
+ durationMs
2752
+ });
2753
+ return ToolExecutionSummarySchema.parse(summary);
2730
2754
  }
2731
- return results;
2732
2755
  }
2733
2756
  /**
2734
2757
  * Handle memory operations from a decision