@keystrokehq/keystroke 0.1.20 → 0.1.22

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 (41) hide show
  1. package/dist/agent.cjs +72 -54
  2. package/dist/agent.cjs.map +1 -1
  3. package/dist/agent.d.cts +2 -2
  4. package/dist/agent.d.mts +2 -2
  5. package/dist/agent.mjs +71 -52
  6. package/dist/agent.mjs.map +1 -1
  7. package/dist/{dist-KpQEao0i.mjs → dist-B1Pjv-cM.mjs} +666 -21
  8. package/dist/dist-B1Pjv-cM.mjs.map +1 -0
  9. package/dist/{dist-BFCT4aiu.cjs → dist-D69ocJ7u.cjs} +728 -23
  10. package/dist/dist-D69ocJ7u.cjs.map +1 -0
  11. package/dist/{index-Dlu1kaci.d.cts → index-BQOZkLWG.d.cts} +10 -34
  12. package/dist/index-BQOZkLWG.d.cts.map +1 -0
  13. package/dist/{index-I9DneAMW.d.mts → index-CGf1NwA4.d.mts} +10 -34
  14. package/dist/index-CGf1NwA4.d.mts.map +1 -0
  15. package/dist/{index-BUYoOHa1.d.mts → index-WHR4qX4x.d.mts} +10 -3
  16. package/dist/index-WHR4qX4x.d.mts.map +1 -0
  17. package/dist/{index-Dzm0OSN4.d.cts → index-wpyFrBvl.d.cts} +10 -3
  18. package/dist/index-wpyFrBvl.d.cts.map +1 -0
  19. package/dist/{token-dA7JRmgB.cjs → token-DZEJHEnH.cjs} +2 -2
  20. package/dist/{token-dA7JRmgB.cjs.map → token-DZEJHEnH.cjs.map} +1 -1
  21. package/dist/{token-shJjdG3B.mjs → token-D_x8iwF8.mjs} +2 -2
  22. package/dist/{token-shJjdG3B.mjs.map → token-D_x8iwF8.mjs.map} +1 -1
  23. package/dist/trigger.cjs +1 -1
  24. package/dist/trigger.d.cts +2 -2
  25. package/dist/trigger.d.mts +2 -2
  26. package/dist/trigger.mjs +1 -1
  27. package/dist/workflow.cjs +3 -1
  28. package/dist/workflow.d.cts +2 -2
  29. package/dist/workflow.d.mts +2 -2
  30. package/dist/workflow.mjs +2 -2
  31. package/package.json +2 -2
  32. package/dist/dist-BFCT4aiu.cjs.map +0 -1
  33. package/dist/dist-BekOBuw8.cjs +0 -665
  34. package/dist/dist-BekOBuw8.cjs.map +0 -1
  35. package/dist/dist-C-1uJk5f.mjs +0 -612
  36. package/dist/dist-C-1uJk5f.mjs.map +0 -1
  37. package/dist/dist-KpQEao0i.mjs.map +0 -1
  38. package/dist/index-BUYoOHa1.d.mts.map +0 -1
  39. package/dist/index-Dlu1kaci.d.cts.map +0 -1
  40. package/dist/index-Dzm0OSN4.d.cts.map +0 -1
  41. package/dist/index-I9DneAMW.d.mts.map +0 -1
@@ -1,5 +1,6 @@
1
1
  import { n as __require, r as __toESM, t as __commonJSMin } from "./chunk-DnnnRqeS.mjs";
2
- import { _ as normalizeCredentialList, a as buildConnectDeeplink, h as mcpEntityId } from "./dist-_i6Rguqn.mjs";
2
+ import { _ as normalizeCredentialList, a as buildConnectDeeplink, h as mcpEntityId, l as defineTool } from "./dist-_i6Rguqn.mjs";
3
+ import { _ as runWithMcpCredentialContext, a as getActionCredentialRequirements, c as getRunSignal, i as executeAction, l as getWorkflowRunHandle, m as registerWorkflowRunGetter } from "./dist-CAZlfg_P.mjs";
3
4
  import { createRequire } from "node:module";
4
5
  import { z } from "zod";
5
6
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -2179,7 +2180,7 @@ function asSchema(schema) {
2179
2180
  type: "object",
2180
2181
  properties: {},
2181
2182
  additionalProperties: false
2182
- }) : isSchema(schema) ? schema : "~standard" in schema ? schema["~standard"].vendor === "zod" ? zodSchema(schema) : standardSchema(schema) : schema();
2183
+ }) : isSchema(schema) ? schema : "~standard" in schema ? schema["~standard"].vendor === "zod" ? zodSchema$1(schema) : standardSchema(schema) : schema();
2183
2184
  }
