@agentuity/runtime 0.1.23 → 0.1.25

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 (38) hide show
  1. package/dist/_standalone.d.ts.map +1 -1
  2. package/dist/_standalone.js +11 -10
  3. package/dist/_standalone.js.map +1 -1
  4. package/dist/_tokens.d.ts.map +1 -1
  5. package/dist/_tokens.js +9 -8
  6. package/dist/_tokens.js.map +1 -1
  7. package/dist/agent.d.ts.map +1 -1
  8. package/dist/agent.js +228 -196
  9. package/dist/agent.js.map +1 -1
  10. package/dist/middleware.d.ts.map +1 -1
  11. package/dist/middleware.js +29 -6
  12. package/dist/middleware.js.map +1 -1
  13. package/dist/otel/fetch.js +1 -1
  14. package/dist/otel/fetch.js.map +1 -1
  15. package/dist/otel/otel.d.ts.map +1 -1
  16. package/dist/otel/otel.js +2 -29
  17. package/dist/otel/otel.js.map +1 -1
  18. package/dist/services/evalrun/http.d.ts.map +1 -1
  19. package/dist/services/evalrun/http.js +31 -2
  20. package/dist/services/evalrun/http.js.map +1 -1
  21. package/dist/services/local/keyvalue.d.ts.map +1 -1
  22. package/dist/services/local/keyvalue.js.map +1 -1
  23. package/dist/services/local/vector.d.ts.map +1 -1
  24. package/dist/services/local/vector.js.map +1 -1
  25. package/dist/services/session/http.d.ts.map +1 -1
  26. package/dist/services/session/http.js +58 -19
  27. package/dist/services/session/http.js.map +1 -1
  28. package/package.json +7 -9
  29. package/src/_standalone.ts +36 -10
  30. package/src/_tokens.ts +14 -12
  31. package/src/agent.ts +260 -259
  32. package/src/middleware.ts +39 -6
  33. package/src/otel/fetch.ts +1 -1
  34. package/src/otel/otel.ts +2 -30
  35. package/src/services/evalrun/http.ts +45 -10
  36. package/src/services/local/keyvalue.ts +3 -1
  37. package/src/services/local/vector.ts +3 -1
  38. package/src/services/session/http.ts +78 -33
package/src/agent.ts CHANGED
@@ -10,7 +10,6 @@ import {
10
10
  type InferInput,
11
11
  type InferOutput,
12
12
  toCamelCase,
13
- type EvalRunStartEvent,
14
13
  } from '@agentuity/core';
15
14
  import { context, SpanStatusCode, type Tracer, trace } from '@opentelemetry/api';
16
15
  import { TraceState } from '@opentelemetry/core';
@@ -27,7 +26,7 @@ import {
27
26
  type RequestAgentContextArgs,
28
27
  } from './_context';
29
28
  import type { Logger } from './logger';
30
- import type { Eval, EvalContext, EvalHandlerResult, EvalRunResult, EvalFunction } from './eval';
29
+ import type { Eval, EvalHandlerResult, EvalRunResult, EvalFunction } from './eval';
31
30
  import { internal } from './logger/internal';
32
31
  import { fireEvent } from './_events';
33
32
  import type { Thread, Session } from './session';
@@ -1659,20 +1658,10 @@ export function createAgent<
1659
1658
  await fireAgentEvent(runtime, agent as Agent, 'started', agentCtx);
1660
1659
 
