experimental-ash 0.18.1 → 0.18.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 (51) hide show
  1. package/CHANGELOG.md +18 -2
  2. package/dist/docs/public/channels/README.md +75 -9
  3. package/dist/docs/public/schedules.md +13 -4
  4. package/dist/src/channel/adapter-context.d.ts +4 -0
  5. package/dist/src/channel/adapter-context.js +6 -0
  6. package/dist/src/channel/adapter.d.ts +10 -10
  7. package/dist/src/channel/cross-channel-receive.d.ts +1 -1
  8. package/dist/src/channel/cross-channel-receive.js +40 -0
  9. package/dist/src/channel/routes.d.ts +7 -0
  10. package/dist/src/channel/send.js +1 -1
  11. package/dist/src/channel/session.d.ts +47 -1
  12. package/dist/src/channel/session.js +46 -0
  13. package/dist/src/channel/types.d.ts +6 -5
  14. package/dist/src/chunks/{dev-authored-source-watcher-DtLxnrXI.js → dev-authored-source-watcher-j7YWh2Gx.js} +1 -1
  15. package/dist/src/chunks/{host-Dor4C8jo.js → host-DkTSR6YJ.js} +2 -2
  16. package/dist/src/chunks/{paths-AVYgVLR3.js → paths-Dwv0Eash.js} +21 -21
  17. package/dist/src/chunks/{prewarm-DsMkM8wg.js → prewarm-CQYfka30.js} +1 -1
  18. package/dist/src/cli/commands/info.js +1 -1
  19. package/dist/src/cli/run.js +1 -1
  20. package/dist/src/evals/cli/eval.js +1 -1
  21. package/dist/src/execution/sandbox/bindings/vercel.d.ts +2 -2
  22. package/dist/src/execution/sandbox/bindings/vercel.js +1 -34
  23. package/dist/src/execution/workflow-entry.js +35 -31
  24. package/dist/src/execution/workflow-steps.d.ts +16 -0
  25. package/dist/src/execution/workflow-steps.js +32 -4
  26. package/dist/src/harness/attachment-staging.js +2 -1
  27. package/dist/src/internal/application/package.js +1 -1
  28. package/dist/src/public/channels/slack/api.d.ts +13 -8
  29. package/dist/src/public/channels/slack/api.js +31 -17
  30. package/dist/src/public/channels/slack/index.d.ts +2 -2
  31. package/dist/src/public/channels/slack/index.js +1 -0
  32. package/dist/src/public/channels/slack/interactions.js +3 -3
  33. package/dist/src/public/channels/slack/slackChannel.d.ts +5 -3
  34. package/dist/src/public/channels/slack/slackChannel.js +26 -15
  35. package/dist/src/public/channels/twilio/api.d.ts +9 -0
  36. package/dist/src/public/channels/twilio/api.js +11 -0
  37. package/dist/src/public/channels/twilio/index.d.ts +1 -1
  38. package/dist/src/public/channels/twilio/index.js +1 -1
  39. package/dist/src/public/channels/twilio/twilioChannel.d.ts +2 -0
  40. package/dist/src/public/channels/twilio/twilioChannel.js +8 -11
  41. package/dist/src/public/definitions/defineChannel.d.ts +9 -1
  42. package/dist/src/public/definitions/defineChannel.js +7 -11
  43. package/dist/src/public/definitions/sandbox.d.ts +2 -3
  44. package/dist/src/public/sandbox/backends/vercel.d.ts +4 -4
  45. package/dist/src/public/sandbox/backends/vercel.js +2 -2
  46. package/dist/src/public/sandbox/index.d.ts +1 -1
  47. package/dist/src/public/sandbox/vercel-sandbox.d.ts +3 -28
  48. package/dist/src/runtime/types.d.ts +1 -2
  49. package/dist/src/shared/sandbox-backend.d.ts +4 -4
  50. package/dist/src/shared/sandbox-definition.d.ts +6 -6
  51. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import { createLogger } from "#internal/logging.js";
2
- import { buildSlackBinding, encodeSlackContinuationToken, } from "#public/channels/slack/api.js";
2
+ import { buildSlackBinding, slackContinuationToken, } from "#public/channels/slack/api.js";
3
3
  import { buildSlackTurnMessage, collectInboundFileParts, createSlackFetchFile, } from "#public/channels/slack/attachments.js";
