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.
- package/CHANGELOG.md +18 -2
- package/dist/docs/public/channels/README.md +75 -9
- package/dist/docs/public/schedules.md +13 -4
- package/dist/src/channel/adapter-context.d.ts +4 -0
- package/dist/src/channel/adapter-context.js +6 -0
- package/dist/src/channel/adapter.d.ts +10 -10
- package/dist/src/channel/cross-channel-receive.d.ts +1 -1
- package/dist/src/channel/cross-channel-receive.js +40 -0
- package/dist/src/channel/routes.d.ts +7 -0
- package/dist/src/channel/send.js +1 -1
- package/dist/src/channel/session.d.ts +47 -1
- package/dist/src/channel/session.js +46 -0
- package/dist/src/channel/types.d.ts +6 -5
- package/dist/src/chunks/{dev-authored-source-watcher-DtLxnrXI.js → dev-authored-source-watcher-j7YWh2Gx.js} +1 -1
- package/dist/src/chunks/{host-Dor4C8jo.js → host-DkTSR6YJ.js} +2 -2
- package/dist/src/chunks/{paths-AVYgVLR3.js → paths-Dwv0Eash.js} +21 -21
- package/dist/src/chunks/{prewarm-DsMkM8wg.js → prewarm-CQYfka30.js} +1 -1
- package/dist/src/cli/commands/info.js +1 -1
- package/dist/src/cli/run.js +1 -1
- package/dist/src/evals/cli/eval.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel.d.ts +2 -2
- package/dist/src/execution/sandbox/bindings/vercel.js +1 -34
- package/dist/src/execution/workflow-entry.js +35 -31
- package/dist/src/execution/workflow-steps.d.ts +16 -0
- package/dist/src/execution/workflow-steps.js +32 -4
- package/dist/src/harness/attachment-staging.js +2 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/public/channels/slack/api.d.ts +13 -8
- package/dist/src/public/channels/slack/api.js +31 -17
- package/dist/src/public/channels/slack/index.d.ts +2 -2
- package/dist/src/public/channels/slack/index.js +1 -0
- package/dist/src/public/channels/slack/interactions.js +3 -3
- package/dist/src/public/channels/slack/slackChannel.d.ts +5 -3
- package/dist/src/public/channels/slack/slackChannel.js +26 -15
- package/dist/src/public/channels/twilio/api.d.ts +9 -0
- package/dist/src/public/channels/twilio/api.js +11 -0
- package/dist/src/public/channels/twilio/index.d.ts +1 -1
- package/dist/src/public/channels/twilio/index.js +1 -1
- package/dist/src/public/channels/twilio/twilioChannel.d.ts +2 -0
- package/dist/src/public/channels/twilio/twilioChannel.js +8 -11
- package/dist/src/public/definitions/defineChannel.d.ts +9 -1
- package/dist/src/public/definitions/defineChannel.js +7 -11
- package/dist/src/public/definitions/sandbox.d.ts +2 -3
- package/dist/src/public/sandbox/backends/vercel.d.ts +4 -4
- package/dist/src/public/sandbox/backends/vercel.js +2 -2
- package/dist/src/public/sandbox/index.d.ts +1 -1
- package/dist/src/public/sandbox/vercel-sandbox.d.ts +3 -28
- package/dist/src/runtime/types.d.ts +1 -2
- package/dist/src/shared/sandbox-backend.d.ts +4 -4
- package/dist/src/shared/sandbox-definition.d.ts +6 -6
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createLogger } from "#internal/logging.js";
|
|
2
|
-
import { buildSlackBinding,
|
|
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
|
|
82
|
-
if (
|
|
83
|
-
throw new Error("slackChannel().receive: `threadTs` and `
|
|
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 (
|
|
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:
|
|
106
|
+
card: initialMessage.card,
|
|
95
107
|
};
|
|
96
|
-
if (
|
|
97
|
-
postInput.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:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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<
|
|
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<
|
|
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 {
|
|
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
|
-
* `
|
|
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<
|
|
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
|
-
* `
|
|
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 {
|
|
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
|
-
*
|
|
19
|
-
*
|
|
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
|
|
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<
|
|
10
|
+
export interface SandboxBackendHandle<SO = Record<string, never>> {
|
|
11
11
|
readonly session: SandboxSession;
|
|
12
|
-
readonly useSessionFn: SandboxSessionUseFn<
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
9
|
-
readonly use: SandboxSessionUseFn<
|
|
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<
|
|
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<
|
|
34
|
+
backend: SandboxBackend<BO, SO>;
|
|
35
35
|
bootstrap?(input: SandboxBootstrapContext<BO>): Promise<void> | void;
|
|
36
|
-
onSession?(input: SandboxSessionContext<
|
|
36
|
+
onSession?(input: SandboxSessionContext<SO>): Promise<void> | void;
|
|
37
37
|
}
|