1661
1660
  try {
1662
- // Wrap agent execution with span tracking if tracer is available
1661
+ // Execute the handler directly - span creation is handled by the caller (AgentRunner.run)
1662
+ // This avoids duplicate spans when agents call other agents
1663
1663
  const result = await (async () => {
1664
- if (agentCtx.tracer && inHTTPContext()) {
1665
- const honoCtx = getHTTPContext();
1666
- return runWithSpan<any, TInput, TOutput, TStream>(
1667
- agentCtx.tracer,
1668
- agent as Agent<TInput, TOutput, TStream>,
1669
- honoCtx,
1670
- async () =>
1671
- inputSchema
1672
- ? await (config.handler as any)(agentCtx, validatedInput)
1673
- : await (config.handler as any)(agentCtx)
1674
- );
1675
- } else if (agent.metadata.id) {
1664
+ if (agent.metadata.id && !inHTTPContext()) {
1676
1665
  // For standalone contexts, wrap with agent context to set aid in trace state
1677
1666
  return runWithAgentContext(agent.metadata.id, () =>
1678
1667
  inputSchema
@@ -1680,7 +1669,8 @@ export function createAgent<
1680
1669
  : (config.handler as any)(agentCtx)
1681
1670
  );
1682
1671
  } else {
1683
- // No agent ID, invoke handler directly
1672
+ // HTTP context or no agent ID - invoke handler directly
1673
+ // Span is created by AgentRunner.run or createAgentRunner
1684
1674
  return inputSchema
1685
1675
  ? (config.handler as any)(agentCtx, validatedInput)
1686
1676
  : (config.handler as any)(agentCtx);
@@ -1917,273 +1907,258 @@ export function createAgent<
1917
1907
  // HTTP context may not be available, spanId will be undefined
1918
1908
  }
1919
1909
 
1910
+ // Capture the agent span context so eval spans are parented to the agent
1911
+ const agentSpanContext = context.active();
1912
+
1920
1913
  // Execute each eval using waitUntil to avoid blocking the response
1921
1914
  for (const evalItem of agentEvals) {
1922
1915
  const evalName = evalItem.metadata.name || 'unnamed';
1923
1916
  const agentName = _agent?.metadata?.name || name;
1917
+ const evalRunId = generateId('evalrun');
1918
+
1919
+ // Look up eval metadata synchronously before async execution
1920
+ const evalMeta = getEvalMetadata(agentName, evalName);
1921
+ const evalId = evalMeta?.id || '';
1922
+ const evalIdentifier = evalMeta?.identifier || '';
1923
+
1924
+ // Create eval span FIRST, parented to agent, then call waitUntil inside it
1925
+ // This makes waitUntil a child of the eval span
1926
+ const tracer = ctx.tracer;
1927
+ if (tracer) {
1928
+ const evalSpan = tracer.startSpan(evalName, {}, agentSpanContext);
1929
+ evalSpan.setAttributes({
1930
+ '@agentuity/evalId': evalId,
1931
+ '@agentuity/evalIdentifier': evalIdentifier,
1932
+ '@agentuity/evalName': evalName,
1933
+ '@agentuity/evalRunId': evalRunId,
1934
+ '@agentuity/agentName': agentName,
1935
+ '@agentuity/evalDescription':
1936
+ evalMeta?.description || evalItem.metadata.description || '',
1937
+ '@agentuity/evalFilename':
1938
+ evalMeta?.filename || evalItem.metadata.filename || '',
1939
+ });
1924
1940
 
1925
- ctx.waitUntil(
1926
- (async () => {
1927
- internal.info(`[EVALRUN] Starting eval run tracking for '${evalName}'`);
1928
- const evalRunId = generateId('evalrun');
1929
-
1930
- // Look up eval metadata from agentuity.metadata.json by agent name and eval name
1931
- internal.info(
1932
- `[EVALRUN] Looking up eval metadata: agentName='${agentName}', evalName='${evalName}'`
1933
- );
1934
- const evalMeta = getEvalMetadata(agentName, evalName);
1935
- internal.info(`[EVALRUN] Eval metadata lookup result:`, {
1936
- found: !!evalMeta,
1937
- identifier: evalMeta?.identifier,
1938
- id: evalMeta?.id,
1939
- filename: evalMeta?.filename,
1940
- });
1941
-
1942
- // evalId = deployment-specific ID (evalid_...), evalIdentifier = stable (eval_...)
1943
- const evalId = evalMeta?.id || '';
1944
- const evalIdentifier = evalMeta?.identifier || '';
1945
- internal.info(
1946
- `[EVALRUN] Resolved evalId='${evalId}', evalIdentifier='${evalIdentifier}'`
1947
- );
1948
-
1949
- // Log eval metadata using structured logging and tracing
1950
- ctx.logger.debug('Starting eval run with metadata', {
1951
- evalName,
1952
- agentName,
1953
- evalRunId,
1954
- evalId,
1955
- evalMetaFromFile: !!evalMeta,
1956
- evalMetadata: evalItem.metadata,
1957
- });
1958
-
1959
- // Add eval metadata to the active span for observability
1960
- const activeSpan = ctx.tracer ? trace.getActiveSpan() : undefined;
1961
- if (activeSpan) {
1962
- activeSpan.setAttributes({
1963
- 'eval.name': evalName,
1964
- 'eval.id': evalId,
1965
- 'eval.runId': evalRunId,
1966
- 'eval.description':
1967
- evalMeta?.description || evalItem.metadata.description || '',
1968
- 'eval.filename': evalMeta?.filename || evalItem.metadata.filename || '',
1969
- });
1970
- }
1941
+ const evalSpanContext = trace.setSpan(agentSpanContext, evalSpan);
1971
1942
 
1972
- const orgId = runtimeConfig.getOrganizationId();
1973
- const projectId = runtimeConfig.getProjectId();
1974
- const devMode = runtimeConfig.isDevMode() ?? false;
1975
- const evalRunEventProvider = getEvalRunEventProvider();
1976
-
1977
- // Only send events if we have required context (devmode flag will be set based on devMode)
1978
- const shouldSendEvalRunEvents =
1979
- orgId && projectId && evalId !== '' && evalIdentifier !== '';
1980
-
1981
- internal.info(`[EVALRUN] Checking conditions for eval '${evalName}':`, {
1982
- orgId: orgId,
1983
- projectId: projectId,
1984
- evalId: evalId,
1985
- evalIdentifier: evalIdentifier,
1986
- devMode,
1987
- hasEvalRunEventProvider: !!evalRunEventProvider,
1988
- shouldSendEvalRunEvents,
1989
- });
1943
+ // Run waitUntil INSIDE the eval span context - this makes waitUntil a child of eval
1944
+ // Pass a function (not an already-executing promise) so waitUntil executes it
1945
+ // AFTER setting up its span context, making operations children of waitUntil
1946
+ context.with(evalSpanContext, () => {
1947
+ ctx.waitUntil(async () => {
1948
+ try {
1949
+ internal.info(`[EVALRUN] Starting eval run tracking for '${evalName}'`);
1950
+
1951
+ const orgId = runtimeConfig.getOrganizationId();
1952
+ const projectId = runtimeConfig.getProjectId();
1953
+ const devMode = runtimeConfig.isDevMode() ?? false;
1954
+ const evalRunEventProvider = getEvalRunEventProvider();
1955
+
1956
+ const shouldSendEvalRunEvents =
1957
+ orgId && projectId && evalId !== '' && evalIdentifier !== '';
1958
+
1959
+ // Send eval run start event
1960
+ if (shouldSendEvalRunEvents && evalRunEventProvider) {
1961
+ try {
1962
+ const deploymentId = runtimeConfig.getDeploymentId();
1963
+ await evalRunEventProvider.start({
1964
+ id: evalRunId,
1965
+ sessionId: ctx.sessionId,
1966
+ evalId,
1967
+ evalIdentifier,
1968
+ orgId: orgId!,
1969
+ projectId: projectId!,
1970
+ devmode: Boolean(devMode),
1971
+ deploymentId: deploymentId || undefined,
1972
+ spanId: agentRunSpanId,
1973
+ });
1974
+ } catch (error) {
1975
+ internal.error(
1976
+ `[EVALRUN] Error sending start event for '${evalName}'`,
1977
+ { error }
1978
+ );
1979
+ }
1980
+ }
1990
1981
 
1991
- if (!shouldSendEvalRunEvents) {
1992
- const reasons: string[] = [];
1993
- if (!orgId) reasons.push('missing orgId');
1994
- if (!projectId) reasons.push('missing projectId');
1995
- if (!evalId || evalId === '') reasons.push('empty evalId');
1996
- if (!evalIdentifier || evalIdentifier === '')
1997
- reasons.push('empty evalIdentifier');
1998
- internal.info(
1999
- `[EVALRUN] Skipping eval run events for '${evalName}': ${reasons.join(', ')}`
2000
- );
2001
- }
1982
+ // Validate eval input/output if schemas exist
1983
+ let evalValidatedInput: any = validatedInput;
1984
+ let evalValidatedOutput: any = validatedOutput;
1985
+
1986
+ if (evalItem.inputSchema) {
1987
+ const result =
1988
+ await evalItem.inputSchema['~standard'].validate(validatedInput);
1989
+ if (result.issues) {
1990
+ throw new ValidationError({
1991
+ issues: result.issues,
1992
+ message: `Eval input validation failed`,
1993
+ });
1994
+ }
1995
+ evalValidatedInput = result.value;
1996
+ }
2002
1997
 
2003
- try {
2004
- internal.debug(`Executing eval: ${evalName}`);
1998
+ if (evalItem.outputSchema) {
1999
+ const result =
2000
+ await evalItem.outputSchema['~standard'].validate(validatedOutput);
2001
+ if (result.issues) {
2002
+ throw new ValidationError({
2003
+ issues: result.issues,
2004
+ message: `Eval output validation failed`,
2005
+ });
2006
+ }
2007
+ evalValidatedOutput = result.value;
2008
+ }
2005
2009
 
2006
- // Send eval run start event
2007
- if (shouldSendEvalRunEvents && evalRunEventProvider) {
2008
- internal.info(
2009
- `[EVALRUN] Sending start event for eval '${evalName}' (id: ${evalRunId}, evalId: ${evalId})`
2010
- );
2011
- try {
2012
- const deploymentId = runtimeConfig.getDeploymentId();
2013
- // Use captured agentRunSpanId (may be undefined if HTTP context unavailable)
2014
- if (!agentRunSpanId) {
2015
- internal.warn(
2016
- `[EVALRUN] agentRunSpanId not available for eval '${evalName}' (id: ${evalRunId}). This may occur if waitUntil runs outside AsyncLocalStorage context.`
2010
+ // Execute the eval handler
2011
+ let handlerResult: EvalHandlerResult;
2012
+ if (inputSchema && outputSchema) {
2013
+ handlerResult = await (evalItem.handler as any)(
2014
+ ctx,
2015
+ evalValidatedInput,
2016
+ evalValidatedOutput
2017
2017
  );
2018
+ } else if (inputSchema) {
2019
+ handlerResult = await (evalItem.handler as any)(ctx, evalValidatedInput);
2020
+ } else if (outputSchema) {
2021
+ handlerResult = await (evalItem.handler as any)(ctx, evalValidatedOutput);
2022
+ } else {
2023
+ handlerResult = await (evalItem.handler as any)(ctx);
2018
2024
  }
2019
- const startEvent: EvalRunStartEvent = {
2020
- id: evalRunId,
2021
- sessionId: ctx.sessionId,
2022
- evalId: evalId, // deployment-specific ID (evalid_...)
2023
- evalIdentifier: evalIdentifier, // stable identifier (eval_...)
2024
- orgId: orgId!,
2025
- projectId: projectId!,
2026
- devmode: Boolean(devMode),
2027
- deploymentId: deploymentId || undefined,
2028
- spanId: agentRunSpanId,
2029
- };
2030
- internal.debug(
2031
- '[EVALRUN] Start event payload: %s',
2032
- JSON.stringify(startEvent, null, 2)
2033
- );
2034
- await evalRunEventProvider.start(startEvent);
2035
- internal.info(
2036
- `[EVALRUN] Start event sent successfully for eval '${evalName}' (id: ${evalRunId})`
2037
- );
2038
- } catch (error) {
2039
- internal.error(
2040
- `[EVALRUN] Error sending eval run start event for '${evalName}' (id: ${evalRunId})`,
2041
- {
2042
- error,
2025
+
2026
+ const result: EvalRunResult = { success: true, ...handlerResult };
2027
+
2028
+ // Send eval run complete event
2029
+ if (shouldSendEvalRunEvents && evalRunEventProvider) {
2030
+ try {
2031
+ await evalRunEventProvider.complete({ id: evalRunId, result });
2032
+ } catch (error) {
2033
+ internal.error(
2034
+ `[EVALRUN] Error sending complete event for '${evalName}'`,
2035
+ { error }
2036
+ );
2043
2037
  }
2044
- );
2045
- // Don't throw - continue with eval execution even if start event fails
2046
- }
2047
- } else if (shouldSendEvalRunEvents && !evalRunEventProvider) {
2048
- internal.warn(
2049
- `[EVALRUN] Conditions met but no evalRunEventProvider available for '${evalName}'`
2050
- );
2051
- } else {
2052
- internal.debug(
2053
- `[EVALRUN] Not sending start event for '${evalName}': shouldSendEvalRunEvents=${shouldSendEvalRunEvents}, hasProvider=${!!evalRunEventProvider}`
2054
- );
2055
- }
2038
+ }
2056
2039
 
2057
- // Validate eval input if schema exists
2058
- let evalValidatedInput: any = validatedInput;
2059
- if (evalItem.inputSchema) {
2060
- const evalInputResult =
2061
- await evalItem.inputSchema['~standard'].validate(validatedInput);
2062
- if (evalInputResult.issues) {
2063
- throw new ValidationError({
2064
- issues: evalInputResult.issues,
2065
- message: `Eval input validation failed: ${evalInputResult.issues.map((i: any) => i.message).join(', ')}`,
2040
+ internal.debug(`Eval '${evalName}' completed successfully`);
2041
+ } catch (error) {
2042
+ const errorMessage =
2043
+ error instanceof Error ? error.message : String(error);
2044
+ evalSpan.recordException(error as Error);
2045
+ evalSpan.setStatus({
2046
+ code: SpanStatusCode.ERROR,
2047
+ message: errorMessage,
2066
2048
  });
2049
+ internal.error(`Error executing eval '${evalName}'`, { error });
2050
+
2051
+ // Send error event
2052
+ const orgId = runtimeConfig.getOrganizationId();
2053
+ const projectId = runtimeConfig.getProjectId();
2054
+ const evalRunEventProvider = getEvalRunEventProvider();
2055
+ if (orgId && projectId && evalId && evalRunEventProvider) {
2056
+ try {
2057
+ await evalRunEventProvider.complete({
2058
+ id: evalRunId,
2059
+ error: errorMessage,
2060
+ result: {
2061
+ success: false,
2062
+ passed: false,
2063
+ error: errorMessage,
2064
+ metadata: {},
2065
+ },
2066
+ });
2067
+ } catch (e) {
2068
+ internal.debug('Failed to send eval run complete event', {
2069
+ evalRunId,
2070
+ errorMessage,
2071
+ error: e instanceof Error ? e.message : String(e),
2072
+ });
2073
+ }
2074
+ }
2075
+ } finally {
2076
+ evalSpan.end();
2067
2077
  }
2068
- evalValidatedInput = evalInputResult.value;
2069
- }
2070
-
2071
- // Validate eval output if schema exists
2072
- let evalValidatedOutput: any = validatedOutput;
2073
- if (evalItem.outputSchema) {
2074
- const evalOutputResult =
2075
- await evalItem.outputSchema['~standard'].validate(validatedOutput);
2076
- if (evalOutputResult.issues) {
2077
- throw new ValidationError({
2078
- issues: evalOutputResult.issues,
2079
- message: `Eval output validation failed: ${evalOutputResult.issues.map((i: any) => i.message).join(', ')}`,
2080
- });
2078
+ });
2079
+ });
2080
+ } else {
2081
+ // No tracer - execute without span
2082
+ ctx.waitUntil(async () => {
2083
+ try {
2084
+ const orgId = runtimeConfig.getOrganizationId();
2085
+ const projectId = runtimeConfig.getProjectId();
2086
+ const devMode = runtimeConfig.isDevMode() ?? false;
2087
+ const evalRunEventProvider = getEvalRunEventProvider();
2088
+ const shouldSendEvalRunEvents =
2089
+ orgId && projectId && evalId !== '' && evalIdentifier !== '';
2090
+
2091
+ if (shouldSendEvalRunEvents && evalRunEventProvider) {
2092
+ try {
2093
+ await evalRunEventProvider.start({
2094
+ id: evalRunId,
2095
+ sessionId: ctx.sessionId,
2096
+ evalId,
2097
+ evalIdentifier,
2098
+ orgId: orgId!,
2099
+ projectId: projectId!,
2100
+ devmode: Boolean(devMode),
2101
+ deploymentId: runtimeConfig.getDeploymentId() || undefined,
2102
+ spanId: agentRunSpanId,
2103
+ });
2104
+ } catch (e) {
2105
+ internal.debug('Failed to send eval run start event', {
2106
+ evalRunId,
2107
+ evalId,
2108
+ evalIdentifier,
2109
+ sessionId: ctx.sessionId,
2110
+ error: e instanceof Error ? e.message : String(e),
2111
+ });
2112
+ }
2081
2113
  }
2082
- evalValidatedOutput = evalOutputResult.value;
2083
- }
2084
2114
 
2085
- // Create EvalContext (just an alias for AgentContext)
2086
- const evalContext: EvalContext = ctx;
2087
-
2088
- // Execute the eval handler conditionally based on agent schema
2089
- let handlerResult: EvalHandlerResult;
2090
- if (inputSchema && outputSchema) {
2091
- // Both input and output defined
2092
- handlerResult = await (evalItem.handler as any)(
2093
- evalContext,
2094
- evalValidatedInput,
2095
- evalValidatedOutput
2096
- );
2097
- } else if (inputSchema) {
2098
- // Only input defined
2099
- handlerResult = await (evalItem.handler as any)(
2100
- evalContext,
2101
- evalValidatedInput
2102
- );
2103
- } else if (outputSchema) {
2104
- // Only output defined
2105
- handlerResult = await (evalItem.handler as any)(
2106
- evalContext,
2107
- evalValidatedOutput
2108
- );
2109
- } else {
2110
- // Neither defined
2111
- handlerResult = await (evalItem.handler as any)(evalContext);
2112
- }
2115
+ let evalValidatedInput: any = validatedInput;
2116
+ let evalValidatedOutput: any = validatedOutput;
2113
2117
 
2114
- // Wrap handler result with success for catalyst
2115
- const result: EvalRunResult = {
2116
- success: true,
2117
- ...handlerResult,
2118
- };
2119
-
2120
- // Log the result
2121
- if (result.score !== undefined) {
2122
- internal.info(
2123
- `Eval '${evalName}' pass: ${result.passed}, score: ${result.score}`,
2124
- result.metadata
2125
- );
2126
- } else {
2127
- internal.info(`Eval '${evalName}' pass: ${result.passed}`, result.metadata);
2128
- }
2118
+ if (evalItem.inputSchema) {
2119
+ const result =
2120
+ await evalItem.inputSchema['~standard'].validate(validatedInput);
2121
+ if (!result.issues) evalValidatedInput = result.value;
2122
+ }
2123
+ if (evalItem.outputSchema) {
2124
+ const result =
2125
+ await evalItem.outputSchema['~standard'].validate(validatedOutput);
2126
+ if (!result.issues) evalValidatedOutput = result.value;
2127
+ }
2129
2128
 
2130
- // Send eval run complete event
2131
- if (shouldSendEvalRunEvents && evalRunEventProvider) {
2132
- internal.info(
2133
- `[EVALRUN] Sending complete event for eval '${evalName}' (id: ${evalRunId})`
2134
- );
2135
- try {
2136
- await evalRunEventProvider.complete({
2137
- id: evalRunId,
2138
- result,
2139
- });
2140
- internal.info(
2141
- `[EVALRUN] Complete event sent successfully for eval '${evalName}' (id: ${evalRunId})`
2142
- );
2143
- } catch (error) {
2144
- internal.error(
2145
- `[EVALRUN] Error sending eval run complete event for '${evalName}' (id: ${evalRunId})`,
2146
- {
2147
- error,
2148
- }
2129
+ let handlerResult: EvalHandlerResult;
2130
+ if (inputSchema && outputSchema) {
2131
+ handlerResult = await (evalItem.handler as any)(
2132
+ ctx,
2133
+ evalValidatedInput,
2134
+ evalValidatedOutput
2149
2135
  );
2136
+ } else if (inputSchema) {
2137
+ handlerResult = await (evalItem.handler as any)(ctx, evalValidatedInput);
2138
+ } else if (outputSchema) {
2139
+ handlerResult = await (evalItem.handler as any)(ctx, evalValidatedOutput);
2140
+ } else {
2141
+ handlerResult = await (evalItem.handler as any)(ctx);
2150
2142
  }
2151
- }
2152
-
2153
- internal.debug(`Eval '${evalName}' completed successfully`);
2154
- } catch (error) {
2155
- const errorMessage = error instanceof Error ? error.message : String(error);
2156
- internal.error(`Error executing eval '${evalName}'`, { error });
2157
2143
 
2158
- // Send eval run complete event with error
2159
- if (shouldSendEvalRunEvents && evalRunEventProvider) {
2160
- internal.info(
2161
- `[EVALRUN] Sending complete event (error) for eval '${evalName}' (id: ${evalRunId})`
2162
- );
2163
- try {
2164
- await evalRunEventProvider.complete({
2165
- id: evalRunId,
2166
- error: errorMessage,
2167
- result: {
2168
- success: false,
2169
- passed: false,
2170
- error: errorMessage,
2171
- metadata: {},
2172
- },
2173
- });
2174
- internal.info(
2175
- `[EVALRUN] Complete event (error) sent successfully for eval '${evalName}' (id: ${evalRunId})`
2176
- );
2177
- } catch (eventError) {
2178
- internal.error(
2179
- `[EVALRUN] Error sending eval run complete event (error) for '${evalName}' (id: ${evalRunId})`,
2180
- { error: eventError }
2181
- );
2144
+ if (shouldSendEvalRunEvents && evalRunEventProvider) {
2145
+ try {
2146
+ await evalRunEventProvider.complete({
2147
+ id: evalRunId,
2148
+ result: { success: true, ...handlerResult },
2149
+ });
2150
+ } catch (e) {
2151
+ internal.debug('Failed to send eval run complete event', {
2152
+ evalRunId,
2153
+ error: e instanceof Error ? e.message : String(e),
2154
+ });
2155
+ }
2182
2156
  }
2157
+ } catch (error) {
2158
+ internal.error(`Error executing eval '${evalName}'`, { error });
2183
2159
  }
2184
- }
2185
- })()
2186
- );
2160
+ });
2161
+ }
2187
2162
  }
2188
2163
  }
2189
2164
  });
@@ -2331,9 +2306,35 @@ export function createAgent<
2331
2306
  removeEventListener: agent.removeEventListener,
2332
2307
  run: inputSchema
2333
2308
  ? async (input: InferSchemaInput<Exclude<TInput, undefined>>) => {
2309
+ // Wrap with span if in HTTP context with tracer
2310
+ if (inHTTPContext()) {
2311
+ const honoCtx = getHTTPContext();
2312
+ const tracer = honoCtx.var.tracer;
2313
+ if (tracer) {
2314
+ return runWithSpan(
2315
+ tracer,
2316
+ agent as Agent<TInput, TOutput, TStream>,
2317
+ honoCtx,
2318
+ async () => await agent.handler(input)
2319
+ );
2320
+ }
2321
+ }
2334
2322
  return await agent.handler(input);
2335
2323
  }
2336
2324
  : async () => {
2325
+ // Wrap with span if in HTTP context with tracer
2326
+ if (inHTTPContext()) {
2327
+ const honoCtx = getHTTPContext();
2328
+ const tracer = honoCtx.var.tracer;
2329
+ if (tracer) {
2330
+ return runWithSpan(
2331
+ tracer,
2332
+ agent as Agent<TInput, TOutput, TStream>,
2333
+ honoCtx,
2334
+ async () => await agent.handler()
2335
+ );
2336
+ }
2337
+ }
2337
2338
  return await agent.handler();
2338
2339
  },
2339
2340
  [INTERNAL_AGENT]: agent, // Store reference to internal agent for testing