stitchkit 0.30.0 → 0.32.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/cli.js +1 -1
- package/dist/{index-zj1s68tb.js → index-36qnfzxe.js} +3 -3
- package/dist/observability/audit.d.ts.map +1 -1
- package/dist/observability/index.js +11 -2
- package/dist/tools/execute.d.ts +12 -1
- package/dist/tools/execute.d.ts.map +1 -1
- package/dist/tools.d.ts +1 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +1 -1
- package/llms-full.txt +48 -9
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -348,8 +348,8 @@ function toolResultFromError(err) {
|
|
|
348
348
|
}
|
|
349
349
|
async function executeToolMethod(method, toolName, rawArgs, context, hooks, lifecycle, coerceJson = false, onOutputStrip) {
|
|
350
350
|
const startedAt = Date.now();
|
|
351
|
-
const finish = async (result) => {
|
|
352
|
-
await hooks?.afterToolCall?.(toolName, rawArgs, result, Date.now() - startedAt, context, method);
|
|
351
|
+
const finish = async (result, thrown) => {
|
|
352
|
+
await hooks?.afterToolCall?.(toolName, rawArgs, result, Date.now() - startedAt, context, method, thrown);
|
|
353
353
|
return result;
|
|
354
354
|
};
|
|
355
355
|
if (hooks?.beforeToolCall) {
|
|
@@ -430,7 +430,7 @@ async function executeToolMethod(method, toolName, rawArgs, context, hooks, life
|
|
|
430
430
|
console.error("[stitchkit] onToolError hook failed:", hookErr);
|
|
431
431
|
}
|
|
432
432
|
}
|
|
433
|
-
return finish(toolResultFromError(err));
|
|
433
|
+
return finish(toolResultFromError(err), err);
|
|
434
434
|
}
|
|
435
435
|
}
|
|
436
436
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/observability/audit.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,kBAAkB,CAAC;AAElE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAe,KAAK,eAAe,EAAmB,MAAM,YAAY,CAAC;AAGhF,oCAAoC;AACpC,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,KAAK,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,iFAAiF;IACjF,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC;IAC1C,yEAAyE;IACzE,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED,qEAAqE;AACrE,MAAM,WAAW,SAAS;IACxB;;;;OAIG;IACH,IAAI,EAAE,CAAC,CAAC,EACN,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,KACpD,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpD;;;OAGG;IACH,QAAQ,EAAE,aAAa,CAAC;CACzB;
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/observability/audit.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,kBAAkB,CAAC;AAElE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAe,KAAK,eAAe,EAAmB,MAAM,YAAY,CAAC;AAGhF,oCAAoC;AACpC,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,KAAK,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,iFAAiF;IACjF,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC;IAC1C,yEAAyE;IACzE,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED,qEAAqE;AACrE,MAAM,WAAW,SAAS;IACxB;;;;OAIG;IACH,IAAI,EAAE,CAAC,CAAC,EACN,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,KACpD,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpD;;;OAGG;IACH,QAAQ,EAAE,aAAa,CAAC;CACzB;AAyCD,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CA6G9D"}
|
|
@@ -109,6 +109,15 @@ function toolErrorMessage(result) {
|
|
|
109
109
|
}
|
|
110
110
|
return hint;
|
|
111
111
|
}
|
|
112
|
+
function auditErrorMessage(result, thrown) {
|
|
113
|
+
if (result.code === "INTERNAL_SERVER_ERROR" && thrown !== undefined) {
|
|
114
|
+
if (thrown instanceof Error)
|
|
115
|
+
return thrown.message;
|
|
116
|
+
if (typeof thrown === "string")
|
|
117
|
+
return thrown;
|
|
118
|
+
}
|
|
119
|
+
return toolErrorMessage(result);
|
|
120
|
+
}
|
|
112
121
|
function readString(value) {
|
|
113
122
|
return typeof value === "string" ? value : undefined;
|
|
114
123
|
}
|
|
@@ -169,7 +178,7 @@ function createAuditHook(config) {
|
|
|
169
178
|
};
|
|
170
179
|
};
|
|
171
180
|
const toolCall = {
|
|
172
|
-
afterToolCall: (toolName, args, result, durationMs, context, endpoint) => {
|
|
181
|
+
afterToolCall: (toolName, args, result, durationMs, context, endpoint, thrown) => {
|
|
173
182
|
const requestCtx = getRequestContext();
|
|
174
183
|
const span = requestCtx ? childSpan(requestCtx.trace) : createTraceContext();
|
|
175
184
|
const measure = result.ok ? measureSize(result.data) : { resultSize: null, responseBytes: 0 };
|
|
@@ -189,7 +198,7 @@ function createAuditHook(config) {
|
|
|
189
198
|
statusCode: result.ok ? 200 : 400,
|
|
190
199
|
durationMs,
|
|
191
200
|
errorCode: result.ok ? undefined : result.code,
|
|
192
|
-
errorMessage: result.ok ? undefined :
|
|
201
|
+
errorMessage: result.ok ? undefined : auditErrorMessage(result, thrown),
|
|
193
202
|
...!result.ok && result.details !== undefined && {
|
|
194
203
|
errorDetail: sanitizePayload(result.details, sanitize)
|
|
195
204
|
},
|
package/dist/tools/execute.d.ts
CHANGED
|
@@ -15,7 +15,18 @@ export interface ToolCallContext {
|
|
|
15
15
|
}
|
|
16
16
|
export interface ToolCallHooks {
|
|
17
17
|
beforeToolCall?: (toolName: string, args: Record<string, unknown>, context: ToolCallContext, endpoint: MethodDef) => void | Promise<void>;
|
|
18
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Every finished call, success and failure alike — the record of the call.
|
|
20
|
+
*
|
|
21
|
+
* `error` is the value **as thrown**, present only when the call failed by
|
|
22
|
+
* throwing (never for an argument-validation failure, an output-schema
|
|
23
|
+
* mismatch or a `beforeToolCall` rejection — those never had a raw value).
|
|
24
|
+
* It is the same value `onToolError` receives, handed here too so a single
|
|
25
|
+
* hook can build one row that names the cause: the `result` alone cannot,
|
|
26
|
+
* because an unexpected throw is scrubbed to a bare `INTERNAL_SERVER_ERROR`.
|
|
27
|
+
* A six-parameter hook is unaffected.
|
|
28
|
+
*/
|
|
29
|
+
afterToolCall?: (toolName: string, args: Record<string, unknown>, result: ToolResult, durationMs: number, context: ToolCallContext, endpoint: MethodDef, error?: unknown) => void | Promise<void>;
|
|
19
30
|
/**
|
|
20
31
|
* The handler path threw — the value **as thrown**, before it is normalised
|
|
21
32
|
* into a `ToolResult`. The tool-side answer to HTTP's `hooks.onError`, and the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../src/tools/execute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,MAAM,UAAU,GAClB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC3B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAElE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,eAAe,CAAC;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,cAAc,CAAC,EAAE,CACf,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,SAAS,KAChB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,aAAa,CAAC,EAAE,CACd,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../src/tools/execute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,MAAM,UAAU,GAClB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC3B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAElE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,eAAe,CAAC;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,cAAc,CAAC,EAAE,CACf,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,SAAS,KAChB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,CACd,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,SAAS,EACnB,KAAK,CAAC,EAAE,OAAO,KACZ,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,WAAW,CAAC,EAAE,CACZ,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,SAAS,KAChB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;AAEjF;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,aAAa;IAC5B,oDAAoD;IACpD,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClF,0DAA0D;IAC1D,WAAW,CAAC,EAAE,CACZ,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,SAAS,KAChB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACjC;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,EAAE;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC,CAQpF;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAC5C,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,OAAO,EAAE,eAAe,EACxB,KAAK,CAAC,EAAE,aAAa,EACrB,SAAS,CAAC,EAAE,aAAa,EACzB,UAAU,UAAQ,EAClB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,GACxC,OAAO,CAAC,UAAU,CAAC,CAwIrB"}
|
package/dist/tools.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export { type CliConfig, createCli } from './tools/cli';
|
|
|
4
4
|
export type { ExitCodeMap } from './tools/cli-format';
|
|
5
5
|
export type { CliWaitConfig } from './tools/cli-wait';
|
|
6
6
|
export { coerceJsonArgs } from './tools/coerce';
|
|
7
|
-
export type { ErrorHintFn, ToolCallHooks, ToolLifecycle, ToolResult } from './tools/execute';
|
|
7
|
+
export type { ErrorHintFn, ToolCallContext, ToolCallHooks, ToolLifecycle, ToolResult, } from './tools/execute';
|
|
8
8
|
export { flattenDiscriminatedUnion, flattenUnionsDeep } from './tools/flatten';
|
|
9
9
|
export { listToolNames, type ToolNameEntry } from './tools/list-names';
|
|
10
10
|
export { buildToolManifest, type ToolManifestEntry } from './tools/manifest';
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,gBAAgB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACrF,OAAO,EAAE,KAAK,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxD,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,YAAY,
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,gBAAgB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACrF,OAAO,EAAE,KAAK,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxD,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,YAAY,EACV,WAAW,EACX,eAAe,EACf,aAAa,EACb,aAAa,EACb,UAAU,GACX,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,yBAAyB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EACL,cAAc,EACd,KAAK,wBAAwB,EAC7B,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,QAAQ,EACR,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,EAClB,KAAK,SAAS,EACd,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,KAAK,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAClF,OAAO,EAAE,KAAK,kBAAkB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,EACvB,KAAK,uBAAuB,EAC5B,4BAA4B,EAC5B,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,kBAAkB,EAClB,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAChB,KAAK,gBAAgB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,KAAK,sBAAsB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC9E,OAAO,EACL,gBAAgB,EAChB,KAAK,cAAc,EACnB,KAAK,gBAAgB,GACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,KAAK,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EACL,mBAAmB,EACnB,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,KAAK,eAAe,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/tools.js
CHANGED
package/llms-full.txt
CHANGED
|
@@ -3024,9 +3024,10 @@ metric, a custom log line, anything that is not a full audit row.
|
|
|
3024
3024
|
|
|
3025
3025
|
`afterHandle(ctx, result, endpoint)` runs after a handler returns;
|
|
3026
3026
|
`onError(ctx, error, endpoint)` when one throws. `afterToolCall(toolName, args,
|
|
3027
|
-
result, durationMs, context)` runs after every tool call —
|
|
3028
|
-
alike — carrying the tool name, the arguments, the result, the
|
|
3029
|
-
call context
|
|
3027
|
+
result, durationMs, context, endpoint, error)` runs after every tool call —
|
|
3028
|
+
success and error alike — carrying the tool name, the arguments, the result, the
|
|
3029
|
+
duration, the call context, the endpoint identity, and (only when the call failed
|
|
3030
|
+
by throwing) the raw thrown value.
|
|
3030
3031
|
|
|
3031
3032
|
```ts
|
|
3032
3033
|
createMcpHandler({
|
|
@@ -3059,12 +3060,11 @@ createMcpHandler({
|
|
|
3059
3060
|
serverInfo, auth, services,
|
|
3060
3061
|
hooks: {
|
|
3061
3062
|
onToolError: (toolName, error, _context, endpoint) => {
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
code: 'TOOL_FAILED',
|
|
3063
|
+
reportToolFailure({
|
|
3064
|
+
tool: toolName,
|
|
3065
|
+
action: endpoint.key,
|
|
3066
3066
|
message: error instanceof Error ? error.message : String(error),
|
|
3067
|
-
|
|
3067
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
3068
3068
|
})
|
|
3069
3069
|
},
|
|
3070
3070
|
},
|
|
@@ -3087,6 +3087,44 @@ observe. (This is also why it lives on `ToolCallHooks` rather than being an
|
|
|
3087
3087
|
`Response`, which a tool call has no use for, and a whole `createServer` hooks
|
|
3088
3088
|
object must stay assignable to `ToolLifecycle`.)
|
|
3089
3089
|
|
|
3090
|
+
**Do not reach for `setRequestError` here.** It writes to the *request* context,
|
|
3091
|
+
which `createAuditHook`'s **tool** row does not read: a tool event takes
|
|
3092
|
+
`errorCode` / `errorMessage` / `errorDetail` from the `ToolResult`, and only
|
|
3093
|
+
identity and `dimensions` from the context. Calling it in `onToolError` would
|
|
3094
|
+
leave the tool row exactly as scrubbed as before — and for MCP over HTTP it would
|
|
3095
|
+
also write the cause into the log line of the enclosing `/mcp` request, turning
|
|
3096
|
+
one incident into two records. It is right for the **HTTP** path, where the
|
|
3097
|
+
request *is* the record.
|
|
3098
|
+
|
|
3099
|
+
### One row that names the cause
|
|
3100
|
+
|
|
3101
|
+
You do not need to correlate the two hooks yourself. `afterToolCall` receives the
|
|
3102
|
+
same raw value as a **seventh parameter**, so one hook can build one record:
|
|
3103
|
+
|
|
3104
|
+
```ts
|
|
3105
|
+
hooks: {
|
|
3106
|
+
afterToolCall: (toolName, args, result, durationMs, context, endpoint, error) => {
|
|
3107
|
+
void writeRow({ toolName, result, durationMs, cause: error, endpoint })
|
|
3108
|
+
},
|
|
3109
|
+
}
|
|
3110
|
+
```
|
|
3111
|
+
|
|
3112
|
+
`error` is present only when the call failed by **throwing** — a
|
|
3113
|
+
validation failure or a `beforeToolCall` rejection leaves it `undefined`, because
|
|
3114
|
+
neither ever had a raw value to lose. The parameter is additive: a six-parameter
|
|
3115
|
+
hook written before it keeps compiling and keeps firing.
|
|
3116
|
+
|
|
3117
|
+
`createAuditHook` uses it already. Where the envelope was scrubbed to
|
|
3118
|
+
`INTERNAL_SERVER_ERROR`, the row's `errorMessage` becomes the real message
|
|
3119
|
+
instead of the placeholder; a truthful envelope (a thrown `AppError`, a
|
|
3120
|
+
`ZodError`) is left alone, `errorCode` and `errorDetail` are untouched, and the
|
|
3121
|
+
stack is not written — that is `onToolError`'s job, for a tracker that wants it.
|
|
3122
|
+
The caller still receives the scrubbed envelope in every case: the raw text
|
|
3123
|
+
reaches your server-side record, never the response. → ADR 0042
|
|
3124
|
+
|
|
3125
|
+
So the two hooks divide by **purpose**, not by capability — `onToolError` for a
|
|
3126
|
+
sink of your own (a tracker, a stack, an alert), `afterToolCall` for the record.
|
|
3127
|
+
|
|
3090
3128
|
### Keying a row on (service, action)
|
|
3091
3129
|
|
|
3092
3130
|
`createAuditHook` already keys every event by **service** and **action**
|
|
@@ -3858,9 +3896,10 @@ Server-only. Turns contracts into MCP and AI-agent tools. Needs the
|
|
|
3858
3896
|
| `Toolkit` | _type_ | the context-pinned tool surface from `createToolkit` |
|
|
3859
3897
|
| `ToolExtend` | _type_ | extra-args extension for `mountMcp` / `mountAgent` |
|
|
3860
3898
|
| `ToolLifecycle` | _type_ | `beforeHandle` / `afterHandle` gate for tool calls — [guide](../guide/mcp-and-agents.md#guarding-tools--lifecycle) |
|
|
3861
|
-
| `ToolCallHooks` | _type_ | `beforeToolCall` / `afterToolCall` / `onToolError` observability hooks — the
|
|
3899
|
+
| `ToolCallHooks` | _type_ | `beforeToolCall` / `afterToolCall` / `onToolError` observability hooks — the raw thrown value reaches both of the last two (`afterToolCall`'s 7th parameter), because normalisation scrubs an unexpected error to `INTERNAL_SERVER_ERROR` ([guide](../guide/observability.md#the-cause-behind-a-failed-tool-call)) |
|
|
3862
3900
|
| `ErrorHintFn` | _type_ | `(toolName, errorCode) => string \| null` — a per-tool recovery hint, shared by every mount |
|
|
3863
3901
|
| `ToolResult` | _type_ | the result of one tool call |
|
|
3902
|
+
| `ToolCallContext` | _type_ | the context every tool hook receives — `{ source }` plus whatever the mount's `context` added |
|
|
3864
3903
|
| `ToolNameEntry` | _type_ | one `listToolNames` row — `{ name, service, method, transports }` |
|
|
3865
3904
|
| `IncompatibleSchemaPolicy` | _type_ | `'throw' \| 'skip' \| 'warn'` |
|
|
3866
3905
|
| `McpMediaContent` | _type_ | a multimodal MCP content item |
|
package/package.json
CHANGED