stitchkit 0.56.0 → 0.56.2

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 (73) hide show
  1. package/README.md +12 -3
  2. package/dist/agent-runtime/compaction.d.ts +33 -0
  3. package/dist/agent-runtime/compaction.d.ts.map +1 -0
  4. package/dist/agent-runtime/coordinator.d.ts +24 -0
  5. package/dist/agent-runtime/coordinator.d.ts.map +1 -0
  6. package/dist/agent-runtime/events.d.ts +454 -0
  7. package/dist/agent-runtime/events.d.ts.map +1 -0
  8. package/dist/agent-runtime/history.d.ts +11 -0
  9. package/dist/agent-runtime/history.d.ts.map +1 -0
  10. package/dist/agent-runtime/managed-tools.d.ts +18 -0
  11. package/dist/agent-runtime/managed-tools.d.ts.map +1 -0
  12. package/dist/agent-runtime/models.d.ts +51 -0
  13. package/dist/agent-runtime/models.d.ts.map +1 -0
  14. package/dist/agent-runtime/observability.d.ts +134 -0
  15. package/dist/agent-runtime/observability.d.ts.map +1 -0
  16. package/dist/agent-runtime/prompt.d.ts +50 -0
  17. package/dist/agent-runtime/prompt.d.ts.map +1 -0
  18. package/dist/agent-runtime/protocol.d.ts +16 -0
  19. package/dist/agent-runtime/protocol.d.ts.map +1 -0
  20. package/dist/agent-runtime/runtime.d.ts +120 -0
  21. package/dist/agent-runtime/runtime.d.ts.map +1 -0
  22. package/dist/agent-runtime/schemas.d.ts +470 -0
  23. package/dist/agent-runtime/schemas.d.ts.map +1 -0
  24. package/dist/agent-runtime/store.d.ts +905 -0
  25. package/dist/agent-runtime/store.d.ts.map +1 -0
  26. package/dist/agent-runtime/testing.d.ts +17 -0
  27. package/dist/agent-runtime/testing.d.ts.map +1 -0
  28. package/dist/agent-runtime-openrouter.d.ts +6 -0
  29. package/dist/agent-runtime-openrouter.d.ts.map +1 -0
  30. package/dist/agent-runtime-openrouter.js +46 -0
  31. package/dist/agent-runtime.d.ts +13 -0
  32. package/dist/agent-runtime.d.ts.map +1 -0
  33. package/dist/agent-runtime.js +1931 -0
  34. package/dist/cli.js +8 -5
  35. package/dist/index-0nc0cddp.js +178 -0
  36. package/dist/{index-6y759j86.js → index-1tkyng3g.js} +9 -57
  37. package/dist/{index-sm2tjx06.js → index-41wm56v0.js} +2 -2
  38. package/dist/index-6djpbnda.js +56 -0
  39. package/dist/{index-j3dem06f.js → index-7c0gkyvj.js} +5 -3
  40. package/dist/{index-n4nfa7gh.js → index-9zn9fb4e.js} +74 -10
  41. package/dist/{index-xy8fmh6w.js → index-f6pymtqe.js} +3 -3
  42. package/dist/{index-jcc611vh.js → index-gnvzyw0k.js} +2 -2
  43. package/dist/{index-qh4xevf5.js → index-mr617n62.js} +4 -2
  44. package/dist/{index-5r13htq1.js → index-ps5pxp3h.js} +1 -1
  45. package/dist/index-sa2mbwa7.js +336 -0
  46. package/dist/index-smpbdg6k.js +27 -0
  47. package/dist/{index-7eq9va6e.js → index-y2rb7dwx.js} +1 -27
  48. package/dist/{index-escqg10p.js → index-zk5zn2nh.js} +32 -334
  49. package/dist/internal/observability-sink.d.ts +26 -0
  50. package/dist/internal/observability-sink.d.ts.map +1 -0
  51. package/dist/node.js +6 -5
  52. package/dist/observability/audit.d.ts +4 -0
  53. package/dist/observability/audit.d.ts.map +1 -1
  54. package/dist/observability/event.d.ts +5 -0
  55. package/dist/observability/event.d.ts.map +1 -1
  56. package/dist/observability/index.js +29 -186
  57. package/dist/remote.js +4 -3
  58. package/dist/server/create.d.ts.map +1 -1
  59. package/dist/server/error-hook.d.ts +10 -8
  60. package/dist/server/error-hook.d.ts.map +1 -1
  61. package/dist/server/index.js +11 -8
  62. package/dist/server/logger.d.ts.map +1 -1
  63. package/dist/server/request-body.d.ts.map +1 -1
  64. package/dist/testing.js +5 -3
  65. package/dist/tools/agent.d.ts.map +1 -1
  66. package/dist/tools/execute.d.ts +7 -0
  67. package/dist/tools/execute.d.ts.map +1 -1
  68. package/dist/tools.d.ts +2 -1
  69. package/dist/tools.d.ts.map +1 -1
  70. package/dist/tools.js +23 -12
  71. package/llms-full.txt +429 -18
  72. package/llms.txt +1 -0
  73. package/package.json +16 -3
