@agentuity/runtime 0.1.24 → 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.
- package/dist/_tokens.d.ts.map +1 -1
- package/dist/_tokens.js +9 -8
- package/dist/_tokens.js.map +1 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +228 -196
- package/dist/agent.js.map +1 -1
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +3 -5
- package/dist/middleware.js.map +1 -1
- package/dist/otel/fetch.js +1 -1
- package/dist/otel/fetch.js.map +1 -1
- package/dist/otel/otel.d.ts.map +1 -1
- package/dist/otel/otel.js +2 -29
- package/dist/otel/otel.js.map +1 -1
- package/dist/services/evalrun/http.d.ts.map +1 -1
- package/dist/services/evalrun/http.js +31 -2
- package/dist/services/evalrun/http.js.map +1 -1
- package/dist/services/session/http.d.ts.map +1 -1
- package/dist/services/session/http.js +58 -19
- package/dist/services/session/http.js.map +1 -1
- package/package.json +7 -9
- package/src/_tokens.ts +14 -12
- package/src/agent.ts +260 -259
- package/src/middleware.ts +3 -6
- package/src/otel/fetch.ts +1 -1
- package/src/otel/otel.ts +2 -30
- package/src/services/evalrun/http.ts +45 -10
- 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,
|
|
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
|
-
//
|
|
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 (
|
|
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
|
-
//
|
|
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
|
-
|
|
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
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
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
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
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
|
-
|
|
2004
|
-
|
|
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
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
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
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
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
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
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
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
const
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
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
|
-
|
|
2086
|
-
|
|
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
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
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
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
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
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
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
|
package/src/middleware.ts
CHANGED
|
@@ -290,7 +290,7 @@ export function createOtelMiddleware() {
|
|
|
290
290
|
await context.with(extractedContext, async (): Promise<void> => {
|
|
291
291
|
const tracer = trace.getTracer('http-server');
|
|
292
292
|
await tracer.startActiveSpan(
|
|
293
|
-
|
|
293
|
+
`${method} ${url.pathname}`,
|
|
294
294
|
{
|
|
295
295
|
kind: SpanKind.SERVER,
|
|
296
296
|
attributes: {
|
|
@@ -464,7 +464,7 @@ export function createOtelMiddleware() {
|
|
|
464
464
|
} else if (isError) {
|
|
465
465
|
// Hono caught an error or response is 5xx - report as error
|
|
466
466
|
const errorMessage = honoError
|
|
467
|
-
? honoError.stack ?? honoError.message
|
|
467
|
+
? (honoError.stack ?? honoError.message)
|
|
468
468
|
: `HTTP ${responseStatus}`;
|
|
469
469
|
span.setStatus({
|
|
470
470
|
code: SpanStatusCode.ERROR,
|
|
@@ -483,10 +483,7 @@ export function createOtelMiddleware() {
|
|
|
483
483
|
if (ex instanceof Error) {
|
|
484
484
|
span.recordException(ex);
|
|
485
485
|
}
|
|
486
|
-
const errorMessage =
|
|
487
|
-
ex instanceof Error
|
|
488
|
-
? ex.stack ?? ex.message
|
|
489
|
-
: String(ex);
|
|
486
|
+
const errorMessage = ex instanceof Error ? (ex.stack ?? ex.message) : String(ex);
|
|
490
487
|
span.setStatus({
|
|
491
488
|
code: SpanStatusCode.ERROR,
|
|
492
489
|
message: ex instanceof Error ? ex.message : String(ex),
|
package/src/otel/fetch.ts
CHANGED