2184
2185
  function standardSchema(standardSchema2) {
2185
2186
  return jsonSchema(() => addAdditionalPropertiesToJsonSchema(standardSchema2["~standard"].jsonSchema.input({ target: "draft-07" })), { validate: async (value) => {
@@ -2231,7 +2232,7 @@ function zod4Schema(zodSchema2, options) {
2231
2232
  function isZod4Schema(zodSchema2) {
2232
2233
  return "_zod" in zodSchema2;
2233
2234
  }
2234
- function zodSchema(zodSchema2, options) {
2235
+ function zodSchema$1(zodSchema2, options) {
2235
2236
  if (isZod4Schema(zodSchema2)) return zod4Schema(zodSchema2, options);
2236
2237
  else return zod3Schema(zodSchema2, options);
2237
2238
  }
@@ -2692,7 +2693,7 @@ var require_get_vercel_oidc_token = /* @__PURE__ */ __commonJSMin(((exports, mod
2692
2693
  err = error;
2693
2694
  }
2694
2695
  try {
2695
- const [{ getTokenPayload, isExpired }, { refreshToken }] = await Promise.all([await Promise.resolve().then(() => /* @__PURE__ */ __toESM(require_token_util())), await import("./token-shJjdG3B.mjs").then((m) => /* @__PURE__ */ __toESM(m.default))]);
2696
+ const [{ getTokenPayload, isExpired }, { refreshToken }] = await Promise.all([await Promise.resolve().then(() => /* @__PURE__ */ __toESM(require_token_util())), await import("./token-D_x8iwF8.mjs").then((m) => /* @__PURE__ */ __toESM(m.default))]);
2696
2697
  if (!token || isExpired(getTokenPayload(token), options?.expirationBufferMs)) {
2697
2698
  await refreshToken(options);
2698
2699
  token = getVercelOidcTokenSync();
@@ -3276,7 +3277,7 @@ var GatewayRateLimitError = class extends (_b4 = GatewayError, _a4$1 = symbol4$1
3276
3277
  var name4$1 = "GatewayModelNotFoundError";
3277
3278
  var marker5$1 = `vercel.ai.gateway.error.${name4$1}`;
3278
3279
  var symbol5$1 = Symbol.for(marker5$1);
3279
- var modelNotFoundParamSchema = lazySchema(() => zodSchema(z$1.object({ modelId: z$1.string() })));
3280
+ var modelNotFoundParamSchema = lazySchema(() => zodSchema$1(z$1.object({ modelId: z$1.string() })));
3280
3281
  var _a5$1, _b5;
3281
3282
  var GatewayModelNotFoundError = class extends (_b5 = GatewayError, _a5$1 = symbol5$1, _b5) {
3282
3283
  constructor({ message = "Model not found", statusCode = 404, modelId, cause, generationId } = {}) {
@@ -3457,7 +3458,7 @@ async function createGatewayErrorFromResponse({ response, statusCode, defaultMes
3457
3458
  });
3458
3459
  }
3459
3460
  }
3460
- var gatewayErrorResponseSchema = lazySchema(() => zodSchema(z$1.object({
3461
+ var gatewayErrorResponseSchema = lazySchema(() => zodSchema$1(z$1.object({
3461
3462
  error: z$1.object({
3462
3463
  message: z$1.string(),
3463
3464
  type: z$1.string().nullish(),
@@ -3555,7 +3556,7 @@ async function parseAuthMethod(headers) {
3555
3556
  });
3556
3557
  return result.success ? result.value : void 0;
3557
3558
  }
3558
- var gatewayAuthMethodSchema = lazySchema(() => zodSchema(z$1.union([z$1.literal("api-key"), z$1.literal("oidc")])));
3559
+ var gatewayAuthMethodSchema = lazySchema(() => zodSchema$1(z$1.union([z$1.literal("api-key"), z$1.literal("oidc")])));
3559
3560
  var KNOWN_MODEL_TYPES = [
3560
3561
  "embedding",
3561
3562
  "image",
@@ -3605,7 +3606,7 @@ var GatewayFetchMetadata = class {
3605
3606
  }
3606
3607
  }
3607
3608
  };
3608
- var gatewayAvailableModelsResponseSchema = lazySchema(() => zodSchema(z$1.object({ models: z$1.array(z$1.object({
3609
+ var gatewayAvailableModelsResponseSchema = lazySchema(() => zodSchema$1(z$1.object({ models: z$1.array(z$1.object({
3609
3610
  id: z$1.string(),
3610
3611
  name: z$1.string(),
3611
3612
  description: z$1.string().nullish(),
@@ -3627,7 +3628,7 @@ var gatewayAvailableModelsResponseSchema = lazySchema(() => zodSchema(z$1.object
3627
3628
  }),
3628
3629
  modelType: z$1.string().nullish()
3629
3630
  })).transform((models) => models.filter((m) => m.modelType == null || KNOWN_MODEL_TYPES.includes(m.modelType))) })));
3630
- var gatewayCreditsResponseSchema = lazySchema(() => zodSchema(z$1.object({
3631
+ var gatewayCreditsResponseSchema = lazySchema(() => zodSchema$1(z$1.object({
3631
3632
  balance: z$1.string(),
3632
3633
  total_used: z$1.string()
3633
3634
  }).transform(({ balance, total_used }) => ({
@@ -3667,7 +3668,7 @@ var GatewaySpendReport = class {
3667
3668
  }
3668
3669
  }
3669
3670
  };
3670
- var gatewaySpendReportResponseSchema = lazySchema(() => zodSchema(z$1.object({ results: z$1.array(z$1.object({
3671
+ var gatewaySpendReportResponseSchema = lazySchema(() => zodSchema$1(z$1.object({ results: z$1.array(z$1.object({
3671
3672
  day: z$1.string().optional(),
3672
3673
  hour: z$1.string().optional(),
3673
3674
  user: z$1.string().optional(),
@@ -3717,7 +3718,7 @@ var GatewayGenerationInfoFetcher = class {
3717
3718
  }
3718
3719
  }
3719
3720
  };
3720
- var gatewayGenerationInfoResponseSchema = lazySchema(() => zodSchema(z$1.object({ data: z$1.object({
3721
+ var gatewayGenerationInfoResponseSchema = lazySchema(() => zodSchema$1(z$1.object({ data: z$1.object({
3721
3722
  id: z$1.string(),
3722
3723
  total_cost: z$1.number(),
3723
3724
  upstream_inference_cost: z$1.number(),
@@ -3969,7 +3970,7 @@ var gatewayEmbeddingWarningSchema = z$1.discriminatedUnion("type", [
3969
3970
  message: z$1.string()
3970
3971
  })
3971
3972
  ]);
3972
- var gatewayEmbeddingResponseSchema = lazySchema(() => zodSchema(z$1.object({
3973
+ var gatewayEmbeddingResponseSchema = lazySchema(() => zodSchema$1(z$1.object({
3973
3974
  embeddings: z$1.array(z$1.array(z$1.number())),
3974
3975
  usage: z$1.object({ tokens: z$1.number() }).nullish(),
3975
3976
  warnings: z$1.array(gatewayEmbeddingWarningSchema).optional(),
@@ -4321,7 +4322,7 @@ var gatewayRerankingWarningSchema = z$1.discriminatedUnion("type", [
4321
4322
  message: z$1.string()
4322
4323
  })
4323
4324
  ]);
4324
- var gatewayRerankingResponseSchema = lazySchema(() => zodSchema(z$1.object({
4325
+ var gatewayRerankingResponseSchema = lazySchema(() => zodSchema$1(z$1.object({
4325
4326
  ranking: z$1.array(z$1.object({
4326
4327
  index: z$1.number(),
4327
4328
  relevanceScore: z$1.number()
@@ -4556,7 +4557,7 @@ function toGatewayRealtimeUrl(baseURL, modelId) {
4556
4557
  }
4557
4558
  var exaSearchToolFactory = createProviderExecutedToolFactory({
4558
4559
  id: "gateway.exa_search",
4559
- inputSchema: lazySchema(() => zodSchema(z.object({
4560
+ inputSchema: lazySchema(() => zodSchema$1(z.object({
4560
4561
  query: z.string().describe("Natural-language web search query. This is required."),
4561
4562
  type: z.enum([
4562
4563
  "auto",
@@ -4619,7 +4620,7 @@ var exaSearchToolFactory = createProviderExecutedToolFactory({
4619
4620
  }).optional()
4620
4621
  }).optional().describe("Controls extracted page content and freshness.")
4621
4622
  }))),
4622
- outputSchema: lazySchema(() => zodSchema(z.union([z.object({
4623
+ outputSchema: lazySchema(() => zodSchema$1(z.union([z.object({
4623
4624
  requestId: z.string(),
4624
4625
  searchType: z.string().optional(),
4625
4626
  resolvedSearchType: z.string().optional(),
@@ -4662,7 +4663,7 @@ var exaSearchToolFactory = createProviderExecutedToolFactory({
4662
4663
  var exaSearch = (config = {}) => exaSearchToolFactory(config);
4663
4664
  var parallelSearchToolFactory = createProviderExecutedToolFactory({
4664
4665
  id: "gateway.parallel_search",
4665
- inputSchema: lazySchema(() => zodSchema(z.object({
4666
+ inputSchema: lazySchema(() => zodSchema$1(z.object({
4666
4667
  objective: z.string().describe("Natural-language description of the web research goal, including source or freshness guidance and broader context from the task. Maximum 5000 characters."),
4667
4668
  search_queries: z.array(z.string()).optional().describe("Optional search queries to supplement the objective. Maximum 200 characters per query."),
4668
4669
  mode: z.enum(["one-shot", "agentic"]).optional().describe("Mode preset: \"one-shot\" for comprehensive results with longer excerpts (default), \"agentic\" for concise, token-efficient results for multi-step workflows."),
@@ -4678,7 +4679,7 @@ var parallelSearchToolFactory = createProviderExecutedToolFactory({
4678
4679
  }).optional().describe("Excerpt configuration for controlling result length."),
4679
4680
  fetch_policy: z.object({ max_age_seconds: z.number().optional().describe("Maximum age in seconds for cached content. Set to 0 to always fetch fresh content.") }).optional().describe("Fetch policy for controlling content freshness.")
4680
4681
  }))),
4681
- outputSchema: lazySchema(() => zodSchema(z.union([z.object({
4682
+ outputSchema: lazySchema(() => zodSchema$1(z.union([z.object({
4682
4683
  searchId: z.string(),
4683
4684
  results: z.array(z.object({
4684
4685
  url: z.string(),
@@ -4703,7 +4704,7 @@ var parallelSearchToolFactory = createProviderExecutedToolFactory({
4703
4704
  var parallelSearch = (config = {}) => parallelSearchToolFactory(config);
4704
4705
  var perplexitySearchToolFactory = createProviderExecutedToolFactory({
4705
4706
  id: "gateway.perplexity_search",
4706
- inputSchema: lazySchema(() => zodSchema(z.object({
4707
+ inputSchema: lazySchema(() => zodSchema$1(z.object({
4707
4708
  query: z.union([z.string(), z.array(z.string())]).describe("Search query (string) or multiple queries (array of up to 5 strings). Multi-query searches return combined results from all queries."),
4708
4709
  max_results: z.number().optional().describe("Maximum number of search results to return (1-20, default: 10)"),
4709
4710
  max_tokens_per_page: z.number().optional().describe("Maximum number of tokens to extract per search result page (256-2048, default: 2048)"),
@@ -4722,7 +4723,7 @@ var perplexitySearchToolFactory = createProviderExecutedToolFactory({
4722
4723
  "year"
4723
4724
  ]).optional().describe("Filter results by relative time period. Cannot be used with search_after_date or search_before_date.")
4724
4725
  }))),
4725
- outputSchema: lazySchema(() => zodSchema(z.union([z.object({
4726
+ outputSchema: lazySchema(() => zodSchema$1(z.union([z.object({
4726
4727
  results: z.array(z.object({
4727
4728
  title: z.string(),
4728
4729
  url: z.string(),
@@ -46107,6 +46108,650 @@ async function resolveActionCredentials(requirements, options) {
46107
46108
  return parseResolvedCredentials(requirements, await resolveCredentials(requirements, options.consumer, options.contextOverride));
46108
46109
  }
46109
46110
  //#endregion
46110
- export { getSession as A, withSpan as B, addAgentSessionDuration as C, failAgentSession as D, createSession as E, setSessionTitle as F, jsonSchema as G, require_token_util as H, touchSession as I, tool as K, captureConsole as L, recordLlmUsageFromAssistantMessage as M, resolveRunSourceFromTraceContext as N, getAgentByRoute as O, setSessionLiveMessage as P, getTraceContext as R, MESSAGE_EVENT_TYPE as S, clearLiveMessage as T, require_token_error as U, createGateway as V, generateId as W, generateText as _, isCredentialError as a, readUIMessageStream as b, withCredentialAssignments as c, connectMcpStdio as d, defineMcp as f, generateObject as g, convertToModelMessages as h, enrichCredentialError as i, listMessageEvents as j, getProjectScopeId as k, connectMcpDefinition as l, ToolLoopAgent as m, captureCredentialToolErrors as n, resolveActionCredentials as o, isMcp as p, createCredentialResolver as r, resolveMcpTools as s, buildCredentialRunContext as t, connectMcpServer as u, isFileUIPart as v, appendEvent as w, toUIMessageStream as x, output_exports as y, logSystem as z };
46111
+ //#region ../workflow/dist/index.mjs
46112
+ var RunCanceledError = class extends Error {
46113
+ constructor(runId) {
46114
+ super(runId ? `Workflow run ${runId} was canceled` : "Workflow run was canceled");
46115
+ this.name = "RunCanceledError";
46116
+ }
46117
+ };
46118
+ function isRunCanceledError(error) {
46119
+ return error instanceof RunCanceledError;
46120
+ }
46121
+ function executeWorkflowStep(state) {
46122
+ const handle = getWorkflowRunHandle();
46123
+ if (!handle?.workflowRunner) throw new Error(`Workflow "${state.workflow.slug}" can only be called as a step inside a running workflow. Run it standalone with executeWorkflow(...).`);
46124
+ return handle.workflowRunner(state.workflow, state.input, { id: state.id });
46125
+ }
46126
+ function createWorkflowStepInvocation(state) {
46127
+ return {
46128
+ stepId(id) {
46129
+ return createWorkflowStepInvocation({
46130
+ ...state,
46131
+ id
46132
+ });
46133
+ },
46134
+ then(onfulfilled, onrejected) {
46135
+ return executeWorkflowStep(state).then(onfulfilled, onrejected);
46136
+ }
46137
+ };
46138
+ }
46139
+ const zodSchema = z.custom((v) => v instanceof z.ZodType, "must be a Zod schema");
46140
+ /** Runtime validation for an unbranded workflow definition. */
46141
+ const workflowCoreSchema = z.object({
46142
+ slug: z.string().trim().min(1),
46143
+ name: z.string().optional(),
46144
+ description: z.string().optional(),
46145
+ subscription: z.object({ mode: z.enum(["system", "subscribable"]).optional() }).optional(),
46146
+ input: zodSchema,
46147
+ output: zodSchema,
46148
+ run: z.function()
46149
+ });
46150
+ const WORKFLOW = Symbol.for("keystroke.workflow");
46151
+ /**
46152
+ * Validates brand + shape via `workflowCoreSchema` so discovery and guards
46153
+ * reject malformed definitions.
46154
+ */
46155
+ function isWorkflow(value) {
46156
+ if (typeof value !== "object" || value === null) return false;
46157
+ if (!(WORKFLOW in value) || value[WORKFLOW] !== true) return false;
46158
+ return workflowCoreSchema.safeParse(value).success;
46159
+ }
46160
+ function defineWorkflow(def) {
46161
+ const result = workflowCoreSchema.safeParse(def);
46162
+ if (!result.success) throw new Error(`Invalid workflow definition: ${formatIssues(result.error.issues)}`);
46163
+ const body = def.run;
46164
+ const workflow = {
46165
+ ...result.data,
46166
+ [WORKFLOW]: true
46167
+ };
46168
+ workflow.run = ((input, ctx) => {
46169
+ if (ctx !== void 0) return body(input, ctx);
46170
+ return createWorkflowStepInvocation({
46171
+ workflow,
46172
+ input
46173
+ });
46174
+ });
46175
+ return workflow;
46176
+ }
46177
+ function formatIssues(issues) {
46178
+ return issues.map((issue) => {
46179
+ return `${issue.path.length > 0 ? `${issue.path.join(".")}: ` : ""}${issue.message}`;
46180
+ }).join("; ");
46181
+ }
46182
+ function serializeWorkflowError(error) {
46183
+ if (error instanceof Error) return {
46184
+ name: error.name,
46185
+ message: error.message
46186
+ };
46187
+ return { message: String(error) };
46188
+ }
46189
+ /** Rebuild an Error from a recorded error so replay re-raises the same failure. */
46190
+ function deserializeWorkflowError(data) {
46191
+ const serialized = data;
46192
+ const error = new Error(serialized?.message ?? "Workflow step failed");
46193
+ if (serialized?.name) error.name = serialized.name;
46194
+ return error;
46195
+ }
46196
+ const UNIT_MS = {
46197
+ ms: 1,
46198
+ s: 1e3,
46199
+ m: 6e4,
46200
+ h: 36e5,
46201
+ d: 864e5
46202
+ };
46203
+ /** Resolve a sleep duration to an absolute resume time. */
46204
+ function resolveResumeAt(duration, now = /* @__PURE__ */ new Date()) {
46205
+ if (duration instanceof Date) return duration;
46206
+ if (typeof duration === "number") return new Date(now.getTime() + Math.max(0, duration));
46207
+ return new Date(now.getTime() + parseDurationToMs(duration));
46208
+ }
46209
+ function parseDurationToMs(value) {
46210
+ const match = /^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/.exec(value.trim());
46211
+ if (!match) throw new Error(`Invalid sleep duration "${value}". Use a number of ms, a Date, or a string like "5s", "10m", "1h".`);
46212
+ const amount = Number(match[1]);
46213
+ const unit = match[2];
46214
+ return Math.round(amount * UNIT_MS[unit]);
46215
+ }
46216
+ /** Indexes replay events by correlationId for O(1) cache-hit checks during replay. */
46217
+ var EventsConsumer = class {
46218
+ byCorrelationId = /* @__PURE__ */ new Map();
46219
+ constructor(events) {
46220
+ for (const event of events) {
46221
+ if (!event.correlationId) continue;
46222
+ const list = this.byCorrelationId.get(event.correlationId);
46223
+ if (list) list.push(event);
46224
+ else this.byCorrelationId.set(event.correlationId, [event]);
46225
+ }
46226
+ }
46227
+ events(correlationId) {
46228
+ return this.byCorrelationId.get(correlationId) ?? [];
46229
+ }
46230
+ hasEventType(correlationId, type) {
46231
+ return this.events(correlationId).some((event) => event.type === type);
46232
+ }
46233
+ /**
46234
+ * Cache lookup for a step. Returns the recorded output on a `step_completed`,
46235
+ * re-raises the recorded error on a terminal `step_failed` (so a permanently
46236
+ * failed step is not re-executed), and otherwise reports a miss — including
46237
+ * when only `step_retrying` events exist (the step re-runs on the next pass).
46238
+ */
46239
+ getStepResult(correlationId) {
46240
+ const events = this.events(correlationId);
46241
+ const failed = events.find((event) => event.type === "step_failed");
46242
+ if (failed) throw deserializeWorkflowError(failed.data);
46243
+ const completed = events.find((event) => event.type === "step_completed");
46244
+ if (completed) return {
46245
+ completed: true,
46246
+ result: completed.data
46247
+ };
46248
+ return { completed: false };
46249
+ }
46250
+ /** Number of prior `step_retrying` events recorded for a step (= failed attempts so far). */
46251
+ countRetrying(correlationId) {
46252
+ return this.events(correlationId).filter((event) => event.type === "step_retrying").length;
46253
+ }
46254
+ isSleepCompleted(correlationId) {
46255
+ return this.hasEventType(correlationId, "sleep_completed");
46256
+ }
46257
+ /** Returns the persisted resumeAt for a scheduled-but-not-completed sleep, if any. */
46258
+ getSleepResumeAt(correlationId) {
46259
+ const scheduled = this.events(correlationId).find((event) => event.type === "sleep_scheduled");
46260
+ if (!scheduled) return;
46261
+ const data = scheduled.data;
46262
+ return data?.resumeAt ? new Date(data.resumeAt) : void 0;
46263
+ }
46264
+ getHookToken(correlationId) {
46265
+ return (this.events(correlationId).find((event) => event.type === "hook_created")?.data)?.token;
46266
+ }
46267
+ getHookResult(correlationId) {
46268
+ const resumed = this.events(correlationId).find((event) => event.type === "hook_resumed");
46269
+ if (!resumed) return { resolved: false };
46270
+ return {
46271
+ resolved: true,
46272
+ payload: resumed.data?.payload
46273
+ };
46274
+ }
46275
+ };
46276
+ /** A promise that never settles — returned by a suspending primitive so the body parks. */
46277
+ function createPendingPromise() {
46278
+ return new Promise(() => {});
46279
+ }
46280
+ /**
46281
+ * Collects pending items requested within a single tick and resolves once, so
46282
+ * parallel suspensions (e.g. Promise.all of two sleeps) batch into one suspension.
46283
+ */
46284
+ var SuspensionCoordinator = class {
46285
+ items = /* @__PURE__ */ new Map();
46286
+ scheduled = false;
46287
+ resolve;
46288
+ promise;
46289
+ constructor() {
46290
+ this.promise = new Promise((resolve) => {
46291
+ this.resolve = resolve;
46292
+ });
46293
+ }
46294
+ request(item) {
46295
+ this.items.set(item.correlationId, item);
46296
+ if (!this.scheduled) {
46297
+ this.scheduled = true;
46298
+ queueMicrotask(() => {
46299
+ this.resolve([...this.items.values()]);
46300
+ });
46301
+ }
46302
+ }
46303
+ waitForSuspension() {
46304
+ return this.promise;
46305
+ }
46306
+ };
46307
+ function createReplayState(params) {
46308
+ return {
46309
+ runId: params.runId,
46310
+ consumer: params.consumer,
46311
+ coordinator: params.coordinator,
46312
+ eventLog: params.eventLog,
46313
+ newEvents: [],
46314
+ now: params.now ?? /* @__PURE__ */ new Date(),
46315
+ hookBaseUrl: params.hookBaseUrl,
46316
+ sleepCounter: 0,
46317
+ hookCounter: 0,
46318
+ stepOccurrences: /* @__PURE__ */ new Map(),
46319
+ stepCorrelationIds: /* @__PURE__ */ new Set()
46320
+ };
46321
+ }
46322
+ /**
46323
+ * Allocate the correlation id for a step. An explicit `.stepId(x)` maps to
46324
+ * `step:x` (and must be unique within a run); otherwise the key is
46325
+ * `step:<actionKey>#<occurrence>` so that two calls to the same action get
46326
+ * distinct, replay-stable ids and inserting an unrelated call never shifts the
46327
+ * ids of later calls (unlike a single global ordinal).
46328
+ */
46329
+ function nextStepCorrelationId(state, actionKey, explicitId) {
46330
+ if (explicitId !== void 0) {
46331
+ const correlationId = `step:${explicitId}`;
46332
+ if (state.stepCorrelationIds.has(correlationId)) throw new Error(`Duplicate step id "${explicitId}" in workflow run ${state.runId}`);
46333
+ state.stepCorrelationIds.add(correlationId);
46334
+ return correlationId;
46335
+ }
46336
+ const occurrence = state.stepOccurrences.get(actionKey) ?? 0;
46337
+ state.stepOccurrences.set(actionKey, occurrence + 1);
46338
+ const correlationId = `step:${actionKey}#${occurrence}`;
46339
+ state.stepCorrelationIds.add(correlationId);
46340
+ return correlationId;
46341
+ }
46342
+ function createSleep(state) {
46343
+ return function sleep(duration) {
46344
+ const correlationId = `sleep#${state.sleepCounter++}`;
46345
+ if (state.consumer.isSleepCompleted(correlationId)) return Promise.resolve();
46346
+ const scheduledResumeAt = state.consumer.getSleepResumeAt(correlationId);
46347
+ const resumeAt = scheduledResumeAt ?? resolveResumeAt(duration, state.now);
46348
+ if (scheduledResumeAt && resumeAt.getTime() <= state.now.getTime()) {
46349
+ state.newEvents.push({
46350
+ id: `sleep_completed:${state.runId}:${correlationId}`,
46351
+ runId: state.runId,
46352
+ type: "sleep_completed",
46353
+ correlationId
46354
+ });
46355
+ return Promise.resolve();
46356
+ }
46357
+ if (!scheduledResumeAt) state.newEvents.push({
46358
+ id: `sleep_scheduled:${state.runId}:${correlationId}`,
46359
+ runId: state.runId,
46360
+ type: "sleep_scheduled",
46361
+ correlationId,
46362
+ data: { resumeAt: resumeAt.toISOString() }
46363
+ });
46364
+ state.coordinator.request({
46365
+ kind: "sleep",
46366
+ correlationId,
46367
+ resumeAt
46368
+ });
46369
+ return createPendingPromise();
46370
+ };
46371
+ }
46372
+ function createHook(state) {
46373
+ return function hook(options) {
46374
+ const correlationId = `hook#${state.hookCounter++}`;
46375
+ const token = options?.token ?? state.consumer.getHookToken(correlationId) ?? `hook_${crypto.randomUUID()}`;
46376
+ const resumeUrl = state.hookBaseUrl ? `${state.hookBaseUrl}/hooks/${token}/resume` : `/hooks/${token}/resume`;
46377
+ const schema = options?.schema ? z.toJSONSchema(options.schema) : void 0;
46378
+ return {
46379
+ token,
46380
+ resumeUrl,
46381
+ then(onFulfilled, onRejected) {
46382
+ const result = state.consumer.getHookResult(correlationId);
46383
+ if (result.resolved) {
46384
+ const payload = options?.schema ? options.schema.parse(result.payload) : result.payload;
46385
+ return Promise.resolve(payload).then(onFulfilled, onRejected);
46386
+ }
46387
+ if (!state.consumer.hasEventType(correlationId, "hook_created")) state.newEvents.push({
46388
+ id: `hook_created:${state.runId}:${correlationId}`,
46389
+ runId: state.runId,
46390
+ type: "hook_created",
46391
+ correlationId,
46392
+ data: schema ? {
46393
+ token,
46394
+ schema
46395
+ } : { token }
46396
+ });
46397
+ state.coordinator.request({
46398
+ kind: "hook",
46399
+ correlationId,
46400
+ token,
46401
+ ...schema ? { schema } : {}
46402
+ });
46403
+ return createPendingPromise().then(onFulfilled, onRejected);
46404
+ }
46405
+ };
46406
+ };
46407
+ }
46408
+ /**
46409
+ * Shared durable-step shell: resolve a stable `correlation_id`, short-circuit
46410
+ * from the event log on a cache hit, otherwise execute and append
46411
+ * `step_completed` immediately (per-step crash durability). A thrown step
46412
+ * appends `step_retrying` (non-fatal, re-run on the next attempt) and
46413
+ * rethrows; the terminal `step_failed` is written by the job handler once the
46414
+ * queue exhausts retries.
46415
+ */
46416
+ async function runDurableStep(state, options) {
46417
+ const { runId, consumer, eventLog } = state;
46418
+ getRunSignal().throwIfAborted();
46419
+ const correlationId = nextStepCorrelationId(state, options.key, options.id);
46420
+ const cached = consumer.getStepResult(correlationId);
46421
+ const metadata = {
46422
+ runId,
46423
+ [options.metadataKey]: options.key,
46424
+ correlationId
46425
+ };
46426
+ if (cached.completed) {
46427
+ await withSpan({
46428
+ kind: options.kind,
46429
+ name: options.key,
46430
+ refId: `${runId}:${correlationId}`,
46431
+ metadata: {
46432
+ ...metadata,
46433
+ replayed: true
46434
+ }
46435
+ }, async () => {
46436
+ await logSystem("info", options.replayMessage, metadata);
46437
+ });
46438
+ return options.parseCached ? options.parseCached(cached.result) : cached.result;
46439
+ }
46440
+ return withSpan({
46441
+ kind: options.kind,
46442
+ name: options.key,
46443
+ refId: `${runId}:${correlationId}`,
46444
+ metadata
46445
+ }, async () => captureConsole(async () => {
46446
+ try {
46447
+ const result = await options.execute(correlationId);
46448
+ await eventLog.append({
46449
+ id: `step_completed:${runId}:${correlationId}`,
46450
+ runId,
46451
+ type: "step_completed",
46452
+ correlationId,
46453
+ data: result
46454
+ });
46455
+ return result;
46456
+ } catch (error) {
46457
+ const attempt = consumer.countRetrying(correlationId);
46458
+ await eventLog.append({
46459
+ id: `step_retrying:${runId}:${correlationId}:${attempt}`,
46460
+ runId,
46461
+ type: "step_retrying",
46462
+ correlationId,
46463
+ data: serializeWorkflowError(error)
46464
+ });
46465
+ state.failedCorrelationId = correlationId;
46466
+ throw error;
46467
+ }
46468
+ }));
46469
+ }
46470
+ function withCredentialScopeOverride(requirements, scope) {
46471
+ if (!requirements || !scope) return requirements;
46472
+ return normalizeCredentialList(requirements).map((requirement) => ({
46473
+ ...requirement,
46474
+ scope
46475
+ }));
46476
+ }
46477
+ /** Builds the per-run action runner; durability lives in {@link runDurableStep}. */
46478
+ function createActionRunner(state, options = {}) {
46479
+ return (action, input, runOptions) => runDurableStep(state, {
46480
+ kind: "action",
46481
+ key: action.slug,
46482
+ id: runOptions?.id,
46483
+ metadataKey: "actionKey",
46484
+ replayMessage: "action replayed from checkpoint",
46485
+ parseCached: (cached) => action.output.parse(cached),
46486
+ execute: async (correlationId) => {
46487
+ const requirements = withCredentialScopeOverride(getActionCredentialRequirements(action), runOptions?.credentialScope);
46488
+ const credentials = requirements?.length ? await resolveActionCredentials(requirements, {
46489
+ resolveCredentials: options.resolveCredentials,
46490
+ context: options.credentialContext,
46491
+ oauthAdapter: options.oauthAdapter,
46492
+ consumer: {
46493
+ kind: "action",
46494
+ name: action.slug,
46495
+ id: correlationId
46496
+ }
46497
+ }) : {};
46498
+ return runWithMcpCredentialContext({
46499
+ ...options.mcpCredentialContext,
46500
+ consumerId: correlationId
46501
+ }, () => executeAction(action, input, credentials));
46502
+ }
46503
+ });
46504
+ }
46505
+ /**
46506
+ * Builds the per-run agent runner: each `agent.prompt()` in a workflow body
46507
+ * becomes a durable step keyed `step:<agentKey>#<occurrence>` (same scheme as
46508
+ * actions). The actual prompt execution is delegated to `runAgent`, supplied
46509
+ * by the host (server) via `executeWorkflow({ runAgent })`.
46510
+ */
46511
+ function createAgentStepRunner(state, runAgent) {
46512
+ return (agent, input, options) => {
46513
+ const slug = agent.slug;
46514
+ return runDurableStep(state, {
46515
+ kind: "agent_session",
46516
+ key: slug,
46517
+ id: options?.id,
46518
+ metadataKey: "agentKey",
46519
+ replayMessage: "agent step replayed from checkpoint",
46520
+ execute: (_correlationId) => runAgent(agent, input, options?.runPrompt)
46521
+ });
46522
+ };
46523
+ }
46524
+ /**
46525
+ * Builds the per-run LLM runner: each `promptLlm()` in a workflow body becomes a
46526
+ * durable step keyed `step:promptLlm#<occurrence>`. The actual LLM call is
46527
+ * delegated to `runLlm`, supplied by the host (server) via `executeWorkflow({ runLlm })`.
46528
+ */
46529
+ function createLlmStepRunner(state, runLlm) {
46530
+ return (opts) => runDurableStep(state, {
46531
+ kind: "llm",
46532
+ key: "promptLlm",
46533
+ id: opts.stepId,
46534
+ metadataKey: "llmKey",
46535
+ replayMessage: "llm step replayed from checkpoint",
46536
+ parseCached: (cached) => opts.outputSchema ? opts.outputSchema.parse(cached) : cached,
46537
+ execute: (_correlationId) => runLlm(opts)
46538
+ });
46539
+ }
46540
+ /**
46541
+ * Builds the per-run sub-workflow runner: each `workflow.run(input)` inside a
46542
+ * workflow body becomes a durable step keyed `step:<slug>#<occurrence>`. The
46543
+ * sub-workflow's body runs inline in the same replay state (its action/agent/
46544
+ * LLM steps and `ctx.sleep`/`ctx.hook` stay durable), and its validated output
46545
+ * is checkpointed so a replay skips the whole sub-workflow once it completes.
46546
+ */
46547
+ function createWorkflowStepRunner(state, ctx) {
46548
+ return (workflowUnknown, input, options) => {
46549
+ const workflow = workflowUnknown;
46550
+ const parsedInput = workflow.input.parse(input);
46551
+ return runDurableStep(state, {
46552
+ kind: "workflow_run",
46553
+ key: workflow.slug,
46554
+ id: options?.id,
46555
+ metadataKey: "workflowKey",
46556
+ replayMessage: "workflow step replayed from checkpoint",
46557
+ parseCached: (cached) => workflow.output.parse(cached),
46558
+ execute: async () => {
46559
+ const output = await workflow.run(parsedInput, ctx);
46560
+ return workflow.output.parse(output);
46561
+ }
46562
+ });
46563
+ };
46564
+ }
46565
+ const storage = new AsyncLocalStorage();
46566
+ registerWorkflowRunGetter(() => {
46567
+ const store = storage.getStore();
46568
+ if (!store) return;
46569
+ return {
46570
+ actionRunner: store.actionRunner,
46571
+ agentRunner: store.agentRunner,
46572
+ llmRunner: store.llmRunner,
46573
+ workflowRunner: store.workflowRunner
46574
+ };
46575
+ });
46576
+ function runWithWorkflowContext(store, fn) {
46577
+ return storage.run(store, fn);
46578
+ }
46579
+ /** In-memory durable log for inline execution and tests. */
46580
+ var MemoryEventLog = class {
46581
+ events = [];
46582
+ ids = /* @__PURE__ */ new Set();
46583
+ async append(event) {
46584
+ const id = event.id ?? crypto.randomUUID();
46585
+ if (this.ids.has(id)) return false;
46586
+ this.ids.add(id);
46587
+ this.events.push({
46588
+ id,
46589
+ runId: event.runId,
46590
+ seq: this.events.length,
46591
+ type: event.type,
46592
+ correlationId: event.correlationId ?? null,
46593
+ data: event.data ?? null
46594
+ });
46595
+ return true;
46596
+ }
46597
+ async listReplay(runId) {
46598
+ return this.events.filter((event) => event.runId === runId).map((event) => ({ ...event }));
46599
+ }
46600
+ };
46601
+ /**
46602
+ * The single way to run a workflow: replay its event log from the top, execute
46603
+ * un-cached primitives, and either complete/fail or suspend at the first
46604
+ * un-satisfied sleep/hook. New events (sleep_scheduled/sleep_completed/
46605
+ * hook_created/run_completed/run_failed) are flushed before returning.
46606
+ *
46607
+ * Durability comes entirely from the log — a suspended run resumes by calling
46608
+ * this again with the same `runId` and event log once the sleep is due or the
46609
+ * hook is resumed.
46610
+ */
46611
+ async function executeWorkflow(workflow, input, options = {}) {
46612
+ const runId = options.runId ?? crypto.randomUUID();
46613
+ const eventLog = options.eventLog ?? new MemoryEventLog();
46614
+ const signal = getRunSignal();
46615
+ const consumer = new EventsConsumer(await eventLog.listReplay(runId));
46616
+ const coordinator = new SuspensionCoordinator();
46617
+ const state = createReplayState({
46618
+ runId,
46619
+ consumer,
46620
+ coordinator,
46621
+ eventLog,
46622
+ hookBaseUrl: options.hookBaseUrl,
46623
+ now: options.now
46624
+ });
46625
+ const actionRunner = createActionRunner(state, {
46626
+ resolveCredentials: options.resolveCredentials,
46627
+ credentialContext: options.credentialContext,
46628
+ oauthAdapter: options.oauthAdapter,
46629
+ mcpCredentialContext: { assignmentTarget: {
46630
+ type: "workflow",
46631
+ key: workflow.slug
46632
+ } }
46633
+ });
46634
+ const ctx = {
46635
+ runId,
46636
+ sleep: createSleep(state),
46637
+ hook: createHook(state),
46638
+ ...options.context
46639
+ };
46640
+ const agentRunner = options.runAgent ? createAgentStepRunner(state, options.runAgent) : void 0;
46641
+ const llmRunner = options.runLlm ? createLlmStepRunner(state, options.runLlm) : void 0;
46642
+ const workflowRunner = createWorkflowStepRunner(state, ctx);
46643
+ const validatedInput = workflow.input.parse(input);
46644
+ const bodyPromise = runWithWorkflowContext({
46645
+ actionRunner,
46646
+ agentRunner,
46647
+ llmRunner,
46648
+ workflowRunner,
46649
+ runId
46650
+ }, () => captureConsole(async () => workflow.run(validatedInput, ctx)));
46651
+ let onAbort;
46652
+ const waitForAbort = signal.aborted ? Promise.resolve({ type: "canceled" }) : new Promise((resolve) => {
46653
+ onAbort = () => resolve({ type: "canceled" });
46654
+ signal.addEventListener("abort", onAbort, { once: true });
46655
+ });
46656
+ const outcome = await Promise.race([
46657
+ bodyPromise.then((output) => ({
46658
+ type: "done",
46659
+ output
46660
+ }), (error) => ({
46661
+ type: "error",
46662
+ error
46663
+ })),
46664
+ coordinator.waitForSuspension().then((items) => ({
46665
+ type: "suspended",
46666
+ items
46667
+ })),
46668
+ waitForAbort
46669
+ ]);
46670
+ if (onAbort) signal.removeEventListener("abort", onAbort);
46671
+ let result;
46672
+ if (outcome.type === "suspended") {
46673
+ bodyPromise.catch(() => {});
46674
+ result = {
46675
+ status: "suspended",
46676
+ items: outcome.items
46677
+ };
46678
+ } else if (outcome.type === "done") {
46679
+ const output = workflow.output.parse(outcome.output);
46680
+ state.newEvents.push({
46681
+ id: `run_completed:${runId}`,
46682
+ runId,
46683
+ type: "run_completed",
46684
+ data: { output }
46685
+ });
46686
+ result = {
46687
+ status: "completed",
46688
+ output
46689
+ };
46690
+ } else if (outcome.type === "canceled" || isRunCanceledError(outcome.error)) {
46691
+ bodyPromise.catch(() => {});
46692
+ state.newEvents.push({
46693
+ id: `run_canceled:${runId}`,
46694
+ runId,
46695
+ type: "run_canceled"
46696
+ });
46697
+ result = { status: "canceled" };
46698
+ } else result = {
46699
+ status: "failed",
46700
+ error: outcome.error,
46701
+ failedCorrelationId: state.failedCorrelationId
46702
+ };
46703
+ for (const event of state.newEvents) await eventLog.append(event);
46704
+ return result;
46705
+ }
46706
+ function promptLlm(prompt, opts) {
46707
+ const handle = getWorkflowRunHandle();
46708
+ if (!handle?.llmRunner) throw new Error("promptLlm must run inside a workflow with an injected llm executor (executeWorkflow({ runLlm })).");
46709
+ return handle.llmRunner({
46710
+ prompt,
46711
+ ...opts
46712
+ });
46713
+ }
46714
+ let executor;
46715
+ function registerWorkflowToolExecutor(fn) {
46716
+ if (executor) throw new Error("workflow tool executor already registered");
46717
+ executor = fn;
46718
+ }
46719
+ function getWorkflowToolExecutor() {
46720
+ if (!executor) throw new Error("workflow tool executor not registered");
46721
+ return executor;
46722
+ }
46723
+ function assertWorkflowToolInput(workflow) {
46724
+ if (!("shape" in workflow.input) || typeof workflow.input.shape !== "object") throw new Error(`Workflow "${workflow.slug}" cannot be used as an agent tool: input schema must be a Zod object.`);
46725
+ }
46726
+ function resolveWorkflowTool(workflow) {
46727
+ assertWorkflowToolInput(workflow);
46728
+ const key = workflow.slug;
46729
+ return defineTool({
46730
+ name: key,
46731
+ label: key,
46732
+ description: workflow.description ?? key,
46733
+ parameters: workflow.input,
46734
+ async execute(toolCallId, params) {
46735
+ const output = await withSpan({
46736
+ kind: "tool_call",
46737
+ name: key,
46738
+ refId: toolCallId,
46739
+ metadata: {
46740
+ tool: key,
46741
+ type: "workflow"
46742
+ }
46743
+ }, () => getWorkflowToolExecutor()(workflow, params, { workflowKey: key }));
46744
+ return {
46745
+ content: [{
46746
+ type: "text",
46747
+ text: JSON.stringify(output)
46748
+ }],
46749
+ details: output
46750
+ };
46751
+ }
46752
+ });
46753
+ }
46754
+ //#endregion
46755
+ export { require_token_error as $, output_exports as A, getProjectScopeId as B, defineMcp as C, generateObject as D, convertToModelMessages as E, appendEvent as F, setSessionLiveMessage as G, listMessageEvents as H, clearLiveMessage as I, captureConsole as J, setSessionTitle as K, createSession as L, toUIMessageStream as M, MESSAGE_EVENT_TYPE as N, generateText as O, addAgentSessionDuration as P, require_token_util as Q, failAgentSession as R, connectMcpStdio as S, ToolLoopAgent as T, recordLlmUsageFromAssistantMessage as U, getSession as V, resolveRunSourceFromTraceContext as W, withSpan as X, getTraceContext as Y, createGateway as Z, resolveActionCredentials as _, executeWorkflow as a, connectMcpDefinition as b, promptLlm as c, serializeWorkflowError as d, generateId as et, buildCredentialRunContext as f, isCredentialError as g, enrichCredentialError as h, deserializeWorkflowError as i, readUIMessageStream as j, isFileUIPart as k, registerWorkflowToolExecutor as l, createCredentialResolver as m, RunCanceledError as n, tool as nt, isRunCanceledError as o, captureCredentialToolErrors as p, touchSession as q, defineWorkflow as r, isWorkflow as s, MemoryEventLog as t, jsonSchema as tt, resolveWorkflowTool as u, resolveMcpTools as v, isMcp as w, connectMcpServer as x, withCredentialAssignments as y, getAgentByRoute as z };
46111
46756
 
46112
- //# sourceMappingURL=dist-KpQEao0i.mjs.map
46757
+ //# sourceMappingURL=dist-B1Pjv-cM.mjs.map