@opperai/agents 0.2.0 → 0.3.0-beta.1

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
@@ -10,6 +10,26 @@ var sse_js = require('@modelcontextprotocol/sdk/client/sse.js');
10
10
  var stdio_js = require('@modelcontextprotocol/sdk/client/stdio.js');
11
11
  var streamableHttp_js = require('@modelcontextprotocol/sdk/client/streamableHttp.js');
12
12
 
13
+ function _interopNamespace(e) {
14
+ if (e && e.__esModule) return e;
15
+ var n = Object.create(null);
16
+ if (e) {
17
+ Object.keys(e).forEach(function (k) {
18
+ if (k !== 'default') {
19
+ var d = Object.getOwnPropertyDescriptor(e, k);
20
+ Object.defineProperty(n, k, d.get ? d : {
21
+ enumerable: true,
22
+ get: function () { return e[k]; }
23
+ });
24
+ }
25
+ });
26
+ }
27
+ n.default = e;
28
+ return Object.freeze(n);
29
+ }
30
+
31
+ var zod__namespace = /*#__PURE__*/_interopNamespace(zod);
32
+
13
33
  var __defProp = Object.defineProperty;
14
34
  var __getOwnPropNames = Object.getOwnPropertyNames;
15
35
  var __esm = (fn, res) => function __init() {
@@ -572,8 +592,11 @@ function getSchemaName(schema) {
572
592
  return schemaAny._def.description;
573
593
  }
574
594
  const typeName = schemaAny._def?.typeName;
575
- if (typeName === "ZodObject" && schemaAny._def) {
576
- const shape = schemaAny._def.shape?.();
595
+ const type = schemaAny._def?.type;
596
+ const isObject = typeName === "ZodObject" || type === "object";
597
+ if (isObject && schemaAny._def) {
598
+ const shapeRaw = schemaAny._def.shape;
599
+ const shape = typeof shapeRaw === "function" ? shapeRaw() : shapeRaw;
577
600
  if (shape && typeof shape === "object") {
578
601
  const keys = Object.keys(shape);
579
602
  if (keys.length > 0) {
@@ -586,6 +609,9 @@ function getSchemaName(schema) {
586
609
  if (typeName) {
587
610
  return typeName.replace("Zod", "").replace("Type", "");
588
611
  }
612
+ if (type) {
613
+ return type.charAt(0).toUpperCase() + type.slice(1);
614
+ }
589
615
  return "Any";
590
616
  } catch {
591
617
  return "Any";
@@ -597,12 +623,15 @@ function extractParameters(schema) {
597
623
  }
598
624
  try {
599
625
  const schemaAny = schema;
600
- if (schemaAny._def?.typeName === "ZodObject") {
601
- const shape = schemaAny._def.shape?.();
626
+ const isObject = schemaAny._def?.typeName === "ZodObject" || schemaAny._def?.type === "object";
627
+ if (isObject) {
628
+ const shapeRaw = schemaAny._def?.shape;
629
+ const shape = typeof shapeRaw === "function" ? shapeRaw() : shapeRaw;
602
630
  if (shape && typeof shape === "object") {
603
631
  const params = [];
604
632
  for (const [key, value] of Object.entries(shape)) {
605
- const fieldType = value?._def?.typeName;
633
+ const valueAny = value;
634
+ const fieldType = valueAny._def?.typeName || valueAny.def?.type || valueAny.type;
606
635
  if (fieldType) {
607
636
  const cleanType = fieldType.replace("Zod", "").toLowerCase();
608
637
  params.push(`${key}: ${cleanType}`);
@@ -945,6 +974,28 @@ var BaseAgent = class {
945
974
  * Opper client configuration
946
975
  */
947
976
  opperConfig;
977
+ /**
978
+ * Creates a new BaseAgent instance
979
+ *
980
+ * @param config - Agent configuration object
981
+ * @param config.name - Unique name identifying this agent (required)
982
+ * @param config.description - Human-readable description of the agent's purpose
983
+ * @param config.instructions - System instructions guiding agent behavior
984
+ * @param config.tools - Array of tools or tool providers available to the agent
985
+ * @param config.maxIterations - Maximum iterations before terminating the agent loop (default: 25)
986
+ * @param config.model - Model identifier(s). Single model or array for fallback (default: "gcp/gemini-flash-latest")
987
+ * @param config.inputSchema - Zod schema for input validation
988
+ * @param config.outputSchema - Zod schema for output validation
989
+ * @param config.enableStreaming - Enable Opper streaming APIs for LLM calls (default: false)
990
+ * @param config.enableMemory - Enable memory subsystem (default: false)
991
+ * @param config.memory - Custom memory implementation (defaults to InMemoryStore if enableMemory is true)
992
+ * @param config.metadata - Additional metadata for the agent
993
+ * @param config.opperConfig - Opper API configuration containing apiKey and baseUrl
994
+ * @param config.onStreamStart - Handler invoked when a streaming call starts
995
+ * @param config.onStreamChunk - Handler invoked for each streaming chunk
996
+ * @param config.onStreamEnd - Handler invoked when a streaming call ends
997
+ * @param config.onStreamError - Handler invoked when streaming encounters an error
998
+ */
948
999
  constructor(config) {
949
1000
  this.name = config.name;
950
1001
  this.description = config.description;
@@ -1408,7 +1459,7 @@ var ThoughtSchema = zod.z.object({
1408
1459
  */
1409
1460
  confidence: zod.z.number().min(0).max(1).optional(),
1410
1461
  /**
1411
- * Additional metadata
1462
+ * Additional metadata (key-value pairs)
1412
1463
  */
1413
1464
  metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
1414
1465
  });
@@ -1445,6 +1496,10 @@ var AgentDecisionSchema = zod.z.object({
1445
1496
  * Agent's internal reasoning
1446
1497
  */
1447
1498
  reasoning: zod.z.string(),
1499
+ /**
1500
+ * Status message for the user (e.g., "Searching for information...", "Processing results...")
1501
+ */
1502
+ userMessage: zod.z.string().default("Working on it..."),
1448
1503
  /**
1449
1504
  * Tool calls to execute (if any)
1450
1505
  * Empty array signals task completion
@@ -1457,8 +1512,34 @@ var AgentDecisionSchema = zod.z.object({
1457
1512
  /**
1458
1513
  * Memory entries to write/update (key -> payload)
1459
1514
  */
1460
- memoryUpdates: zod.z.record(MemoryUpdateSchema).default({})
1515
+ memoryUpdates: zod.z.record(zod.z.string(), MemoryUpdateSchema).default({}),
1516
+ /**
1517
+ * Whether the task is complete and finalResult is available
1518
+ * (single LLM call pattern)
1519
+ */
1520
+ isComplete: zod.z.boolean().default(false),
1521
+ /**
1522
+ * The final result when isComplete=true
1523
+ * Should match outputSchema if specified
1524
+ */
1525
+ finalResult: zod.z.unknown().optional()
1461
1526
  });
1527
+ function createAgentDecisionWithOutputSchema(outputSchema) {
1528
+ if (!outputSchema) {
1529
+ return AgentDecisionSchema;
1530
+ }
1531
+ const finalResultSchema = outputSchema.optional();
1532
+ const dynamicSchema = zod.z.object({
1533
+ reasoning: zod.z.string(),
1534
+ userMessage: zod.z.string().default("Working on it..."),
1535
+ toolCalls: zod.z.array(ToolCallSchema).default([]),
1536
+ memoryReads: zod.z.array(zod.z.string()).default([]),
1537
+ memoryUpdates: zod.z.record(zod.z.string(), MemoryUpdateSchema).default({}),
1538
+ isComplete: zod.z.boolean().default(false),
1539
+ finalResult: finalResultSchema
1540
+ });
1541
+ return dynamicSchema;
1542
+ }
1462
1543
  var ToolExecutionSummarySchema = zod.z.object({
1463
1544
  /**
1464
1545
  * Tool name
@@ -1477,10 +1558,60 @@ var ToolExecutionSummarySchema = zod.z.object({
1477
1558
  */
1478
1559
  error: zod.z.string().optional()
1479
1560
  });
1561
+ var hasNativeToJSONSchema = typeof zod__namespace.toJSONSchema === "function";
1562
+ function zodSchemaToJsonSchema(schema) {
1563
+ if (hasNativeToJSONSchema) {
1564
+ try {
1565
+ const toJSONSchema2 = zod__namespace.toJSONSchema;
1566
+ const result = toJSONSchema2(schema);
1567
+ return result;
1568
+ } catch {
1569
+ }
1570
+ }
1571
+ return zodToJsonSchema.zodToJsonSchema(schema);
1572
+ }
1573
+ var SchemaValidationError = class extends Error {
1574
+ issues;
1575
+ constructor(message, issues) {
1576
+ super(message);
1577
+ this.name = "SchemaValidationError";
1578
+ this.issues = issues;
1579
+ }
1580
+ };
1581
+ var validateSchema = (schema, value, options = {}) => {
1582
+ const result = schema.safeParse(value);
1583
+ if (!result.success) {
1584
+ throw new SchemaValidationError(
1585
+ options.message ?? "Schema validation failed",
1586
+ result.error.issues
1587
+ );
1588
+ }
1589
+ return result.data;
1590
+ };
1591
+ var isSchemaValid = (schema, value) => {
1592
+ return schema.safeParse(value).success;
1593
+ };
1594
+ var schemaToJson = (schema, options = {}) => {
1595
+ if (hasNativeToJSONSchema) {
1596
+ return zodSchemaToJsonSchema(schema);
1597
+ }
1598
+ return zodToJsonSchema.zodToJsonSchema(schema, options);
1599
+ };
1600
+ var getSchemaDefault = (schema) => {
1601
+ const result = schema.safeParse(void 0);
1602
+ return result.success ? result.data : void 0;
1603
+ };
1604
+ var mergeSchemaDefaults = (schema, value) => {
1605
+ const defaults = getSchemaDefault(schema);
1606
+ if (defaults && typeof defaults === "object") {
1607
+ return validateSchema(schema, { ...defaults, ...value });
1608
+ }
1609
+ return validateSchema(schema, value);
1610
+ };
1480
1611
 
1481
1612
  // package.json
1482
1613
  var package_default = {
1483
- version: "0.2.0"};
1614
+ version: "0.3.0-beta.1"};
1484
1615
 
1485
1616
  // src/utils/version.ts
1486
1617
  var SDK_NAME = "@opperai/agents";
@@ -1608,7 +1739,8 @@ var OpperClient = class {
1608
1739
  const span = await this.client.spans.create({
1609
1740
  name: options.name,
1610
1741
  ...options.input !== void 0 && { input: options.input },
1611
- ...options.parentSpanId && { parentId: options.parentSpanId }
1742
+ ...options.parentSpanId && { parentId: options.parentSpanId },
1743
+ ...options.type && { type: options.type }
1612
1744
  });
1613
1745
  return {
1614
1746
  id: span.id,
@@ -1625,7 +1757,11 @@ var OpperClient = class {
1625
1757
  const serializedOutput = output !== void 0 && output !== null ? typeof output === "object" ? JSON.stringify(output) : String(output) : void 0;
1626
1758
  await this.client.spans.update(spanId, {
1627
1759
  ...serializedOutput !== void 0 && { output: serializedOutput },
1628
- ...options?.error && { error: options.error }
1760
+ ...options?.error && { error: options.error },
1761
+ ...options?.startTime && { startTime: options.startTime },
1762
+ ...options?.endTime && { endTime: options.endTime },
1763
+ ...options?.meta && { meta: options.meta },
1764
+ ...options?.name && { name: options.name }
1629
1765
  });
1630
1766
  }, `update-span:${spanId}`);
1631
1767
  }
@@ -1706,7 +1842,7 @@ var OpperClient = class {
1706
1842
  }
1707
1843
  if (isZodSchema(schema)) {
1708
1844
  try {
1709
- return zodToJsonSchema.zodToJsonSchema(schema);
1845
+ return zodSchemaToJsonSchema(schema);
1710
1846
  } catch (error) {
1711
1847
  this.logger.warn("Failed to convert Zod schema to JSON Schema", {
1712
1848
  error: error instanceof Error ? error.message : String(error)
@@ -1732,41 +1868,6 @@ var OpperClient = class {
1732
1868
  function createOpperClient(apiKey, options) {
1733
1869
  return new OpperClient(apiKey, options);
1734
1870
  }
1735
- var SchemaValidationError = class extends Error {
1736
- issues;
1737
- constructor(message, issues) {
1738
- super(message);
1739
- this.name = "SchemaValidationError";
1740
- this.issues = issues;
1741
- }
1742
- };
1743
- var validateSchema = (schema, value, options = {}) => {
1744
- const result = schema.safeParse(value);
1745
- if (!result.success) {
1746
- throw new SchemaValidationError(
1747
- options.message ?? "Schema validation failed",
1748
- result.error.issues
1749
- );
1750
- }
1751
- return result.data;
1752
- };
1753
- var isSchemaValid = (schema, value) => {
1754
- return schema.safeParse(value).success;
1755
- };
1756
- var schemaToJson = (schema, options = {}) => {
1757
- return zodToJsonSchema.zodToJsonSchema(schema, options);
1758
- };
1759
- var getSchemaDefault = (schema) => {
1760
- const result = schema.safeParse(void 0);
1761
- return result.success ? result.data : void 0;
1762
- };
1763
- var mergeSchemaDefaults = (schema, value) => {
1764
- const defaults = getSchemaDefault(schema);
1765
- if (defaults && typeof defaults === "object") {
1766
- return validateSchema(schema, { ...defaults, ...value });
1767
- }
1768
- return validateSchema(schema, value);
1769
- };
1770
1871
 
1771
1872
  // src/utils/streaming.ts
1772
1873
  var STREAM_ROOT_PATH = "_root";
@@ -1943,7 +2044,11 @@ var StreamAssembler = class {
1943
2044
  if (path === STREAM_ROOT_PATH) {
1944
2045
  continue;
1945
2046
  }
1946
- const value = resolveFieldValue(path, this.displayBuffers, this.valueBuffers);
2047
+ const value = resolveFieldValue(
2048
+ path,
2049
+ this.displayBuffers,
2050
+ this.valueBuffers
2051
+ );
1947
2052
  setNestedValue(result, path, value);
1948
2053
  }
1949
2054
  return normalizeIndexed(result);
@@ -1963,6 +2068,31 @@ var Agent = class extends BaseAgent {
1963
2068
  opperClient;
1964
2069
  logger;
1965
2070
  verbose;
2071
+ /**
2072
+ * Creates a new Agent instance
2073
+ *
2074
+ * @param config - Agent configuration object
2075
+ * @param config.name - Unique name identifying this agent (required)
2076
+ * @param config.description - Human-readable description of the agent's purpose
2077
+ * @param config.instructions - System instructions guiding agent behavior
2078
+ * @param config.tools - Array of tools or tool providers available to the agent
2079
+ * @param config.maxIterations - Maximum iterations before terminating (default: 25)
2080
+ * @param config.model - Model identifier(s) as string or array for fallback (default: "gcp/gemini-flash-latest")
2081
+ * @param config.inputSchema - Zod schema for input validation
2082
+ * @param config.outputSchema - Zod schema for output validation
2083
+ * @param config.enableStreaming - Enable streaming for LLM calls (default: false)
2084
+ * @param config.enableMemory - Enable memory subsystem (default: false)
2085
+ * @param config.memory - Custom memory implementation (defaults to InMemoryStore if enableMemory is true)
2086
+ * @param config.metadata - Additional metadata for the agent
2087
+ * @param config.opperConfig - Opper API configuration (apiKey, baseUrl)
2088
+ * @param config.opperClient - Custom Opper client instance (for testing or custom configuration)
2089
+ * @param config.logger - Logger instance for debugging
2090
+ * @param config.verbose - Enable verbose logging (default: false)
2091
+ * @param config.onStreamStart - Handler invoked when streaming starts
2092
+ * @param config.onStreamChunk - Handler invoked for each streaming chunk
2093
+ * @param config.onStreamEnd - Handler invoked when streaming ends
2094
+ * @param config.onStreamError - Handler invoked on streaming errors
2095
+ */
1966
2096
  constructor(config) {
1967
2097
  super(config);
1968
2098
  this.logger = config.logger ?? getDefaultLogger();
@@ -1998,6 +2128,7 @@ var Agent = class extends BaseAgent {
1998
2128
  maxIterations: this.maxIterations,
1999
2129
  tools: Array.from(this.tools.keys())
2000
2130
  });
2131
+ const executionStartTime = /* @__PURE__ */ new Date();
2001
2132
  const parentSpan = await this.opperClient.createSpan({
2002
2133
  name: `${this.name}_execution`,
2003
2134
  input: this.serializeInput(input),
@@ -2017,6 +2148,48 @@ var Agent = class extends BaseAgent {
2017
2148
  input,
2018
2149
  context
2019
2150
  );
2151
+ if (decision.isComplete && decision.finalResult !== void 0) {
2152
+ this.log("Task completed with final result in single call", {
2153
+ iteration: currentIteration
2154
+ });
2155
+ await this.handleMemoryActions(decision, context, thinkSpanId);
2156
+ let finalResult;
2157
+ if (this.outputSchema) {
2158
+ const parseResult = this.outputSchema.safeParse(
2159
+ decision.finalResult
2160
+ );
2161
+ if (parseResult.success) {
2162
+ finalResult = parseResult.data;
2163
+ } else {
2164
+ this.logger.warn(
2165
+ "Final result validation against output schema failed, falling back to generate_final_result",
2166
+ { error: parseResult.error.message }
2167
+ );
2168
+ break;
2169
+ }
2170
+ } else {
2171
+ const rawResult = decision.finalResult;
2172
+ if (typeof rawResult === "string") {
2173
+ finalResult = rawResult;
2174
+ } else if (rawResult === null || rawResult === void 0) {
2175
+ finalResult = "";
2176
+ } else if (typeof rawResult === "object") {
2177
+ finalResult = JSON.stringify(rawResult);
2178
+ } else {
2179
+ finalResult = String(rawResult);
2180
+ }
2181
+ }
2182
+ const executionEndTime2 = /* @__PURE__ */ new Date();
2183
+ await this.opperClient.updateSpan(parentSpan.id, finalResult, {
2184
+ startTime: executionStartTime,
2185
+ endTime: executionEndTime2,
2186
+ meta: {
2187
+ durationMs: executionEndTime2.getTime() - executionStartTime.getTime()
2188
+ }
2189
+ });
2190
+ await this.triggerHook(HookEvents.LoopEnd, { context });
2191
+ return finalResult;
2192
+ }
2020
2193
  const memoryResults = await this.handleMemoryActions(
2021
2194
  decision,
2022
2195
  context,
@@ -2026,7 +2199,7 @@ var Agent = class extends BaseAgent {
2026
2199
  const toolResults = await this.executeToolCalls(
2027
2200
  decision,
2028
2201
  context,
2029
- thinkSpanId
2202
+ context.parentSpanId ?? void 0
2030
2203
  );
2031
2204
  const combinedResults = [...memoryResults, ...toolResults];
2032
2205
  const newToolCalls = context.toolCalls.slice(toolCallStartIndex);
@@ -2061,11 +2234,24 @@ var Agent = class extends BaseAgent {
2061
2234
  );
2062
2235
  }
2063
2236
  const result = await this.generateFinalResult(input, context);
2064
- await this.opperClient.updateSpan(parentSpan.id, result);
2237
+ const executionEndTime = /* @__PURE__ */ new Date();
2238
+ await this.opperClient.updateSpan(parentSpan.id, result, {
2239
+ startTime: executionStartTime,
2240
+ endTime: executionEndTime,
2241
+ meta: {
2242
+ durationMs: executionEndTime.getTime() - executionStartTime.getTime()
2243
+ }
2244
+ });
2065
2245
  return result;
2066
2246
  } catch (error) {
2247
+ const executionEndTime = /* @__PURE__ */ new Date();
2067
2248
  await this.opperClient.updateSpan(parentSpan.id, void 0, {
2068
- error: error instanceof Error ? error.message : String(error)
2249
+ error: error instanceof Error ? error.message : String(error),
2250
+ startTime: executionStartTime,
2251
+ endTime: executionEndTime,
2252
+ meta: {
2253
+ durationMs: executionEndTime.getTime() - executionStartTime.getTime()
2254
+ }
2069
2255
  });
2070
2256
  throw error;
2071
2257
  }
@@ -2074,11 +2260,15 @@ var Agent = class extends BaseAgent {
2074
2260
  * Think step: Call LLM to decide next action
2075
2261
  */
2076
2262
  async think(input, context) {
2077
- const spanName = "think";
2263
+ const sanitizedName = this.name.toLowerCase().replace(/[\s-]/g, "_");
2264
+ const spanName = `think_${sanitizedName}`;
2078
2265
  this.log("Think step", { iteration: context.iteration });
2079
2266
  await this.triggerHook(HookEvents.LlmCall, { context, callType: "think" });
2267
+ const decisionSchema = createAgentDecisionWithOutputSchema(
2268
+ this.outputSchema
2269
+ );
2080
2270
  if (this.enableStreaming) {
2081
- return this.thinkStreaming(input, context);
2271
+ return this.thinkStreaming(input, context, decisionSchema, spanName);
2082
2272
  }
2083
2273
  try {
2084
2274
  const instructions = this.buildThinkInstructions();
@@ -2087,7 +2277,7 @@ var Agent = class extends BaseAgent {
2087
2277
  name: spanName,
2088
2278
  instructions,
2089
2279
  input: thinkContext,
2090
- outputSchema: AgentDecisionSchema,
2280
+ outputSchema: decisionSchema,
2091
2281
  model: this.model,
2092
2282
  ...context.parentSpanId && { parentSpanId: context.parentSpanId }
2093
2283
  });
@@ -2098,15 +2288,25 @@ var Agent = class extends BaseAgent {
2098
2288
  totalTokens: response.usage.totalTokens,
2099
2289
  cost: response.usage.cost
2100
2290
  });
2101
- const decision = AgentDecisionSchema.parse(response.jsonPayload);
2291
+ const decision = decisionSchema.parse(
2292
+ response.jsonPayload
2293
+ );
2102
2294
  await this.triggerHook(HookEvents.LlmResponse, {
2103
2295
  context,
2104
2296
  callType: "think",
2105
2297
  response
2106
2298
  });
2299
+ if (response.spanId) {
2300
+ await this.opperClient.updateSpan(response.spanId, void 0, {
2301
+ name: "think"
2302
+ });
2303
+ }
2107
2304
  await this.triggerHook(HookEvents.ThinkEnd, {
2108
2305
  context,
2109
- thought: { reasoning: decision.reasoning }
2306
+ thought: {
2307
+ reasoning: decision.reasoning,
2308
+ userMessage: decision.userMessage
2309
+ }
2110
2310
  });
2111
2311
  this.log("Think result", {
2112
2312
  reasoning: decision.reasoning,
@@ -2122,12 +2322,11 @@ var Agent = class extends BaseAgent {
2122
2322
  );
2123
2323
  }
2124
2324
  }
2125
- async thinkStreaming(input, context) {
2126
- const spanName = "think";
2325
+ async thinkStreaming(input, context, decisionSchema, spanName) {
2127
2326
  const instructions = this.buildThinkInstructions();
2128
2327
  const thinkContext = await this.buildThinkContext(input, context);
2129
2328
  const assembler = createStreamAssembler({
2130
- schema: AgentDecisionSchema
2329
+ schema: decisionSchema
2131
2330
  });
2132
2331
  let streamSpanId;
2133
2332
  await this.triggerHook(HookEvents.StreamStart, {
@@ -2143,7 +2342,7 @@ var Agent = class extends BaseAgent {
2143
2342
  name: spanName,
2144
2343
  instructions,
2145
2344
  input: thinkContext,
2146
- outputSchema: AgentDecisionSchema,
2345
+ outputSchema: decisionSchema,
2147
2346
  model: this.model,
2148
2347
  ...context.parentSpanId && { parentSpanId: context.parentSpanId }
2149
2348
  });
@@ -2187,11 +2386,11 @@ var Agent = class extends BaseAgent {
2187
2386
  const finalize = assembler.finalize();
2188
2387
  let decision;
2189
2388
  if (finalize.type === "structured" && finalize.structured) {
2190
- decision = AgentDecisionSchema.parse(
2389
+ decision = decisionSchema.parse(
2191
2390
  finalize.structured
2192
2391
  );
2193
2392
  } else {
2194
- decision = AgentDecisionSchema.parse({
2393
+ decision = decisionSchema.parse({
2195
2394
  reasoning: finalize.type === "root" ? finalize.rootText ?? "" : ""
2196
2395
  });
2197
2396
  }
@@ -2214,9 +2413,17 @@ var Agent = class extends BaseAgent {
2214
2413
  response: streamResponse,
2215
2414
  parsed: decision
2216
2415
  });
2416
+ if (streamSpanId) {
2417
+ await this.opperClient.updateSpan(streamSpanId, void 0, {
2418
+ name: "think"
2419
+ });
2420
+ }
2217
2421
  await this.triggerHook(HookEvents.ThinkEnd, {
2218
2422
  context,
2219
- thought: { reasoning: decision.reasoning }
2423
+ thought: {
2424
+ reasoning: decision.reasoning,
2425
+ userMessage: decision.userMessage
2426
+ }
2220
2427
  });
2221
2428
  this.log("Think result", {
2222
2429
  reasoning: decision.reasoning,
@@ -2258,12 +2465,22 @@ YOUR TASK:
2258
2465
  1. Analyze the current situation
2259
2466
  2. Decide if the goal is complete or more actions are needed
2260
2467
  3. If more actions needed: specify tools to call
2261
- 4. If goal complete: return empty tool_calls list
2468
+ 4. If goal complete:
2469
+ - Set isComplete=true
2470
+ - Provide the complete answer/output in finalResult
2471
+ - Leave toolCalls empty
2262
2472
 
2263
2473
  IMPORTANT:
2264
- - Return empty toolCalls array when task is COMPLETE
2474
+ - When task is COMPLETE, you MUST set isComplete=true AND provide finalResult
2475
+ - The finalResult should be a complete, well-structured answer based on all work done
2265
2476
  - Only use available tools
2266
- - Provide clear reasoning for each decision`;
2477
+ - Provide clear reasoning for each decision
2478
+ - If an outputSchema was specified, ensure finalResult matches that schema
2479
+
2480
+ USER MESSAGE:
2481
+ - Always provide a brief, user-friendly status in userMessage
2482
+ - This message is shown to users to indicate progress (e.g., "Searching for weather data...", "Calculating results...", "Done!")
2483
+ - Keep it concise and informative`;
2267
2484
  if (this.enableMemory) {
2268
2485
  instructions += `
2269
2486
 
@@ -2347,9 +2564,14 @@ The memory you write persists across all process() calls on this agent.`;
2347
2564
  this.log(`Action: ${toolCall.toolName}`, {
2348
2565
  parameters: toolCall.arguments
2349
2566
  });
2567
+ const startTime = /* @__PURE__ */ new Date();
2568
+ const tool2 = this.tools.get(toolCall.toolName);
2569
+ const isAgentTool = tool2?.metadata?.["isAgent"] === true;
2570
+ const spanType = isAgentTool ? "\u{1F916} agent" : "\u{1F527} tool";
2350
2571
  const toolSpan = await this.opperClient.createSpan({
2351
2572
  name: `tool_${toolCall.toolName}`,
2352
2573
  input: toolCall.arguments,
2574
+ type: spanType,
2353
2575
  ...parentSpanId ? { parentSpanId } : context.parentSpanId ? { parentSpanId: context.parentSpanId } : {}
2354
2576
  });
2355
2577
  try {
@@ -2359,11 +2581,20 @@ The memory you write persists across all process() calls on this agent.`;
2359
2581
  context,
2360
2582
  { spanId: toolSpan.id }
2361
2583
  );
2584
+ const endTime = /* @__PURE__ */ new Date();
2585
+ const durationMs = endTime.getTime() - startTime.getTime();
2362
2586
  if (result.success) {
2363
- await this.opperClient.updateSpan(toolSpan.id, result.output);
2587
+ await this.opperClient.updateSpan(toolSpan.id, result.output, {
2588
+ startTime,
2589
+ endTime,
2590
+ meta: { durationMs }
2591
+ });
2364
2592
  } else {
2365
2593
  await this.opperClient.updateSpan(toolSpan.id, void 0, {
2366
- error: result.error instanceof Error ? result.error.message : String(result.error)
2594
+ error: result.error instanceof Error ? result.error.message : String(result.error),
2595
+ startTime,
2596
+ endTime,
2597
+ meta: { durationMs }
2367
2598
  });
2368
2599
  }
2369
2600
  const summary = {
@@ -2378,12 +2609,18 @@ The memory you write persists across all process() calls on this agent.`;
2378
2609
  this.log(
2379
2610
  `Tool ${toolCall.toolName} ${result.success ? "succeeded" : "failed"}`,
2380
2611
  {
2381
- success: result.success
2612
+ success: result.success,
2613
+ durationMs
2382
2614
  }
2383
2615
  );
2384
2616
  } catch (error) {
2617
+ const endTime = /* @__PURE__ */ new Date();
2618
+ const durationMs = endTime.getTime() - startTime.getTime();
2385
2619
  await this.opperClient.updateSpan(toolSpan.id, void 0, {
2386
- error: error instanceof Error ? error.message : String(error)
2620
+ error: error instanceof Error ? error.message : String(error),
2621
+ startTime,
2622
+ endTime,
2623
+ meta: { durationMs }
2387
2624
  });
2388
2625
  const summary = {
2389
2626
  toolName: toolCall.toolName,
@@ -2392,7 +2629,8 @@ The memory you write persists across all process() calls on this agent.`;
2392
2629
  };
2393
2630
  results.push(ToolExecutionSummarySchema.parse(summary));
2394
2631
  this.logger.warn(`Tool ${toolCall.toolName} threw error`, {
2395
- error: error instanceof Error ? error.message : String(error)
2632
+ error: error instanceof Error ? error.message : String(error),
2633
+ durationMs
2396
2634
  });
2397
2635
  }
2398
2636
  }
@@ -2421,6 +2659,7 @@ The memory you write persists across all process() calls on this agent.`;
2421
2659
  const spanParentId = parentSpanId ?? context.parentSpanId ?? void 0;
2422
2660
  const summaries = [];
2423
2661
  if (hasReads) {
2662
+ const startTime = /* @__PURE__ */ new Date();
2424
2663
  try {
2425
2664
  const keySet = new Set(
2426
2665
  decision.memoryReads.filter(
@@ -2432,10 +2671,17 @@ The memory you write persists across all process() calls on this agent.`;
2432
2671
  const memoryReadSpan = await this.opperClient.createSpan({
2433
2672
  name: "memory_read",
2434
2673
  input: keys,
2674
+ type: "\u{1F9E0} memory",
2435
2675
  ...spanParentId && { parentSpanId: spanParentId }
2436
2676
  });
2437
2677
  const memoryData = await this.memory.read(keys);
2438
- await this.opperClient.updateSpan(memoryReadSpan.id, memoryData);
2678
+ const endTime = /* @__PURE__ */ new Date();
2679
+ const durationMs = endTime.getTime() - startTime.getTime();
2680
+ await this.opperClient.updateSpan(memoryReadSpan.id, memoryData, {
2681
+ startTime,
2682
+ endTime,
2683
+ meta: { durationMs }
2684
+ });
2439
2685
  context.setMetadata("current_memory", memoryData);
2440
2686
  this.log(`Loaded ${Object.keys(memoryData).length} memory entries`, {
2441
2687
  keys
@@ -2474,10 +2720,12 @@ The memory you write persists across all process() calls on this agent.`;
2474
2720
  }
2475
2721
  }
2476
2722
  if (hasWrites) {
2723
+ const startTime = /* @__PURE__ */ new Date();
2477
2724
  try {
2478
2725
  const memoryWriteSpan = await this.opperClient.createSpan({
2479
2726
  name: "memory_write",
2480
2727
  input: updateEntries.map(([key]) => key),
2728
+ type: "\u{1F9E0} memory",
2481
2729
  ...spanParentId && { parentSpanId: spanParentId }
2482
2730
  });
2483
2731
  for (const [key, update] of updateEntries) {
@@ -2494,9 +2742,16 @@ The memory you write persists across all process() calls on this agent.`;
2494
2742
  value: castUpdate.value
2495
2743
  });
2496
2744
  }
2745
+ const endTime = /* @__PURE__ */ new Date();
2746
+ const durationMs = endTime.getTime() - startTime.getTime();
2497
2747
  await this.opperClient.updateSpan(
2498
2748
  memoryWriteSpan.id,
2499
- `Successfully wrote ${updateEntries.length} keys`
2749
+ `Successfully wrote ${updateEntries.length} keys`,
2750
+ {
2751
+ startTime,
2752
+ endTime,
2753
+ meta: { durationMs }
2754
+ }
2500
2755
  );
2501
2756
  this.log(`Wrote ${updateEntries.length} memory entries`);
2502
2757
  summaries.push(
@@ -2569,8 +2824,10 @@ Follow any instructions provided for formatting and style.`;
2569
2824
  );
2570
2825
  }
2571
2826
  try {
2827
+ const sanitizedName = this.name.toLowerCase().replace(/[\s-]/g, "_");
2828
+ const functionName = `generate_final_result_${sanitizedName}`;
2572
2829
  const callOptions = {
2573
- name: "generate_final_result",
2830
+ name: functionName,
2574
2831
  instructions,
2575
2832
  input: finalContext,
2576
2833
  model: this.model
@@ -2617,8 +2874,10 @@ Follow any instructions provided for formatting and style.`;
2617
2874
  callType: "final_result"
2618
2875
  });
2619
2876
  try {
2877
+ const sanitizedName = this.name.toLowerCase().replace(/[\s-]/g, "_");
2878
+ const functionName = `generate_final_result_${sanitizedName}`;
2620
2879
  const streamResponse = await this.opperClient.stream({
2621
- name: "generate_final_result",
2880
+ name: functionName,
2622
2881
  instructions,
2623
2882
  input: finalContext,
2624
2883
  model: this.model,
@@ -3560,6 +3819,7 @@ exports.ThoughtSchema = ThoughtSchema;
3560
3819
  exports.ToolCallSchema = ToolCallSchema;
3561
3820
  exports.ToolExecutionSummarySchema = ToolExecutionSummarySchema;
3562
3821
  exports.ToolRunner = ToolRunner;
3822
+ exports.createAgentDecisionWithOutputSchema = createAgentDecisionWithOutputSchema;
3563
3823
  exports.createFunctionTool = createFunctionTool;
3564
3824
  exports.createHookManager = createHookManager;
3565
3825
  exports.createInMemoryStore = createInMemoryStore;
@@ -3577,5 +3837,6 @@ exports.schemaToJson = schemaToJson;
3577
3837
  exports.setDefaultLogger = setDefaultLogger;
3578
3838
  exports.tool = tool;
3579
3839
  exports.validateSchema = validateSchema;
3840
+ exports.zodSchemaToJsonSchema = zodSchemaToJsonSchema;
3580
3841
  //# sourceMappingURL=index.cjs.map
3581
3842
  //# sourceMappingURL=index.cjs.map