4
4
  import { defaultEvents, defaultInputRequestedHandler, defaultOnAppMention, defaultOnDirectMessage, } from "#public/channels/slack/defaults.js";
5
5
  import { parseAppMentionEvent, parseDirectMessageEvent, prependSlackContext, } from "#public/channels/slack/inbound.js";
@@ -8,14 +8,26 @@ import { mergeUploadPolicy, } from "#public/channels/upload-policy.js";
8
8
  import { verifySlackRequest } from "#public/channels/slack/verify.js";
9
9
  import { defineChannel, POST, } from "#public/definitions/defineChannel.js";
10
10
  const log = createLogger("slack.channel");
11
- function rebuildSlackContext(state, credentials) {
11
+ function rebuildSlackContext(state, session, credentials) {
12
12
  const { thread, slack } = buildSlackBinding({
13
13
  botToken: credentials?.botToken,
14
14
  channelId: state.channelId ?? "",
15
15
  threadTs: state.threadTs ?? "",
16
16
  teamId: state.teamId ?? undefined,
17
+ // First `ctx.thread.post(...)` in a session that started without a
18
+ // thread (programmatic start, schedule firing, etc.) becomes the
19
+ // thread root. We update durable adapter state so subsequent
20
+ // posts thread under it, and re-key the parked session so a
21
+ // follow-up `@mention` reply in the same thread resumes the same
22
+ // workflow.
23
+ onAnchor(ts) {
24
+ state.threadTs = ts;
25
+ if (state.channelId) {
26
+ session.setContinuationToken(slackContinuationToken(state.channelId, ts));
27
+ }
28
+ },
17
29
  });
18
- return { thread, slack, state };
30
+ return { thread, slack, session, state };
19
31
  }
20
32
  /**
21
33
  * Slack channel factory. Wires up the Slack webhook route, mention
@@ -48,8 +60,8 @@ export function slackChannel(config = {}) {
48
60
  pendingAuthMessageTs: {},
49
61
  },
50
62
  fetchFile: slackFetchFile,
51
- context(state) {
52
- return rebuildSlackContext(state, config.credentials);
63
+ context(state, session) {
64
+ return rebuildSlackContext(state, session, config.credentials);
53
65
  },
54
66
  routes: [
55
67
  POST(config.route ?? "/ash/v1/slack", async (req, { send, waitUntil }) => {
@@ -78,12 +90,12 @@ export function slackChannel(config = {}) {
78
90
  throw new Error("slackChannel().receive requires args.channelId.");
79
91
  }
80
92
  const requestedThreadTs = typeof receiveArgs.threadTs === "string" ? receiveArgs.threadTs : "";
81
- const initialPost = receiveArgs.initialPost;
82
- if (initialPost && requestedThreadTs.length > 0) {
83
- throw new Error("slackChannel().receive: `threadTs` and `initialPost` are mutually exclusive.");
93
+ const initialMessage = receiveArgs.initialMessage;
94
+ if (initialMessage && requestedThreadTs.length > 0) {
95
+ throw new Error("slackChannel().receive: `threadTs` and `initialMessage` are mutually exclusive.");
84
96
  }
85
97
  let threadTs = requestedThreadTs;
86
- if (initialPost) {
98
+ if (initialMessage) {
87
99
  const { thread } = buildSlackBinding({
88
100
  botToken: config.credentials?.botToken,
89
101
  channelId,
@@ -91,17 +103,17 @@ export function slackChannel(config = {}) {
91
103
  teamId: undefined,
92
104
  });
93
105
  const postInput = {
94
- card: initialPost.card,
106
+ card: initialMessage.card,
95
107
  };
96
- if (initialPost.fallbackText !== undefined) {
97
- postInput.fallbackText = initialPost.fallbackText;
108
+ if (initialMessage.fallbackText !== undefined) {
109
+ postInput.fallbackText = initialMessage.fallbackText;
98
110
  }
99
111
  const posted = await thread.post(postInput);
100
112
  threadTs = posted.id;
101
113
  }
102
114
  return send(input.message, {
103
115
  auth: input.auth,
104
- continuationToken: encodeSlackContinuationToken(channelId, threadTs),
116
+ continuationToken: slackContinuationToken(channelId, threadTs),
105
117
  state: {
106
118
  channelId,
107
119
  threadTs: threadTs || null,
@@ -206,7 +218,6 @@ async function dispatchInboundMessage(input) {
206
218
  }
207
219
  if (result === null || result === undefined)
208
220
  return;
209
- const continuationToken = encodeSlackContinuationToken(message.channelId, message.threadTs);
210
221
  const fileParts = await collectInboundFileParts({
211
222
  mention: message,
212
223
  thread,
@@ -227,7 +238,7 @@ async function dispatchInboundMessage(input) {
227
238
  try {
228
239
  await input.send(turnMessage, {
229
240
  auth: result.auth,
230
- continuationToken,
241
+ continuationToken: slackContinuationToken(message.channelId, message.threadTs),
231
242
  state: {
232
243
  channelId: message.channelId,
233
244
  threadTs: message.threadTs,
@@ -6,6 +6,15 @@
6
6
  * required or exposed through Ash public APIs.
7
7
  */
8
8
  import { type TwilioAuthToken } from "#public/channels/twilio/verify.js";
9
+ /**
10
+ * Builds the Twilio channel-local continuation token
11
+ * (`<from>:<to>`). Route `send()` namespaces this with the channel
12
+ * name before handing it to the runtime (`twilio:<from>:<to>`), so
13
+ * Twilio routes should pass the raw channel-local form returned
14
+ * here. `to` may be empty for proactive sessions that don't yet know
15
+ * the Twilio sender number.
16
+ */
17
+ export declare function twilioContinuationToken(from: string, to: string | undefined): string;
9
18
  /** Twilio Account SID, materialized directly or from an async secret provider. */
10
19
  export type TwilioAccountSid = string | (() => string | Promise<string>);
11
20
  /** Fetch implementation override used by tests or non-standard runtimes. */
@@ -6,6 +6,17 @@
6
6
  * required or exposed through Ash public APIs.
7
7
  */
8
8
  import { resolveTwilioAuthToken } from "#public/channels/twilio/verify.js";
9
+ /**
10
+ * Builds the Twilio channel-local continuation token
11
+ * (`<from>:<to>`). Route `send()` namespaces this with the channel
12
+ * name before handing it to the runtime (`twilio:<from>:<to>`), so
13
+ * Twilio routes should pass the raw channel-local form returned
14
+ * here. `to` may be empty for proactive sessions that don't yet know
15
+ * the Twilio sender number.
16
+ */
17
+ export function twilioContinuationToken(from, to) {
18
+ return `${from}:${to ?? ""}`;
19
+ }
9
20
  /** Resolves a Twilio Account SID, falling back to `TWILIO_ACCOUNT_SID`. */
10
21
  export async function resolveTwilioAccountSid(accountSid) {
11
22
  const source = accountSid ?? process.env.TWILIO_ACCOUNT_SID;
@@ -1,5 +1,5 @@
1
1
  export { twilioChannel, type TwilioAllowFrom, type TwilioChannel, type TwilioChannelConfig, type TwilioChannelCredentials, type TwilioChannelEvents, type TwilioChannelState, type TwilioContext, type TwilioEventContext, type TwilioHandle, type TwilioInboundResult, type TwilioInboundResultOrPromise, type TwilioMessagingConfig, type TwilioReceiveArgs, type TwilioSendMessageOptions, type TwilioVoiceConfig, type TwilioVoiceResult, type TwilioVoiceResultOrPromise, } from "#public/channels/twilio/twilioChannel.js";
2
- export { callTwilioApi, resolveTwilioAccountSid, sendTwilioMessage, updateTwilioCall, type TwilioAccountSid, type TwilioApiOptions, type TwilioApiResponse, type TwilioCredentials, type TwilioFetch, type TwilioSendMessageInput, type TwilioUpdateCallInput, } from "#public/channels/twilio/api.js";
2
+ export { callTwilioApi, resolveTwilioAccountSid, sendTwilioMessage, twilioContinuationToken, updateTwilioCall, type TwilioAccountSid, type TwilioApiOptions, type TwilioApiResponse, type TwilioCredentials, type TwilioFetch, type TwilioSendMessageInput, type TwilioUpdateCallInput, } from "#public/channels/twilio/api.js";
3
3
  export type { TwilioInboundContext, TwilioTextMessage, TwilioVoiceCall, TwilioVoiceTranscription, } from "#public/channels/twilio/inbound.js";
4
4
  export { emptyTwilioResponse, escapeXml, gatherSpeechTwilioResponse, sayTwilioResponse, twimlResponse, type TwilioGatherTwimlOptions, } from "#public/channels/twilio/twiml.js";
5
5
  export { buildTwilioSignatureBase, resolveTwilioAuthToken, signTwilioRequest, verifyTwilioRequest, type TwilioAuthToken, type TwilioVerifiedRequest, type TwilioVerifyOptions, type TwilioWebhookUrl, } from "#public/channels/twilio/verify.js";
@@ -1,4 +1,4 @@
1
1
  export { twilioChannel, } from "#public/channels/twilio/twilioChannel.js";
2
- export { callTwilioApi, resolveTwilioAccountSid, sendTwilioMessage, updateTwilioCall, } from "#public/channels/twilio/api.js";
2
+ export { callTwilioApi, resolveTwilioAccountSid, sendTwilioMessage, twilioContinuationToken, updateTwilioCall, } from "#public/channels/twilio/api.js";
3
3
  export { emptyTwilioResponse, escapeXml, gatherSpeechTwilioResponse, sayTwilioResponse, twimlResponse, } from "#public/channels/twilio/twiml.js";
4
4
  export { buildTwilioSignatureBase, resolveTwilioAuthToken, signTwilioRequest, verifyTwilioRequest, } from "#public/channels/twilio/verify.js";
@@ -1,4 +1,5 @@
1
1
  import type { TypedReceiveRoute } from "#channel/receive-args.js";
2
+ import type { SessionHandle } from "#channel/session.js";
2
3
  import type { SessionAuthContext } from "#channel/types.js";
3
4
  import type { HandleMessageStreamEvent } from "#protocol/message.js";
4
5
  import { type TwilioApiOptions, type TwilioApiResponse, type TwilioCredentials } from "#public/channels/twilio/api.js";
@@ -16,6 +17,7 @@ export interface TwilioContext {
16
17
  }
17
18
  /** Event-handler Twilio context, including mutable per-phone channel state. */
18
19
  export interface TwilioEventContext extends TwilioContext {
20
+ readonly session: SessionHandle;
19
21
  state: TwilioChannelState;
20
22
  }
21
23
  /** JSON-serializable state for the phone-number conversation. */
@@ -1,5 +1,5 @@
1
1
  import { createLogger } from "#internal/logging.js";
2
- import { callTwilioApi, sendTwilioMessage, updateTwilioCall, } from "#public/channels/twilio/api.js";
2
+ import { callTwilioApi, sendTwilioMessage, twilioContinuationToken, updateTwilioCall, } from "#public/channels/twilio/api.js";
3
3
  import { defaultEvents, defaultOnText, defaultOnVoice, defaultOnVoiceTranscription, } from "#public/channels/twilio/defaults.js";
4
4
  import { parseTwilioTextMessage, parseTwilioVoiceCall, parseTwilioVoiceTranscription, prependTwilioContext, } from "#public/channels/twilio/inbound.js";
5
5
  import { emptyTwilioResponse, gatherSpeechTwilioResponse, sayTwilioResponse, } from "#public/channels/twilio/twiml.js";
@@ -22,8 +22,8 @@ export function twilioChannel(config) {
22
22
  lastCallSid: null,
23
23
  lastMessageSid: null,
24
24
  },
25
- context(state) {
26
- return rebuildTwilioContext(state, config);
25
+ context(state, session) {
26
+ return rebuildTwilioContext(state, session, config);
27
27
  },
28
28
  routes: [
29
29
  POST(routes.messages, async (req, { send, waitUntil }) => {
@@ -96,10 +96,9 @@ export function twilioChannel(config) {
96
96
  throw new Error("twilioChannel().receive requires args.phoneNumber.");
97
97
  }
98
98
  const from = readString(input.args.from) ?? config.messaging?.from ?? null;
99
- const continuationToken = encodeTwilioContinuationToken(phoneNumber, from);
100
99
  return send(input.message, {
101
100
  auth: input.auth,
102
- continuationToken,
101
+ continuationToken: twilioContinuationToken(phoneNumber, from ?? undefined),
103
102
  state: {
104
103
  from: phoneNumber,
105
104
  lastCallSid: null,
@@ -111,8 +110,9 @@ export function twilioChannel(config) {
111
110
  events: mergedEvents,
112
111
  });
113
112
  }
114
- function rebuildTwilioContext(state, config) {
113
+ function rebuildTwilioContext(state, session, config) {
115
114
  return {
115
+ session,
116
116
  state,
117
117
  twilio: buildTwilioHandle({
118
118
  callSid: state.lastCallSid ?? undefined,
@@ -218,7 +218,7 @@ async function dispatchText(input) {
218
218
  try {
219
219
  await input.send(turnMessage, {
220
220
  auth: result.auth,
221
- continuationToken: encodeTwilioContinuationToken(message.from, message.to),
221
+ continuationToken: twilioContinuationToken(message.from, message.to),
222
222
  state: {
223
223
  from: message.from,
224
224
  lastCallSid: null,
@@ -278,7 +278,7 @@ async function dispatchVoiceTranscription(input) {
278
278
  try {
279
279
  await input.send(turnMessage, {
280
280
  auth: result.auth,
281
- continuationToken: encodeTwilioContinuationToken(transcription.from, transcription.to),
281
+ continuationToken: twilioContinuationToken(transcription.from, transcription.to),
282
282
  state: {
283
283
  from: transcription.from,
284
284
  lastCallSid: transcription.callSid ?? null,
@@ -297,9 +297,6 @@ async function isAllowed(from, allowFrom) {
297
297
  return true;
298
298
  return typeof resolved === "string" ? resolved === from : resolved.includes(from);
299
299
  }
300
- function encodeTwilioContinuationToken(from, to) {
301
- return `${from}:${to ?? ""}`;
302
- }
303
300
  async function buildActionUrl(request, config, route) {
304
301
  const base = typeof config.publicBaseUrl === "function"
305
302
  ? await config.publicBaseUrl(request)
@@ -33,7 +33,15 @@ export interface ChannelEvents<TCtx = void> {
33
33
  }
34
34
  export interface ChannelConfig<TState = undefined, TCtx = void> {
35
35
  readonly state?: TState;
36
- context?(state: NonNullable<TState>): TCtx;
36
+ /**
37
+ * Builds the per-step channel context handed to `events` and
38
+ * `deliver`. Receives the live {@link SessionHandle} so factories
39
+ * that need to wire late-bound callbacks (e.g. Slack's auto-anchor
40
+ * `onAnchor` calling `session.setContinuationToken(...)`) can close
41
+ * over it. State mutations made inside the returned context flow
42
+ * back through `adapter.state` automatically.
43
+ */
44
+ context?(state: NonNullable<TState>, session: SessionHandle): TCtx;
37
45
  readonly routes: readonly RouteDefinition<TState>[];
38
46
  receive?(input: {
39
47
  readonly message: string;
@@ -48,26 +48,21 @@ function buildAdapter(config) {
48
48
  if (!hasBehavior && !hasEventHandlers && !hasFetchFile) {
49
49
  return { kind: config.kindHint ?? HTTP_ADAPTER_KIND };
50
50
  }
51
- return {
51
+ const adapter = {
52
52
  kind: config.kindHint ?? "defineChannel",
53
53
  state: hasState ? { ...config.state } : {},
54
54
  fetchFile: config.fetchFile,
55
55
  createAdapterContext(base) {
56
56
  const state = base.state;
57
- const channelCtx = hasContext ? config.context(state) : {};
57
+ const session = base.session;
58
+ const channelCtx = hasContext
59
+ ? config.context(state, session)
60
+ : {};
58
61
  return {
59
62
  ...channelCtx,
60
63
  state,
61
64
  ctx: base.ctx,
62
- session: {
63
- id: "",
64
- continuationToken: "",
65
- auth: null,
66
- initiatorAuth: null,
67
- setContinuationToken(_token) {
68
- // TODO: wire to runtime
69
- },
70
- },
65
+ session,
71
66
  };
72
67
  },
73
68
  deliver(payload) {
@@ -75,4 +70,5 @@ function buildAdapter(config) {
75
70
  },
76
71
  ...eventHandlers,
77
72
  };
73
+ return adapter;
78
74
  }
@@ -1,10 +1,9 @@
1
1
  import type { Optional } from "#shared/optional.js";
2
- import type { SandboxSession } from "#shared/sandbox-session.js";
3
2
  import type { SandboxDefinition as SharedSandboxDefinition } from "#shared/sandbox-definition.js";
4
3
  export type { SandboxCommandOptions, SandboxCommandResult, SandboxReadTextFileOptions, SandboxSession, SandboxWriteTextFileOptions, } from "#shared/sandbox-session.js";
5
4
  export type { SandboxBootstrapUseFn, SandboxSessionUseFn, SandboxBootstrapContext, SandboxSessionContext, } from "#shared/sandbox-definition.js";
6
- export type SandboxDefinition<S extends SandboxSession = SandboxSession, BO = Record<string, never>, SO = Record<string, never>> = Optional<SharedSandboxDefinition<S, BO, SO>, "backend">;
5
+ export type SandboxDefinition<BO = Record<string, never>, SO = Record<string, never>> = Optional<SharedSandboxDefinition<BO, SO>, "backend">;
7
6
  /**
8
7
  * Defines a sandbox configuration.
9
8
  */
10
- export declare function defineSandbox<S extends SandboxSession = SandboxSession, BO = Record<string, never>, SO = Record<string, never>>(definition: SandboxDefinition<S, BO, SO>): SandboxDefinition<S, BO, SO>;
9
+ export declare function defineSandbox<BO = Record<string, never>, SO = Record<string, never>>(definition: SandboxDefinition<BO, SO>): SandboxDefinition<BO, SO>;
@@ -1,11 +1,11 @@
1
1
  import type { SandboxBackend } from "#public/definitions/sandbox-backend.js";
2
- import type { VercelSandbox, VercelSandboxBootstrapUseOptions, VercelSandboxSessionUseOptions } from "#public/sandbox/vercel-sandbox.js";
2
+ import type { VercelSandboxBootstrapUseOptions, VercelSandboxSessionUseOptions } from "#public/sandbox/vercel-sandbox.js";
3
3
  /**
4
4
  * Constructs the built-in Vercel sandbox backend.
5
5
  *
6
6
  * `bootstrap({ use })` applies its options to the template via
7
7
  * `sandbox.update(...)`; those settings persist into the snapshot.
8
- * `onSession({ use })` applies its options to the live session via
9
- * `VercelSandbox.update()`.
8
+ * `onSession({ use })` applies its options to the live session via the
9
+ * SDK's `update` under the hood.
10
10
  */
11
- export declare function vercelBackend(): SandboxBackend<VercelSandbox, VercelSandboxBootstrapUseOptions, VercelSandboxSessionUseOptions>;
11
+ export declare function vercelBackend(): SandboxBackend<VercelSandboxBootstrapUseOptions, VercelSandboxSessionUseOptions>;
@@ -4,8 +4,8 @@ import { createVercelSandboxBackend } from "#execution/sandbox/bindings/vercel.j
4
4
  *
5
5
  * `bootstrap({ use })` applies its options to the template via
6
6
  * `sandbox.update(...)`; those settings persist into the snapshot.
7
- * `onSession({ use })` applies its options to the live session via
8
- * `VercelSandbox.update()`.
7
+ * `onSession({ use })` applies its options to the live session via the
8
+ * SDK's `update` under the hood.
9
9
  */
10
10
  export function vercelBackend() {
11
11
  return createVercelSandboxBackend();
@@ -9,4 +9,4 @@ export { SandboxTemplateNotProvisionedError } from "#public/definitions/sandbox-
9
9
  export { defaultBackend } from "#public/sandbox/backends/default.js";
10
10
  export { localBackend } from "#public/sandbox/backends/local.js";
11
11
  export { vercelBackend } from "#public/sandbox/backends/vercel.js";
12
- export type { VercelSandbox, VercelSandboxBootstrapUseOptions, VercelSandboxSessionUseOptions, } from "#public/sandbox/vercel-sandbox.js";
12
+ export type { VercelSandboxBootstrapUseOptions, VercelSandboxSessionUseOptions, } from "#public/sandbox/vercel-sandbox.js";
@@ -1,5 +1,4 @@
1
1
  import type { SandboxUpdateParams } from "#compiled/@vercel/sandbox/index.js";
2
- import type { SandboxSession } from "#public/definitions/sandbox.js";
3
2
  /**
4
3
  * Options accepted by the Vercel backend's `bootstrap({ use })` hook.
5
4
  * Aliases the Vercel SDK's `SandboxUpdateParams` because bootstrap
@@ -14,32 +13,8 @@ import type { SandboxSession } from "#public/definitions/sandbox.js";
14
13
  */
15
14
  export type VercelSandboxBootstrapUseOptions = SandboxUpdateParams;
16
15
  /**
17
- * Options accepted by the Vercel backend's `onSession({ use })` hook
18
- * and `VercelSandbox.update()`. Aliases the Vercel SDK's
19
- * `SandboxUpdateParams` so the full live-session configuration surface
20
- * is available to authors.
16
+ * Options accepted by the Vercel backend's `onSession({ use })` hook.
17
+ * Aliases the Vercel SDK's `SandboxUpdateParams`; passed values are
18
+ * applied to the live session via the SDK's `update` under the hood.
21
19
  */
22
20
  export type VercelSandboxSessionUseOptions = SandboxUpdateParams;
23
- /**
24
- * Ash-owned session type returned by the Vercel backend's
25
- * `onSession({ use })` hook. Extends the narrow
26
- * {@link SandboxSession} with Vercel-specific capabilities that only
27
- * make sense on a live session sandbox (not a bootstrap template).
28
- */
29
- export interface VercelSandbox extends SandboxSession {
30
- readonly name: string;
31
- readonly persistent: boolean;
32
- readonly status: string;
33
- readonly networkPolicy: SandboxUpdateParams["networkPolicy"];
34
- readonly tags: Record<string, string> | undefined;
35
- update(params: VercelSandboxSessionUseOptions): Promise<void>;
36
- stop(opts?: {
37
- blocking?: boolean;
38
- }): Promise<void>;
39
- snapshot(opts?: {
40
- expiration?: number;
41
- }): Promise<{
42
- snapshotId: string;
43
- }>;
44
- domain(port: number): string;
45
- }
@@ -16,7 +16,6 @@ import type { InternalSkillDefinition } from "#shared/skill-definition.js";
16
16
  import type { InternalAgentDefinition } from "#shared/agent-definition.js";
17
17
  import type { InternalToolDefinitionWithExecuteFn } from "#shared/tool-definition.js";
18
18
  import type { SandboxDefinition } from "#shared/sandbox-definition.js";
19
- import type { SandboxSession } from "#shared/sandbox-session.js";
20
19
  /**
21
20
  * Runtime-owned source ref describing one additive config module import.
22
21
  */
@@ -83,7 +82,7 @@ export interface ResolvedConnectionDefinition extends ResolvedModuleSourceRef {
83
82
  * `vercelBackend()` and `localBackend()` based on the current
84
83
  * environment).
85
84
  */
86
- export type ResolvedSandboxDefinition = Readonly<SandboxDefinition<SandboxSession>> & ResolvedModuleSourceRef & {
85
+ export type ResolvedSandboxDefinition = Readonly<SandboxDefinition> & ResolvedModuleSourceRef & {
87
86
  readonly description?: string;
88
87
  };
89
88
  /**
@@ -7,9 +7,9 @@ import type { SandboxSession } from "#shared/sandbox-session.js";
7
7
  * runtime orchestrator can persist reconnect metadata and release
8
8
  * resources.
9
9
  */
10
- export interface SandboxBackendHandle<S extends SandboxSession = SandboxSession, SO = Record<string, never>> {
10
+ export interface SandboxBackendHandle<SO = Record<string, never>> {
11
11
  readonly session: SandboxSession;
12
- readonly useSessionFn: SandboxSessionUseFn<S, SO>;
12
+ readonly useSessionFn: SandboxSessionUseFn<SO>;
13
13
  captureState(): Promise<SandboxBackendSessionState>;
14
14
  dispose(): Promise<void>;
15
15
  }
@@ -97,7 +97,7 @@ export interface SandboxBackendPrewarmInput<BO = Record<string, never>> {
97
97
  * Each backend owns the full template-then-session lifecycle internally;
98
98
  * callers only need a single `create` call.
99
99
  */
100
- export interface SandboxBackend<S extends SandboxSession = SandboxSession, BO = Record<string, never>, SO = Record<string, never>> {
100
+ export interface SandboxBackend<BO = Record<string, never>, SO = Record<string, never>> {
101
101
  /**
102
102
  * Stable identifier for this backend implementation.
103
103
  *
@@ -113,7 +113,7 @@ export interface SandboxBackend<S extends SandboxSession = SandboxSession, BO =
113
113
  * {@link SandboxTemplateNotProvisionedError} when the requested
114
114
  * template is missing.
115
115
  */
116
- create(input: SandboxBackendCreateInput): Promise<SandboxBackendHandle<S, SO>>;
116
+ create(input: SandboxBackendCreateInput): Promise<SandboxBackendHandle<SO>>;
117
117
  /**
118
118
  * Build-time prewarm hook. Ash invokes this for every authored
119
119
  * sandbox in the compiled graph before serving traffic so the backend
@@ -1,12 +1,12 @@
1
1
  import type { SandboxSession } from "#shared/sandbox-session.js";
2
2
  import type { SandboxBackend } from "#shared/sandbox-backend.js";
3
3
  export type SandboxBootstrapUseFn<O = Record<string, never>> = (options?: O) => Promise<SandboxSession>;
4
- export type SandboxSessionUseFn<S extends SandboxSession = SandboxSession, O = Record<string, never>> = (options?: O) => Promise<S>;
4
+ export type SandboxSessionUseFn<O = Record<string, never>> = (options?: O) => Promise<SandboxSession>;
5
5
  export interface SandboxBootstrapContext<O = Record<string, never>> {
6
6
  readonly use: SandboxBootstrapUseFn<O>;
7
7
  }
8
- export interface SandboxSessionContext<S extends SandboxSession = SandboxSession, O = Record<string, never>> {
9
- readonly use: SandboxSessionUseFn<S, O>;
8
+ export interface SandboxSessionContext<O = Record<string, never>> {
9
+ readonly use: SandboxSessionUseFn<O>;
10
10
  }
11
11
  /**
12
12
  * Public sandbox definition authored in `agent/sandbox.ts` (shorthand)
@@ -21,7 +21,7 @@ export interface SandboxSessionContext<S extends SandboxSession = SandboxSession
21
21
  * `subagents/<name>/sandbox.ts` (or the folder form) and do not inherit
22
22
  * their parent's sandbox (skill seeds differ per agent).
23
23
  */
24
- export interface SandboxDefinition<S extends SandboxSession = SandboxSession, BO = Record<string, never>, SO = Record<string, never>> {
24
+ export interface SandboxDefinition<BO = Record<string, never>, SO = Record<string, never>> {
25
25
  /**
26
26
  * Backend that runs this sandbox.
27
27
  *
@@ -31,7 +31,7 @@ export interface SandboxDefinition<S extends SandboxSession = SandboxSession, BO
31
31
  * everywhere else. Set `backend` explicitly to pin the sandbox to a
32
32
  * specific backend regardless of environment.
33
33
  */
34
- backend: SandboxBackend<S, BO, SO>;
34
+ backend: SandboxBackend<BO, SO>;
35
35
  bootstrap?(input: SandboxBootstrapContext<BO>): Promise<void> | void;
36
- onSession?(input: SandboxSessionContext<S, SO>): Promise<void> | void;
36
+ onSession?(input: SandboxSessionContext<SO>): Promise<void> | void;
37
37
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "experimental-ash",
3
- "version": "0.18.1",
3
+ "version": "0.18.2",
4
4
  "bin": {
5
5
  "ash": "./bin/ash.js",
6
6
  "experimental-ash": "./bin/ash.js"