@@ -0,0 +1,336 @@
1
+ import {
2
+ objectShapeKeys
3
+ } from "./index-6djpbnda.js";
4
+ import {
5
+ formatZodError,
6
+ getRequestContext,
7
+ normalizeError,
8
+ runWithRequestContext,
9
+ validateDeclaredOutput
10
+ } from "./index-7c0gkyvj.js";
11
+ import {
12
+ AppError,
13
+ STITCH_ERROR_STATUS,
14
+ isStitchErrorCode,
15
+ isUnsafeKey,
16
+ safeJsonParse
17
+ } from "./index-ps5pxp3h.js";
18
+ import {
19
+ isRecord
20
+ } from "./index-smpbdg6k.js";
21
+
22
+ // src/tools/coerce.ts
23
+ import { z } from "zod";
24
+ function needsJsonCoercion(schema) {
25
+ if (schema instanceof z.ZodArray || schema instanceof z.ZodObject || schema instanceof z.ZodRecord || schema instanceof z.ZodTuple || schema instanceof z.ZodUnion) {
26
+ return true;
27
+ }
28
+ if (schema instanceof z.ZodOptional || schema instanceof z.ZodNullable || schema instanceof z.ZodDefault) {
29
+ return needsJsonCoercion(schema.unwrap());
30
+ }
31
+ return false;
32
+ }
33
+ function acceptsRawString(schema) {
34
+ const type = schema._zod.def.type;
35
+ if (type === "string" || type === "template_literal")
36
+ return true;
37
+ if (schema instanceof z.ZodLiteral) {
38
+ return schema.def.values.some((value) => typeof value === "string");
39
+ }
40
+ if (schema instanceof z.ZodEnum) {
41
+ return schema.options.some((value) => typeof value === "string");
42
+ }
43
+ if (schema instanceof z.ZodOptional || schema instanceof z.ZodNullable || schema instanceof z.ZodDefault) {
44
+ return acceptsRawString(schema.unwrap());
45
+ }
46
+ if (schema instanceof z.ZodUnion) {
47
+ return schema.def.options.some((option) => acceptsRawString(option));
48
+ }
49
+ return false;
50
+ }
51
+ function matchingVariant(union, value) {
52
+ const disc = union.def.discriminator;
53
+ const tag = value[disc];
54
+ for (const option of union.def.options) {
55
+ if (!(option instanceof z.ZodObject))
56
+ continue;
57
+ const field = option.shape[disc];
58
+ if (field instanceof z.ZodLiteral && field.def.values.some((v) => v === tag))
59
+ return option;
60
+ if (field instanceof z.ZodEnum && field.options.some((v) => v === tag))
61
+ return option;
62
+ }
63
+ return;
64
+ }
65
+ function coerceValue(value, schema) {
66
+ if (!schema)
67
+ return value;
68
+ if (schema instanceof z.ZodOptional || schema instanceof z.ZodNullable || schema instanceof z.ZodDefault) {
69
+ return coerceValue(value, schema.unwrap());
70
+ }
71
+ let current = value;
72
+ if (typeof current === "string" && needsJsonCoercion(schema)) {
73
+ if (acceptsRawString(schema))
74
+ return current;
75
+ try {
76
+ current = safeJsonParse(current);
77
+ } catch {
78
+ return value;
79
+ }
80
+ }
81
+ if (schema instanceof z.ZodObject && isRecord(current)) {
82
+ const shape = schema.shape;
83
+ const out = {};
84
+ for (const [key, item] of Object.entries(current)) {
85
+ out[key] = coerceValue(item, shape[key]);
86
+ }
87
+ return out;
88
+ }
89
+ if (schema instanceof z.ZodArray && Array.isArray(current)) {
90
+ return current.map((item) => coerceValue(item, schema.element));
91
+ }
92
+ if (schema instanceof z.ZodDiscriminatedUnion && isRecord(current)) {
93
+ const variant = matchingVariant(schema, current);
94
+ return variant ? coerceValue(current, variant) : current;
95
+ }
96
+ return current;
97
+ }
98
+ function coerceJsonArgs(args, schema) {
99
+ const coerced = coerceValue(args, schema);
100
+ return isRecord(coerced) ? coerced : args;
101
+ }
102
+
103
+ // src/tools/execute.ts
104
+ class ToolExecutionControlError extends Error {
105
+ reason;
106
+ constructor(reason) {
107
+ super(`Agent tool execution stopped: ${reason}`);
108
+ this.name = "ToolExecutionControlError";
109
+ this.reason = reason;
110
+ }
111
+ }
112
+ function isToolExecutionControlError(value) {
113
+ return value instanceof ToolExecutionControlError;
114
+ }
115
+ var normalizedToolErrors = new WeakMap;
116
+ function toolResultFromError(err) {
117
+ const appErr = normalizeError(err);
118
+ const result = {
119
+ ok: false,
120
+ code: appErr.code,
121
+ details: appErr.details ?? { message: appErr.message },
122
+ ...appErr.hint && { hint: appErr.hint }
123
+ };
124
+ normalizedToolErrors.set(result, appErr);
125
+ return result;
126
+ }
127
+ function toolErrorFromResult(result) {
128
+ const retained = normalizedToolErrors.get(result);
129
+ if (retained)
130
+ return retained;
131
+ const details = isRecord(result.details) ? result.details : undefined;
132
+ const message = typeof details?.message === "string" ? details.message : result.code;
133
+ const status = isStitchErrorCode(result.code) ? STITCH_ERROR_STATUS[result.code] : 500;
134
+ return new AppError(result.code, message, status, details, result.hint);
135
+ }
136
+ async function executeToolMethod(method, toolName, rawArgs, context, hooks, lifecycle, coerceJson = false, onOutputStrip, extension, finalizeOutput) {
137
+ return inToolCallContext({ source: context.source, toolName, method }, () => runToolMethod(method, toolName, rawArgs, context, hooks, lifecycle, coerceJson, onOutputStrip, extension, finalizeOutput));
138
+ }
139
+ function inToolCallContext(call, body) {
140
+ const parent = getRequestContext();
141
+ if (!parent)
142
+ return body();
143
+ return runWithRequestContext({
144
+ ...parent,
145
+ trace: parent.trace,
146
+ dimensions: parent.dimensions ? { ...parent.dimensions } : undefined,
147
+ error: undefined,
148
+ source: call.source,
149
+ method: "TOOL",
150
+ path: `/${call.source}/${call.toolName}`,
151
+ serviceName: call.method.serviceName,
152
+ action: call.method.key
153
+ }, body);
154
+ }
155
+ async function runToolMethod(method, toolName, rawArgs, context, hooks, lifecycle, coerceJson, onOutputStrip, extension, finalizeOutput) {
156
+ const startedAt = Date.now();
157
+ let hookContext = context;
158
+ const finish = async (result, thrown) => {
159
+ try {
160
+ await hooks?.afterToolCall?.({
161
+ toolName,
162
+ args: rawArgs,
163
+ result,
164
+ durationMs: Date.now() - startedAt,
165
+ context: hookContext,
166
+ endpoint: method,
167
+ ...thrown !== undefined && { error: thrown }
168
+ });
169
+ } catch (hookError) {
170
+ try {
171
+ console.error("[stitchkit] afterToolCall hook failed:", hookError);
172
+ } catch {}
173
+ }
174
+ return result;
175
+ };
176
+ let beforeRan = false;
177
+ const runBefore = async () => {
178
+ if (beforeRan || !hooks?.beforeToolCall)
179
+ return null;
180
+ beforeRan = true;
181
+ try {
182
+ await hooks.beforeToolCall({
183
+ toolName,
184
+ args: rawArgs,
185
+ context: hookContext,
186
+ endpoint: method
187
+ });
188
+ return null;
189
+ } catch (err) {
190
+ return finish(toolResultFromError(err));
191
+ }
192
+ };
193
+ const finishThrown = async (err) => {
194
+ const beforeFailure2 = await runBefore();
195
+ if (beforeFailure2)
196
+ return beforeFailure2;
197
+ if (hooks?.onToolError) {
198
+ try {
199
+ await hooks.onToolError({
200
+ toolName,
201
+ error: err,
202
+ context: hookContext,
203
+ endpoint: method
204
+ });
205
+ } catch (hookErr) {
206
+ try {
207
+ console.error("[stitchkit] onToolError hook failed:", hookErr);
208
+ } catch {}
209
+ }
210
+ }
211
+ return finish(toolResultFromError(err), err);
212
+ };
213
+ let callArgs = rawArgs;
214
+ let callContext = context;
215
+ if (extension) {
216
+ const extensionKeys = new Set(Object.keys(extension.schema.shape));
217
+ const extensionArgs = Object.fromEntries(Object.entries(rawArgs).filter(([key]) => extensionKeys.has(key)));
218
+ let parsed;
219
+ try {
220
+ parsed = extension.schema.safeParse(extensionArgs);
221
+ } catch (err) {
222
+ return finishThrown(err);
223
+ }
224
+ if (!parsed.success) {
225
+ const beforeFailure2 = await runBefore();
226
+ if (beforeFailure2)
227
+ return beforeFailure2;
228
+ return finish({
229
+ ok: false,
230
+ code: "VALIDATION_ERROR",
231
+ details: { message: `Invalid tool extension: ${formatZodError(parsed.error)}` }
232
+ });
233
+ }
234
+ try {
235
+ const resolved = await extension.resolve({ ...rawArgs, ...parsed.data });
236
+ callContext = {
237
+ ...context,
238
+ ...resolved,
239
+ source: context.source,
240
+ ...context.mcp !== undefined && { mcp: context.mcp }
241
+ };
242
+ hookContext = callContext;
243
+ callArgs = Object.fromEntries(Object.entries(rawArgs).filter(([key]) => !extensionKeys.has(key)));
244
+ } catch (err) {
245
+ return finishThrown(err);
246
+ }
247
+ }
248
+ const beforeFailure = await runBefore();
249
+ if (beforeFailure)
250
+ return beforeFailure;
251
+ const paramKeys = new Set(objectShapeKeys(method.paramsSchema));
252
+ let paramArgs = {};
253
+ let inputArgs = {};
254
+ for (const [key, value] of Object.entries(callArgs)) {
255
+ if (isUnsafeKey(key))
256
+ continue;
257
+ if (paramKeys.has(key))
258
+ paramArgs[key] = value;
259
+ else
260
+ inputArgs[key] = value;
261
+ }
262
+ if (coerceJson) {
263
+ paramArgs = coerceJsonArgs(paramArgs, method.paramsSchema);
264
+ inputArgs = coerceJsonArgs(inputArgs, method.inputSchema);
265
+ }
266
+ let params;
267
+ if (method.paramsSchema) {
268
+ let result;
269
+ try {
270
+ result = method.paramsSchema.safeParse(paramArgs);
271
+ } catch (err) {
272
+ return finishThrown(err);
273
+ }
274
+ if (!result.success) {
275
+ return finish({
276
+ ok: false,
277
+ code: "VALIDATION_ERROR",
278
+ details: { message: `Invalid params: ${formatZodError(result.error)}` }
279
+ });
280
+ }
281
+ params = result.data;
282
+ }
283
+ let input;
284
+ if (method.inputSchema) {
285
+ let result;
286
+ try {
287
+ result = method.inputSchema.safeParse(inputArgs);
288
+ } catch (err) {
289
+ return finishThrown(err);
290
+ }
291
+ if (!result.success) {
292
+ return finish({
293
+ ok: false,
294
+ code: "VALIDATION_ERROR",
295
+ details: { message: `Invalid input: ${formatZodError(result.error)}` }
296
+ });
297
+ }
298
+ input = result.data;
299
+ }
300
+ try {
301
+ const ctx = {
302
+ ...callContext,
303
+ params,
304
+ input,
305
+ source: context.source
306
+ };
307
+ if (lifecycle?.beforeHandle) {
308
+ await lifecycle.beforeHandle(ctx, method);
309
+ }
310
+ let data = await method.handler(ctx);
311
+ if (lifecycle?.afterHandle) {
312
+ const transformed = await lifecycle.afterHandle(ctx, data, method);
313
+ if (transformed !== undefined)
314
+ data = transformed;
315
+ }
316
+ const checked = validateDeclaredOutput(method.outputSchema, data, onOutputStrip);
317
+ if (!checked.ok) {
318
+ return finish({
319
+ ok: false,
320
+ code: "INTERNAL_SERVER_ERROR",
321
+ details: { message: checked.message }
322
+ });
323
+ }
324
+ data = checked.data;
325
+ if (finalizeOutput)
326
+ data = await finalizeOutput(data);
327
+ const output = (data === undefined || data === null) && !method.outputSchema ? { status: "ok" } : data;
328
+ return finish({ ok: true, data: output });
329
+ } catch (err) {
330
+ if (isToolExecutionControlError(err))
331
+ throw err;
332
+ return finishThrown(err);
333
+ }
334
+ }
335
+
336
+ export { coerceJsonArgs, ToolExecutionControlError, isToolExecutionControlError, toolResultFromError, toolErrorFromResult, executeToolMethod };
@@ -0,0 +1,27 @@
1
+ // src/internal/typed.ts
2
+ function typedEntries(value) {
3
+ return Object.entries(value);
4
+ }
5
+ function isRecord(value) {
6
+ return typeof value === "object" && value !== null && !Array.isArray(value);
7
+ }
8
+ function callRuntimeHandler(handler, context) {
9
+ if (typeof handler !== "function") {
10
+ throw new TypeError("Runtime handler must be a function");
11
+ }
12
+ return Reflect.apply(handler, undefined, [context]);
13
+ }
14
+ function transportResult(value) {
15
+ return value;
16
+ }
17
+ function mapObject(source, mapper) {
18
+ const result = {};
19
+ for (const [key, value] of typedEntries(source)) {
20
+ const mapped = mapper(key, value);
21
+ if (mapped !== undefined)
22
+ result[key] = mapped;
23
+ }
24
+ return result;
25
+ }
26
+
27
+ export { typedEntries, isRecord, callRuntimeHandler, transportResult, mapObject };
@@ -120,30 +120,4 @@ function parseTrailingWildcard(path) {
120
120
  return wildcard;
121
121
  }
122
122
 
123
- // src/internal/typed.ts
124
- function typedEntries(value) {
125
- return Object.entries(value);
126
- }
127
- function isRecord(value) {
128
- return typeof value === "object" && value !== null && !Array.isArray(value);
129
- }
130
- function callRuntimeHandler(handler, context) {
131
- if (typeof handler !== "function") {
132
- throw new TypeError("Runtime handler must be a function");
133
- }
134
- return Reflect.apply(handler, undefined, [context]);
135
- }
136
- function transportResult(value) {
137
- return value;
138
- }
139
- function mapObject(source, mapper) {
140
- const result = {};
141
- for (const [key, value] of typedEntries(source)) {
142
- const mapped = mapper(key, value);
143
- if (mapped !== undefined)
144
- result[key] = mapped;
145
- }
146
- return result;
147
- }
148
-
149
- export { parseTrailingWildcard, typedEntries, isRecord, callRuntimeHandler, transportResult, mapObject, createTraceContext, parseTraceparent, formatTraceparent, resolveTraceContext, childSpan, resolvePropagationContext };
123
+ export { parseTrailingWildcard, createTraceContext, parseTraceparent, formatTraceparent, resolveTraceContext, childSpan, resolvePropagationContext };