experimental-ash 0.18.3 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/dist/docs/internals/context.md +7 -0
- package/dist/docs/public/channels/README.md +5 -0
- package/dist/docs/public/channels/slack.md +58 -4
- package/dist/docs/public/hooks.md +4 -2
- package/dist/docs/public/sandbox.md +71 -49
- package/dist/docs/public/tools.md +55 -3
- package/dist/docs/public/typescript-api.md +6 -1
- package/dist/src/channel/adapter.js +12 -2
- package/dist/src/channel/routes.d.ts +9 -1
- package/dist/src/channel/send.js +3 -3
- package/dist/src/channel/types.d.ts +3 -1
- package/dist/src/chunks/{dev-authored-source-watcher-j7YWh2Gx.js → dev-authored-source-watcher-NA8BZIXr.js} +1 -1
- package/dist/src/chunks/host-DOH_6p0f.js +22 -0
- package/dist/src/chunks/{paths-Dwv0Eash.js → paths-CbL9m08U.js} +25 -25
- package/dist/src/chunks/{prewarm-CQYfka30.js → prewarm-Bz6Jr9J1.js} +1 -1
- package/dist/src/cli/commands/info.js +1 -1
- package/dist/src/cli/run.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +7 -7
- package/dist/src/compiled/@ai-sdk/anthropic/index.js +2 -2
- package/dist/src/compiled/@ai-sdk/anthropic/package.json +1 -1
- package/dist/src/compiled/@ai-sdk/google/index.js +6 -6
- package/dist/src/compiled/@ai-sdk/google/package.json +1 -1
- package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
- package/dist/src/compiled/@ai-sdk/mcp/package.json +1 -1
- package/dist/src/compiled/@ai-sdk/openai/index.js +6 -10
- package/dist/src/compiled/@ai-sdk/openai/package.json +1 -1
- package/dist/src/compiled/@ai-sdk/otel/index.js +2 -2
- package/dist/src/compiled/@ai-sdk/otel/package.json +1 -1
- package/dist/src/compiled/@ai-sdk/provider/package.json +1 -1
- package/dist/src/compiled/@vercel/sandbox/index.d.ts +6 -1
- package/dist/src/compiled/@workflow/core/index.js +1 -1
- package/dist/src/compiled/@workflow/core/runtime.js +5 -5
- package/dist/src/compiled/@workflow/core/workflow.js +1 -1
- package/dist/src/compiled/@workflow/errors/index.js +1 -1
- package/dist/src/compiled/_chunks/workflow/{context-errors-CmtmBosi.js → context-errors-zbKocOyk.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/dist-CpUQh3NH.js +14 -0
- package/dist/src/compiled/_chunks/workflow/{resume-hook-BqY8TqOE.js → resume-hook-CL8Ed91K.js} +2 -2
- package/dist/src/compiled/_chunks/workflow/sleep-Dn3i9nxI.js +1 -0
- package/dist/src/context/hook-lifecycle.js +5 -1
- package/dist/src/evals/cli/eval.js +1 -1
- package/dist/src/execution/node-step.js +1 -0
- package/dist/src/execution/sandbox/bash-tool.js +1 -1
- package/dist/src/execution/sandbox/bindings/local.d.ts +14 -1
- package/dist/src/execution/sandbox/bindings/local.js +22 -16
- package/dist/src/execution/sandbox/bindings/vercel.d.ts +6 -0
- package/dist/src/execution/sandbox/bindings/vercel.js +25 -14
- package/dist/src/execution/sandbox/glob-tool.js +1 -1
- package/dist/src/execution/sandbox/grep-tool.js +1 -1
- package/dist/src/execution/sandbox/lazy-backend.d.ts +15 -0
- package/dist/src/execution/sandbox/lazy-backend.js +33 -0
- package/dist/src/execution/sandbox/read-file-tool.js +1 -1
- package/dist/src/execution/sandbox/ripgrep-probe.js +1 -1
- package/dist/src/execution/sandbox/session.js +49 -31
- package/dist/src/execution/sandbox/stream-utils.d.ts +2 -2
- package/dist/src/execution/sandbox/stream-utils.js +1 -1
- package/dist/src/execution/sandbox/write-file-tool.js +3 -3
- package/dist/src/execution/skills/types.d.ts +1 -1
- package/dist/src/execution/workflow-entry.d.ts +2 -4
- package/dist/src/execution/workflow-entry.js +1 -1
- package/dist/src/harness/attachment-staging.js +10 -11
- package/dist/src/harness/execute-tool.d.ts +1 -0
- package/dist/src/harness/messages.js +15 -0
- package/dist/src/harness/tools.js +5 -0
- package/dist/src/harness/types.d.ts +6 -7
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-definition/sandbox.d.ts +8 -2
- package/dist/src/internal/authored-definition/sandbox.js +10 -2
- package/dist/src/internal/authored-definition/schema-backed.js +12 -1
- package/dist/src/internal/nitro/host/configure-nitro-routes.js +1 -1
- package/dist/src/internal/workflow-bundle/builder-support.d.ts +1 -0
- package/dist/src/internal/workflow-bundle/builder-support.js +14 -0
- package/dist/src/internal/workflow-bundle/builder.js +6 -6
- package/dist/src/public/channels/slack/api-encoding.d.ts +1 -1
- package/dist/src/public/channels/slack/api-encoding.js +1 -7
- package/dist/src/public/channels/slack/api.d.ts +5 -4
- package/dist/src/public/channels/slack/api.js +6 -6
- package/dist/src/public/channels/slack/index.d.ts +3 -0
- package/dist/src/public/channels/slack/index.js +2 -0
- package/dist/src/public/channels/slack/slackChannel.d.ts +12 -4
- package/dist/src/public/channels/slack/slackChannel.js +4 -1
- package/dist/src/public/channels/slack/thread.d.ts +26 -0
- package/dist/src/public/channels/slack/thread.js +45 -0
- package/dist/src/public/definitions/sandbox.d.ts +1 -1
- package/dist/src/public/definitions/tool.d.ts +25 -0
- package/dist/src/public/sandbox/backends/default.d.ts +16 -1
- package/dist/src/public/sandbox/backends/default.js +7 -19
- package/dist/src/public/sandbox/backends/local.d.ts +7 -4
- package/dist/src/public/sandbox/backends/local.js +7 -5
- package/dist/src/public/sandbox/backends/vercel.d.ts +9 -3
- package/dist/src/public/sandbox/backends/vercel.js +9 -3
- package/dist/src/public/sandbox/index.d.ts +3 -2
- package/dist/src/public/sandbox/local-sandbox.d.ts +7 -0
- package/dist/src/public/sandbox/local-sandbox.js +1 -0
- package/dist/src/public/sandbox/vercel-sandbox.d.ts +13 -1
- package/dist/src/public/tools/index.d.ts +1 -1
- package/dist/src/runtime/resolve-sandbox.js +5 -1
- package/dist/src/runtime/resolve-tool.js +3 -0
- package/dist/src/runtime/skills/sandbox-access.js +3 -3
- package/dist/src/runtime/types.d.ts +17 -2
- package/dist/src/shared/sandbox-definition.d.ts +16 -1
- package/dist/src/shared/sandbox-session.d.ts +53 -121
- package/package.json +9 -9
- package/dist/src/chunks/host-C19hLVqS.js +0 -22
- package/dist/src/compiled/_chunks/workflow/dist-4zn5tehu.js +0 -10
- package/dist/src/compiled/_chunks/workflow/dist-DTWUhyDN.js +0 -5
- package/dist/src/compiled/_chunks/workflow/sleep-D30F1GSr.js +0 -1
- /package/dist/src/compiled/_chunks/workflow/{dist-B6aByiku.js → dist-0iNBqPYp.js} +0 -0
- /package/dist/src/compiled/_chunks/workflow/{dist-CVo7knbW.js → dist-D774SUM4.js} +0 -0
- /package/dist/src/compiled/_chunks/workflow/{src-Bc9OYRaN.js → src-ClRYdO4-.js} +0 -0
- /package/dist/src/compiled/_chunks/workflow/{symbols-DkV1V0kM.js → symbols-D-4tVV8x.js} +0 -0
- /package/dist/src/compiled/_chunks/workflow/{token-Cq5QjRq8.js → token-CsNmv7KW.js} +0 -0
- /package/dist/src/compiled/_chunks/workflow/{token-Duaoxfi5.js → token-j5Cl4rrs.js} +0 -0
|
@@ -4,7 +4,7 @@ import { dirname, join, relative, resolve } from "node:path";
|
|
|
4
4
|
import { resolvePackageSourceDirectoryPath, resolveWorkflowModulePath, } from "#internal/application/package.js";
|
|
5
5
|
import { prepareAshVersionedCacheDirectory, writeAshVersionedCacheMetadata, } from "#internal/application/cache-metadata.js";
|
|
6
6
|
import { normalizeEsmImportSpecifier } from "#internal/application/import-specifier.js";
|
|
7
|
-
import { bundleFinalWorkflowOutput, collectWorkflowInputFiles, convertClassesManifest, convertStepsManifest, convertWorkflowsManifest, createAshPackageImportsPlugin, createWorkflowImport, createWorkflowPseudoPackagePlugin, createWorkflowTransformPlugin, createWorkflowVirtualEntryPlugin, WORKFLOW_VIRTUAL_ENTRY_ID, } from "#internal/workflow-bundle/builder-support.js";
|
|
7
|
+
import { atomicWriteFile, bundleFinalWorkflowOutput, collectWorkflowInputFiles, convertClassesManifest, convertStepsManifest, convertWorkflowsManifest, createAshPackageImportsPlugin, createWorkflowImport, createWorkflowPseudoPackagePlugin, createWorkflowTransformPlugin, createWorkflowVirtualEntryPlugin, WORKFLOW_VIRTUAL_ENTRY_ID, } from "#internal/workflow-bundle/builder-support.js";
|
|
8
8
|
import { buildWithNitroRolldown, getSingleRolldownChunk, } from "#internal/bundler/nitro-rolldown.js";
|
|
9
9
|
import { writeNitroStepEntrypoint } from "#internal/workflow-bundle/nitro-step-entry.js";
|
|
10
10
|
import { copyNitroFunctionDirectory, createWorkflowFunctionEnvironment, retargetNitroFunctionDirectoryToWorkflowRoute, WORKFLOW_BUILDER_DEFERRED_PACKAGES, WORKFLOW_STEP_EXTERNAL_PACKAGES, } from "#internal/workflow-bundle/vercel-workflow-output.js";
|
|
@@ -347,12 +347,12 @@ async function addStepRegistrationsImport(workflowBundlePath, stepRegistrationsP
|
|
|
347
347
|
].join("\n");
|
|
348
348
|
const firstImportMatch = source.match(/^import\s.+?;\n/m);
|
|
349
349
|
if (firstImportMatch === null || firstImportMatch.index === undefined) {
|
|
350
|
-
await
|
|
350
|
+
await atomicWriteFile(workflowBundlePath, `${importSource}${source}`);
|
|
351
351
|
return;
|
|
352
352
|
}
|
|
353
353
|
const insertionIndex = firstImportMatch.index + firstImportMatch[0].length;
|
|
354
354
|
const nextSource = `${source.slice(0, insertionIndex)}${importSource}${source.slice(insertionIndex)}`;
|
|
355
|
-
await
|
|
355
|
+
await atomicWriteFile(workflowBundlePath, nextSource);
|
|
356
356
|
}
|
|
357
357
|
async function rewriteWorkflowRuntimeImports(filePath) {
|
|
358
358
|
const source = await readTextFileIfPresent(filePath);
|
|
@@ -371,7 +371,7 @@ async function rewriteWorkflowRuntimeImports(filePath) {
|
|
|
371
371
|
nextSource = replaceStringLiteralSpecifier(nextSource, specifier, resolvedSpecifier);
|
|
372
372
|
}
|
|
373
373
|
if (nextSource !== source) {
|
|
374
|
-
await
|
|
374
|
+
await atomicWriteFile(filePath, nextSource);
|
|
375
375
|
}
|
|
376
376
|
}
|
|
377
377
|
async function rewriteWorkflowCodeLiteral(filePath) {
|
|
@@ -394,7 +394,7 @@ async function rewriteWorkflowCodeLiteral(filePath) {
|
|
|
394
394
|
const workflowCode = decodeWorkflowCodeTemplateLiteral(expression, filePath);
|
|
395
395
|
const nextSource = `${source.slice(0, valueStart)}${encodeWorkflowCodeLiteral(workflowCode)}${source.slice(expressionEnd)}`;
|
|
396
396
|
if (nextSource !== source) {
|
|
397
|
-
await
|
|
397
|
+
await atomicWriteFile(filePath, nextSource);
|
|
398
398
|
}
|
|
399
399
|
}
|
|
400
400
|
function encodeWorkflowCodeLiteral(workflowCode) {
|
|
@@ -468,5 +468,5 @@ async function mirrorFileBypassingUnlink(sourcePath, targetPath) {
|
|
|
468
468
|
if (existingContents !== null && existingContents.equals(sourceContents)) {
|
|
469
469
|
return;
|
|
470
470
|
}
|
|
471
|
-
await
|
|
471
|
+
await atomicWriteFile(targetPath, sourceContents);
|
|
472
472
|
}
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
export function encodeSlackApiBody(body
|
|
2
|
-
if (encoding === "json") {
|
|
3
|
-
return {
|
|
4
|
-
body: JSON.stringify(body),
|
|
5
|
-
contentType: "application/json; charset=utf-8",
|
|
6
|
-
};
|
|
7
|
-
}
|
|
1
|
+
export function encodeSlackApiBody(body) {
|
|
8
2
|
const params = new URLSearchParams();
|
|
9
3
|
if (body && typeof body === "object") {
|
|
10
4
|
for (const [key, value] of Object.entries(body)) {
|
|
@@ -42,15 +42,16 @@ export interface SlackApiResponse {
|
|
|
42
42
|
/**
|
|
43
43
|
* Low-level POST to a Slack Web API method.
|
|
44
44
|
*
|
|
45
|
-
* Signs
|
|
46
|
-
*
|
|
47
|
-
*
|
|
45
|
+
* Signs with the bot token and form-encodes the body — Slack documents
|
|
46
|
+
* `application/x-www-form-urlencoded` as universal, JSON support is
|
|
47
|
+
* partial (e.g. `conversations.replies` rejects JSON), so form is the
|
|
48
|
+
* only safe default. Returns Slack's raw JSON response; callers inspect
|
|
49
|
+
* `response.ok` themselves.
|
|
48
50
|
*/
|
|
49
51
|
export declare function callSlackApi(input: {
|
|
50
52
|
readonly botToken: SlackBotToken | undefined;
|
|
51
53
|
readonly operation: string;
|
|
52
54
|
readonly body: unknown;
|
|
53
|
-
readonly encoding?: "form" | "json";
|
|
54
55
|
}): Promise<SlackApiResponse>;
|
|
55
56
|
/**
|
|
56
57
|
* Builds the `request(op, body)` Slack API caller installed on every
|
|
@@ -43,13 +43,15 @@ export async function resolveSlackBotToken(token) {
|
|
|
43
43
|
/**
|
|
44
44
|
* Low-level POST to a Slack Web API method.
|
|
45
45
|
*
|
|
46
|
-
* Signs
|
|
47
|
-
*
|
|
48
|
-
*
|
|
46
|
+
* Signs with the bot token and form-encodes the body — Slack documents
|
|
47
|
+
* `application/x-www-form-urlencoded` as universal, JSON support is
|
|
48
|
+
* partial (e.g. `conversations.replies` rejects JSON), so form is the
|
|
49
|
+
* only safe default. Returns Slack's raw JSON response; callers inspect
|
|
50
|
+
* `response.ok` themselves.
|
|
49
51
|
*/
|
|
50
52
|
export async function callSlackApi(input) {
|
|
51
53
|
const token = await resolveSlackBotToken(input.botToken);
|
|
52
|
-
const encoded = encodeSlackApiBody(input.body
|
|
54
|
+
const encoded = encodeSlackApiBody(input.body);
|
|
53
55
|
const response = await fetch(`https://slack.com/api/${input.operation}`, {
|
|
54
56
|
method: "POST",
|
|
55
57
|
headers: {
|
|
@@ -99,7 +101,6 @@ export function buildSlackBinding(input) {
|
|
|
99
101
|
const getUrl = await callSlackApi({
|
|
100
102
|
botToken: input.botToken,
|
|
101
103
|
operation: "files.getUploadURLExternal",
|
|
102
|
-
encoding: "form",
|
|
103
104
|
body: {
|
|
104
105
|
filename: file.filename,
|
|
105
106
|
length: bytes.byteLength,
|
|
@@ -135,7 +136,6 @@ export function buildSlackBinding(input) {
|
|
|
135
136
|
const complete = await callSlackApi({
|
|
136
137
|
botToken: input.botToken,
|
|
137
138
|
operation: "files.completeUploadExternal",
|
|
138
|
-
encoding: "form",
|
|
139
139
|
body: completeBody,
|
|
140
140
|
});
|
|
141
141
|
if (complete.ok !== true) {
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
export type { ModelMessage } from "ai";
|
|
1
2
|
export { slackChannel, type SlackApiResponse, type SlackBotToken, type SlackChannel, type SlackChannelConfig, type SlackChannelCredentials, type SlackChannelEvents, type SlackChannelState, type SlackContext, type SlackEventContext, type SlackHandle, type SlackInboundResult, type SlackInboundResultOrPromise, type SlackInitialMessage, type SlackInteractionAction, type SlackMentionResult, type SlackMentionResultOrPromise, type SlackReceiveArgs, type SlackThread, type SlackWebhookVerifier, } from "#public/channels/slack/slackChannel.js";
|
|
2
3
|
export type { SlackAttachment, SlackAuthor, SlackInboundContext, SlackMessage, } from "#public/channels/slack/inbound.js";
|
|
3
4
|
export { slackContinuationToken, type SlackPostInput, type SlackPostedMessage, type SlackThreadMessage, type SlackUploadFilesOptions, type SlackUploadFilesResult, } from "#public/channels/slack/api.js";
|
|
5
|
+
export { defaultSlackAuth } from "#public/channels/slack/defaults.js";
|
|
6
|
+
export { loadThreadContextMessages, type LoadThreadContextMessagesOptions, type ThreadContextSince, } from "#public/channels/slack/thread.js";
|
|
4
7
|
export { cardToBlocks, cardToFallbackText, type BlockKitBlock, } from "#public/channels/slack/blocks.js";
|
|
5
8
|
/**
|
|
6
9
|
* Card builders and element types re-exported from the vendored chat
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { slackChannel, } from "#public/channels/slack/slackChannel.js";
|
|
2
2
|
export { slackContinuationToken, } from "#public/channels/slack/api.js";
|
|
3
|
+
export { defaultSlackAuth } from "#public/channels/slack/defaults.js";
|
|
4
|
+
export { loadThreadContextMessages, } from "#public/channels/slack/thread.js";
|
|
3
5
|
export { cardToBlocks, cardToFallbackText, } from "#public/channels/slack/blocks.js";
|
|
4
6
|
/**
|
|
5
7
|
* Card builders and element types re-exported from the vendored chat
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ModelMessage } from "ai";
|
|
1
2
|
import type { TypedReceiveRoute } from "#channel/receive-args.js";
|
|
2
3
|
import type { SessionHandle } from "#channel/session.js";
|
|
3
4
|
import type { SessionAuthContext } from "#channel/types.js";
|
|
@@ -158,12 +159,19 @@ export interface SlackInteractionUser {
|
|
|
158
159
|
readonly name?: string;
|
|
159
160
|
}
|
|
160
161
|
/**
|
|
161
|
-
* Result of an `onAppMention` or `onDirectMessage` callback. Return
|
|
162
|
-
*
|
|
163
|
-
*
|
|
162
|
+
* Result of an `onAppMention` or `onDirectMessage` callback. Return an
|
|
163
|
+
* object (auth may be `null`) to dispatch a turn, or `null` to silently
|
|
164
|
+
* drop the inbound message.
|
|
165
|
+
*
|
|
166
|
+
* `modelContext` mirrors lifecycle hook results: it contributes
|
|
167
|
+
* ephemeral messages to the next model call only, without writing them
|
|
168
|
+
* to durable session history. Use `role: "system"` for Slack thread
|
|
169
|
+
* background context so it lands before the user's mention; see
|
|
170
|
+
* `docs/public/channels/slack.md`.
|
|
164
171
|
*/
|
|
165
172
|
export type SlackMentionResult = {
|
|
166
|
-
auth: SessionAuthContext | null;
|
|
173
|
+
readonly auth: SessionAuthContext | null;
|
|
174
|
+
readonly modelContext?: readonly ModelMessage[];
|
|
167
175
|
} | null;
|
|
168
176
|
export type SlackMentionResultOrPromise = SlackMentionResult | Promise<SlackMentionResult>;
|
|
169
177
|
/**
|
|
@@ -230,7 +230,10 @@ async function dispatchInboundMessage(input) {
|
|
|
230
230
|
? prependSlackContext(baseMessage, inboundContext)
|
|
231
231
|
: baseMessage;
|
|
232
232
|
try {
|
|
233
|
-
await input.send(
|
|
233
|
+
await input.send({
|
|
234
|
+
message: turnMessage,
|
|
235
|
+
modelContext: result.modelContext,
|
|
236
|
+
}, {
|
|
234
237
|
auth: result.auth,
|
|
235
238
|
continuationToken: slackContinuationToken(message.channelId, message.threadTs),
|
|
236
239
|
state: {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { SlackThread, SlackThreadMessage } from "#public/channels/slack/api.js";
|
|
2
|
+
export type ThreadContextSince = "thread-root" | "last-agent-reply" | ((message: SlackThreadMessage) => boolean);
|
|
3
|
+
export interface LoadThreadContextMessagesOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Boundary for returned context messages. Defaults to `"thread-root"`.
|
|
6
|
+
*
|
|
7
|
+
* Use `"last-agent-reply"` to include only user/thread messages
|
|
8
|
+
* since the last agent-authored Slack reply. Pass a predicate
|
|
9
|
+
* function for custom boundaries, such as "since the last message
|
|
10
|
+
* that mentioned a particular user".
|
|
11
|
+
*/
|
|
12
|
+
readonly since?: ThreadContextSince;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Loads messages that are useful as background context for the current
|
|
16
|
+
* Slack thread turn.
|
|
17
|
+
*
|
|
18
|
+
* Returns an empty array when `message` is the thread root. For thread
|
|
19
|
+
* replies, refreshes the bound Slack thread and returns its recent
|
|
20
|
+
* messages before the triggering message, filtered by {@link options}.
|
|
21
|
+
* Formatting and model-message role choice stay with the caller.
|
|
22
|
+
*/
|
|
23
|
+
export declare function loadThreadContextMessages(thread: Pick<SlackThread, "recentMessages" | "refresh">, message: {
|
|
24
|
+
readonly threadTs: string;
|
|
25
|
+
readonly ts: string;
|
|
26
|
+
}, options?: LoadThreadContextMessagesOptions): Promise<SlackThreadMessage[]>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loads messages that are useful as background context for the current
|
|
3
|
+
* Slack thread turn.
|
|
4
|
+
*
|
|
5
|
+
* Returns an empty array when `message` is the thread root. For thread
|
|
6
|
+
* replies, refreshes the bound Slack thread and returns its recent
|
|
7
|
+
* messages before the triggering message, filtered by {@link options}.
|
|
8
|
+
* Formatting and model-message role choice stay with the caller.
|
|
9
|
+
*/
|
|
10
|
+
export async function loadThreadContextMessages(thread, message, options = {}) {
|
|
11
|
+
if (isThreadRootMessage(message)) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
await thread.refresh();
|
|
15
|
+
const currentIndex = thread.recentMessages.findIndex((entry) => entry.ts === message.ts);
|
|
16
|
+
const candidateMessages = currentIndex === -1 ? thread.recentMessages : thread.recentMessages.slice(0, currentIndex);
|
|
17
|
+
const priorMessages = candidateMessages.filter((entry) => entry.threadTs === message.threadTs && entry.ts !== message.ts);
|
|
18
|
+
return applySinceBoundary(priorMessages, options.since);
|
|
19
|
+
}
|
|
20
|
+
function isThreadRootMessage(message) {
|
|
21
|
+
return message.threadTs === message.ts;
|
|
22
|
+
}
|
|
23
|
+
function findLastIndex(items, predicate) {
|
|
24
|
+
for (let index = items.length - 1; index >= 0; index -= 1) {
|
|
25
|
+
if (predicate(items[index])) {
|
|
26
|
+
return index;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return -1;
|
|
30
|
+
}
|
|
31
|
+
function applySinceBoundary(messages, since) {
|
|
32
|
+
const boundary = since ?? "thread-root";
|
|
33
|
+
if (typeof boundary === "function") {
|
|
34
|
+
const lastMatchingIndex = findLastIndex(messages, boundary);
|
|
35
|
+
return messages.slice(lastMatchingIndex + 1);
|
|
36
|
+
}
|
|
37
|
+
switch (boundary) {
|
|
38
|
+
case "thread-root":
|
|
39
|
+
return [...messages];
|
|
40
|
+
case "last-agent-reply": {
|
|
41
|
+
const lastAgentReplyIndex = findLastIndex(messages, (entry) => entry.isMe);
|
|
42
|
+
return messages.slice(lastAgentReplyIndex + 1);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Optional } from "#shared/optional.js";
|
|
2
2
|
import type { SandboxDefinition as SharedSandboxDefinition } from "#shared/sandbox-definition.js";
|
|
3
|
-
export type {
|
|
3
|
+
export type { SandboxCommandResult, SandboxReadBinaryFileOptions, SandboxReadFileOptions, SandboxReadTextFileOptions, SandboxRunCommandOptions, SandboxSession, SandboxWriteBinaryFileOptions, SandboxWriteFileOptions, SandboxWriteTextFileOptions, } from "#shared/sandbox-session.js";
|
|
4
4
|
export type { SandboxBootstrapUseFn, SandboxSessionUseFn, SandboxBootstrapContext, SandboxSessionContext, } from "#shared/sandbox-definition.js";
|
|
5
5
|
export type SandboxDefinition<BO = Record<string, never>, SO = Record<string, never>> = Optional<SharedSandboxDefinition<BO, SO>, "backend">;
|
|
6
6
|
/**
|
|
@@ -47,6 +47,19 @@ export interface NeedsApprovalContext {
|
|
|
47
47
|
* function. These are the same options the SDK passes to every tool call.
|
|
48
48
|
*/
|
|
49
49
|
export type ToolExecuteOptions = Readonly<AiSdkToolExecuteOptions>;
|
|
50
|
+
/**
|
|
51
|
+
* Ash-owned shape for the model-facing tool result produced by
|
|
52
|
+
* {@link ToolDefinition.toModelOutput}. Structurally compatible with the
|
|
53
|
+
* AI SDK's `ToolResultOutput` so the harness can forward it without
|
|
54
|
+
* conversion.
|
|
55
|
+
*/
|
|
56
|
+
export type ToolModelOutput = {
|
|
57
|
+
readonly type: "text";
|
|
58
|
+
readonly value: string;
|
|
59
|
+
} | {
|
|
60
|
+
readonly type: "json";
|
|
61
|
+
readonly value: unknown;
|
|
62
|
+
};
|
|
50
63
|
/**
|
|
51
64
|
* Result returned from a {@link ToolRetentionPolicy} function.
|
|
52
65
|
*
|
|
@@ -106,6 +119,17 @@ export type ToolDefinition<TInput = unknown, TOutput = unknown> = PublicToolDefi
|
|
|
106
119
|
* {@link ToolRetentionPolicy}.
|
|
107
120
|
*/
|
|
108
121
|
retentionPolicy?: ToolRetentionPolicy<TOutput>;
|
|
122
|
+
/**
|
|
123
|
+
* Optional projection that controls what the model sees as the tool
|
|
124
|
+
* result. Receives the full `TOutput` from {@link execute} and returns
|
|
125
|
+
* a {@link ToolModelOutput} that becomes the model-facing tool result.
|
|
126
|
+
*
|
|
127
|
+
* When omitted, the model sees the full `execute` return value
|
|
128
|
+
* (default AI SDK serialization). Channel event handlers
|
|
129
|
+
* (`action.result`) always receive the full output regardless of
|
|
130
|
+
* whether this function is defined.
|
|
131
|
+
*/
|
|
132
|
+
toModelOutput?: (output: TOutput) => ToolModelOutput | Promise<ToolModelOutput>;
|
|
109
133
|
/**
|
|
110
134
|
* Called after message-history compaction. The framework invokes this
|
|
111
135
|
* hook for every tool that declares it, in tool registration order,
|
|
@@ -125,6 +149,7 @@ export declare function defineTool<TSchema extends StandardJSONSchemaV1<unknown,
|
|
|
125
149
|
execute: ToolDefinition<StandardJSONSchemaV1.InferOutput<TSchema>, TOutput>["execute"];
|
|
126
150
|
needsApproval?: ToolDefinition<unknown, unknown>["needsApproval"];
|
|
127
151
|
retentionPolicy?: ToolDefinition<unknown, TOutput>["retentionPolicy"];
|
|
152
|
+
toModelOutput?: ToolDefinition<unknown, TOutput>["toModelOutput"];
|
|
128
153
|
onCompact?: ToolDefinition<unknown, unknown>["onCompact"];
|
|
129
154
|
}): ToolDefinition<StandardJSONSchemaV1.InferOutput<TSchema>, TOutput>;
|
|
130
155
|
export declare function defineTool<TInput = unknown, TOutput = unknown>(definition: ToolDefinition<TInput, TOutput>): ToolDefinition<TInput, TOutput>;
|
|
@@ -1,7 +1,22 @@
|
|
|
1
1
|
import type { SandboxBackend } from "#public/definitions/sandbox-backend.js";
|
|
2
|
+
import type { LocalSandboxCreateOptions } from "#public/sandbox/local-sandbox.js";
|
|
3
|
+
import type { VercelSandboxCreateOptions } from "#public/sandbox/vercel-sandbox.js";
|
|
4
|
+
/**
|
|
5
|
+
* Input to {@link defaultBackend}: a separate options bag per inner
|
|
6
|
+
* backend. The framework picks one bag at runtime based on `process.env.VERCEL`
|
|
7
|
+
* and passes it to the chosen factory; the other is ignored.
|
|
8
|
+
*/
|
|
9
|
+
export interface DefaultBackendOptions {
|
|
10
|
+
readonly local?: LocalSandboxCreateOptions;
|
|
11
|
+
readonly vercel?: VercelSandboxCreateOptions;
|
|
12
|
+
}
|
|
2
13
|
/**
|
|
3
14
|
* Constructs an env-aware sandbox backend that delegates to
|
|
4
15
|
* {@link vercelBackend} on hosted Vercel (where `process.env.VERCEL`
|
|
5
16
|
* is truthy) and to {@link localBackend} everywhere else.
|
|
17
|
+
*
|
|
18
|
+
* Optionally accepts a keyed options bag (`{ local, vercel }`) so each
|
|
19
|
+
* inner backend receives its own typed create options without forcing
|
|
20
|
+
* authors to pin to one backend up front.
|
|
6
21
|
*/
|
|
7
|
-
export declare function defaultBackend(): SandboxBackend;
|
|
22
|
+
export declare function defaultBackend(opts?: DefaultBackendOptions): SandboxBackend;
|
|
@@ -1,27 +1,15 @@
|
|
|
1
|
+
import { lazyBackend } from "#execution/sandbox/lazy-backend.js";
|
|
1
2
|
import { localBackend } from "#public/sandbox/backends/local.js";
|
|
2
3
|
import { vercelBackend } from "#public/sandbox/backends/vercel.js";
|
|
3
4
|
/**
|
|
4
5
|
* Constructs an env-aware sandbox backend that delegates to
|
|
5
6
|
* {@link vercelBackend} on hosted Vercel (where `process.env.VERCEL`
|
|
6
7
|
* is truthy) and to {@link localBackend} everywhere else.
|
|
8
|
+
*
|
|
9
|
+
* Optionally accepts a keyed options bag (`{ local, vercel }`) so each
|
|
10
|
+
* inner backend receives its own typed create options without forcing
|
|
11
|
+
* authors to pin to one backend up front.
|
|
7
12
|
*/
|
|
8
|
-
export function defaultBackend() {
|
|
9
|
-
|
|
10
|
-
function resolve() {
|
|
11
|
-
if (resolved === undefined) {
|
|
12
|
-
resolved = process.env.VERCEL ? vercelBackend() : localBackend();
|
|
13
|
-
}
|
|
14
|
-
return resolved;
|
|
15
|
-
}
|
|
16
|
-
return {
|
|
17
|
-
get name() {
|
|
18
|
-
return resolve().name;
|
|
19
|
-
},
|
|
20
|
-
create(input) {
|
|
21
|
-
return resolve().create(input);
|
|
22
|
-
},
|
|
23
|
-
async prewarm(input) {
|
|
24
|
-
await resolve().prewarm(input);
|
|
25
|
-
},
|
|
26
|
-
};
|
|
13
|
+
export function defaultBackend(opts) {
|
|
14
|
+
return lazyBackend(() => process.env.VERCEL ? vercelBackend(opts?.vercel) : localBackend(opts?.local));
|
|
27
15
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { SandboxBackend } from "#public/definitions/sandbox-backend.js";
|
|
2
|
+
import type { LocalSandboxCreateOptions } from "#public/sandbox/local-sandbox.js";
|
|
2
3
|
/**
|
|
3
4
|
* Constructs the built-in local sandbox backend.
|
|
4
5
|
*
|
|
@@ -7,8 +8,10 @@ import type { SandboxBackend } from "#public/definitions/sandbox-backend.js";
|
|
|
7
8
|
* under the application root. It is the default backend on developer
|
|
8
9
|
* machines (`pnpm ash dev`).
|
|
9
10
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* Accepts an `opts` parameter for parity with other backends, but
|
|
12
|
+
* `LocalSandboxCreateOptions` is empty today — `just-bash` does not
|
|
13
|
+
* currently expose any configuration worth surfacing. New options would
|
|
14
|
+
* be added by widening `LocalSandboxCreateOptions` and routing them
|
|
15
|
+
* into the binding without changing this signature.
|
|
13
16
|
*/
|
|
14
|
-
export declare function localBackend(): SandboxBackend;
|
|
17
|
+
export declare function localBackend(opts?: LocalSandboxCreateOptions): SandboxBackend;
|
|
@@ -7,10 +7,12 @@ import { createLocalSandboxBackend } from "#execution/sandbox/bindings/local.js"
|
|
|
7
7
|
* under the application root. It is the default backend on developer
|
|
8
8
|
* machines (`pnpm ash dev`).
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* Accepts an `opts` parameter for parity with other backends, but
|
|
11
|
+
* `LocalSandboxCreateOptions` is empty today — `just-bash` does not
|
|
12
|
+
* currently expose any configuration worth surfacing. New options would
|
|
13
|
+
* be added by widening `LocalSandboxCreateOptions` and routing them
|
|
14
|
+
* into the binding without changing this signature.
|
|
13
15
|
*/
|
|
14
|
-
export function localBackend() {
|
|
15
|
-
return createLocalSandboxBackend();
|
|
16
|
+
export function localBackend(opts) {
|
|
17
|
+
return createLocalSandboxBackend({ createOptions: opts });
|
|
16
18
|
}
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import type { SandboxBackend } from "#public/definitions/sandbox-backend.js";
|
|
2
|
-
import type { VercelSandboxBootstrapUseOptions, VercelSandboxSessionUseOptions } from "#public/sandbox/vercel-sandbox.js";
|
|
2
|
+
import type { VercelSandboxBootstrapUseOptions, VercelSandboxCreateOptions, VercelSandboxSessionUseOptions } from "#public/sandbox/vercel-sandbox.js";
|
|
3
3
|
/**
|
|
4
4
|
* Constructs the built-in Vercel sandbox backend.
|
|
5
5
|
*
|
|
6
|
+
* The optional `opts` parameter is forwarded to the Vercel SDK's
|
|
7
|
+
* `Sandbox.create(...)` for every fresh sandbox the framework creates
|
|
8
|
+
* (template at prewarm, session at first-time create). On resume
|
|
9
|
+
* (`Sandbox.get`), no create happens, so opts are not re-applied.
|
|
10
|
+
*
|
|
6
11
|
* `bootstrap({ use })` applies its options to the template via
|
|
7
12
|
* `sandbox.update(...)`; those settings persist into the snapshot.
|
|
8
13
|
* `onSession({ use })` applies its options to the live session via the
|
|
9
|
-
* SDK's `update` under the hood
|
|
14
|
+
* SDK's `update` under the hood — overriding any overlapping field
|
|
15
|
+
* from `opts`.
|
|
10
16
|
*/
|
|
11
|
-
export declare function vercelBackend(): SandboxBackend<VercelSandboxBootstrapUseOptions, VercelSandboxSessionUseOptions>;
|
|
17
|
+
export declare function vercelBackend(opts?: VercelSandboxCreateOptions): SandboxBackend<VercelSandboxBootstrapUseOptions, VercelSandboxSessionUseOptions>;
|
|
@@ -2,11 +2,17 @@ import { createVercelSandboxBackend } from "#execution/sandbox/bindings/vercel.j
|
|
|
2
2
|
/**
|
|
3
3
|
* Constructs the built-in Vercel sandbox backend.
|
|
4
4
|
*
|
|
5
|
+
* The optional `opts` parameter is forwarded to the Vercel SDK's
|
|
6
|
+
* `Sandbox.create(...)` for every fresh sandbox the framework creates
|
|
7
|
+
* (template at prewarm, session at first-time create). On resume
|
|
8
|
+
* (`Sandbox.get`), no create happens, so opts are not re-applied.
|
|
9
|
+
*
|
|
5
10
|
* `bootstrap({ use })` applies its options to the template via
|
|
6
11
|
* `sandbox.update(...)`; those settings persist into the snapshot.
|
|
7
12
|
* `onSession({ use })` applies its options to the live session via the
|
|
8
|
-
* SDK's `update` under the hood
|
|
13
|
+
* SDK's `update` under the hood — overriding any overlapping field
|
|
14
|
+
* from `opts`.
|
|
9
15
|
*/
|
|
10
|
-
export function vercelBackend() {
|
|
11
|
-
return createVercelSandboxBackend();
|
|
16
|
+
export function vercelBackend(opts) {
|
|
17
|
+
return createVercelSandboxBackend({ createOptions: opts });
|
|
12
18
|
}
|
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
* `agent/sandbox/sandbox.ts` when paired with a `workspace/` folder).
|
|
4
4
|
*/
|
|
5
5
|
export { getSandbox } from "#context/accessors.js";
|
|
6
|
-
export { defineSandbox, type SandboxBootstrapContext, type SandboxBootstrapUseFn, type
|
|
6
|
+
export { defineSandbox, type SandboxBootstrapContext, type SandboxBootstrapUseFn, type SandboxCommandResult, type SandboxDefinition, type SandboxReadBinaryFileOptions, type SandboxReadFileOptions, type SandboxReadTextFileOptions, type SandboxRunCommandOptions, type SandboxSession, type SandboxSessionContext, type SandboxSessionUseFn, type SandboxWriteBinaryFileOptions, type SandboxWriteFileOptions, type SandboxWriteTextFileOptions, } from "#public/definitions/sandbox.js";
|
|
7
7
|
export type { SandboxBackend, SandboxBackendCreateInput, SandboxBackendHandle, SandboxBackendPrewarmInput, SandboxBackendRuntimeContext, SandboxBackendSessionState, SandboxSeedFile, } from "#public/definitions/sandbox-backend.js";
|
|
8
8
|
export { SandboxTemplateNotProvisionedError } from "#public/definitions/sandbox-backend.js";
|
|
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 { LocalSandboxCreateOptions } from "#public/sandbox/local-sandbox.js";
|
|
13
|
+
export type { VercelSandboxBootstrapUseOptions, VercelSandboxCreateOptions, VercelSandboxSessionUseOptions, } from "#public/sandbox/vercel-sandbox.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options accepted by `localBackend(opts)`. Reserved for future
|
|
3
|
+
* widening: today the local backend exposes no consumer-controllable
|
|
4
|
+
* create options, so this is an empty object. The parameter exists on
|
|
5
|
+
* the factory so adding real fields here later is purely additive.
|
|
6
|
+
*/
|
|
7
|
+
export type LocalSandboxCreateOptions = Record<string, never>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
import type { SandboxUpdateParams } from "#compiled/@vercel/sandbox/index.js";
|
|
1
|
+
import type { Sandbox as SdkSandbox, SandboxUpdateParams } from "#compiled/@vercel/sandbox/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Options accepted by `vercelBackend(opts)`. Forwarded directly to the
|
|
4
|
+
* Vercel SDK's `Sandbox.create(...)` for every fresh sandbox the
|
|
5
|
+
* framework creates (template at prewarm time, session at first-time
|
|
6
|
+
* session-create). Skipped on resume (`Sandbox.get`) since no create
|
|
7
|
+
* happens there.
|
|
8
|
+
*
|
|
9
|
+
* Framework-injected fields (`name`, `persistent`, `source`, `signal`)
|
|
10
|
+
* are excluded — the framework owns those and overrides any author-
|
|
11
|
+
* supplied values.
|
|
12
|
+
*/
|
|
13
|
+
export type VercelSandboxCreateOptions = Omit<NonNullable<Parameters<typeof SdkSandbox.create>[0]>, "name" | "persistent" | "source" | "signal">;
|
|
2
14
|
/**
|
|
3
15
|
* Options accepted by the Vercel backend's `bootstrap({ use })` hook.
|
|
4
16
|
* Aliases the Vercel SDK's `SandboxUpdateParams` because bootstrap
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tool authoring helpers for `agent/tools/*.ts` files.
|
|
3
3
|
*/
|
|
4
|
-
export { type CompactionHookInput, type CompactionHookResult, type DisabledToolSentinel, defineTool, disableTool, isDisabledToolSentinel, type NeedsApprovalContext, type RetentionSummary, type ToolDefinition, type ToolRetentionPolicy, } from "#public/definitions/tool.js";
|
|
4
|
+
export { type CompactionHookInput, type CompactionHookResult, type DisabledToolSentinel, defineTool, disableTool, isDisabledToolSentinel, type NeedsApprovalContext, type RetentionSummary, type ToolDefinition, type ToolModelOutput, type ToolRetentionPolicy, } from "#public/definitions/tool.js";
|
|
5
5
|
export { type DefineBashToolInput, defineBashTool } from "#public/tools/define-bash-tool.js";
|
|
6
6
|
export { type DefineGlobToolInput, defineGlobTool } from "#public/tools/define-glob-tool.js";
|
|
7
7
|
export { type DefineGrepToolInput, defineGrepTool } from "#public/tools/define-grep-tool.js";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { lazyBackend } from "#execution/sandbox/lazy-backend.js";
|
|
1
2
|
import { expectObjectRecord } from "#internal/authored-module.js";
|
|
2
3
|
import { defaultBackend } from "#public/sandbox/backends/default.js";
|
|
3
4
|
import { toErrorMessage } from "#shared/errors.js";
|
|
@@ -47,8 +48,11 @@ function resolveBackend(value, logicalPath) {
|
|
|
47
48
|
if (value === undefined) {
|
|
48
49
|
return defaultBackend();
|
|
49
50
|
}
|
|
51
|
+
if (typeof value === "function") {
|
|
52
|
+
return lazyBackend(value);
|
|
53
|
+
}
|
|
50
54
|
if (typeof value !== "object" || value === null) {
|
|
51
|
-
throw new ResolveAgentError(`Sandbox "${logicalPath}" exposed a non-object "backend" field. Use vercelBackend(), localBackend(),
|
|
55
|
+
throw new ResolveAgentError(`Sandbox "${logicalPath}" exposed a non-object "backend" field. Use vercelBackend(), localBackend(), another factory that returns a SandboxBackend value, or a zero-arg callback returning one.`, { logicalPath });
|
|
52
56
|
}
|
|
53
57
|
const record = value;
|
|
54
58
|
if (typeof record.name !== "string" || record.name.length === 0) {
|
|
@@ -60,6 +60,9 @@ function extractOptionalHooks(record, definition) {
|
|
|
60
60
|
if (retentionPolicy !== undefined) {
|
|
61
61
|
optional.retentionPolicy = retentionPolicy;
|
|
62
62
|
}
|
|
63
|
+
if (record.toModelOutput !== undefined) {
|
|
64
|
+
optional.toModelOutput = expectFunction(record.toModelOutput, describe(definition, "to provide a toModelOutput function"));
|
|
65
|
+
}
|
|
63
66
|
if (record.inputSchema !== undefined && isFlexibleSchema(record.inputSchema)) {
|
|
64
67
|
optional.inputStandardSchema = record.inputSchema;
|
|
65
68
|
}
|
|
@@ -27,7 +27,7 @@ export async function loadSkillFromSandbox(access, id) {
|
|
|
27
27
|
assertSafeSkillId(id);
|
|
28
28
|
const sandbox = await requireSandboxSession(access);
|
|
29
29
|
const path = skillFilePath(id, "SKILL.md");
|
|
30
|
-
const instructions = await sandbox.readTextFile(path);
|
|
30
|
+
const instructions = await sandbox.readTextFile({ path });
|
|
31
31
|
if (instructions === null) {
|
|
32
32
|
throw new Error(`No skill named "${id}" at ${path}.`);
|
|
33
33
|
}
|
|
@@ -47,14 +47,14 @@ export function createSandboxSkillHandle(access, id) {
|
|
|
47
47
|
return {
|
|
48
48
|
async bytes() {
|
|
49
49
|
const sandbox = await requireSandboxSession(access);
|
|
50
|
-
const content = await sandbox.readBinaryFile(path);
|
|
50
|
+
const content = await sandbox.readBinaryFile({ path });
|
|
51
51
|
if (content === null)
|
|
52
52
|
throw new Error(`Skill file not found: ${path}`);
|
|
53
53
|
return content;
|
|
54
54
|
},
|
|
55
55
|
async text() {
|
|
56
56
|
const sandbox = await requireSandboxSession(access);
|
|
57
|
-
const content = await sandbox.readTextFile(path);
|
|
57
|
+
const content = await sandbox.readTextFile({ path });
|
|
58
58
|
if (content === null)
|
|
59
59
|
throw new Error(`Skill file not found: ${path}`);
|
|
60
60
|
return content;
|
|
@@ -5,7 +5,7 @@ import type { DiscoverDiagnosticsSummary } from "#discover/diagnostics.js";
|
|
|
5
5
|
import type { ChannelMethod, RouteContext } from "#public/definitions/channel.js";
|
|
6
6
|
import type { RouteHandler } from "#channel/routes.js";
|
|
7
7
|
import type { LifecycleHooks, StreamEventHook } from "#public/definitions/hook.js";
|
|
8
|
-
import type { CompactionHookInput, CompactionHookResult, NeedsApprovalContext, ToolRetentionPolicy } from "#public/definitions/tool.js";
|
|
8
|
+
import type { CompactionHookInput, CompactionHookResult, NeedsApprovalContext, ToolModelOutput, ToolRetentionPolicy } from "#public/definitions/tool.js";
|
|
9
9
|
import type { AuthorizationDefinition, HeadersDefinition, ToolFilterDefinition } from "#runtime/connections/types.js";
|
|
10
10
|
import type { CompiledWorkspaceResourceRoot } from "#compiler/manifest.js";
|
|
11
11
|
import type { WorkspaceRuntimeSpec } from "#runtime/workspace/types.js";
|
|
@@ -15,6 +15,7 @@ import type { SourceRef, ModuleSourceRef, SkillPackageSourceRef, MarkdownSourceR
|
|
|
15
15
|
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
|
+
import type { SandboxBackend } from "#shared/sandbox-backend.js";
|
|
18
19
|
import type { SandboxDefinition } from "#shared/sandbox-definition.js";
|
|
19
20
|
/**
|
|
20
21
|
* Runtime-owned source ref describing one additive config module import.
|
|
@@ -82,7 +83,15 @@ export interface ResolvedConnectionDefinition extends ResolvedModuleSourceRef {
|
|
|
82
83
|
* `vercelBackend()` and `localBackend()` based on the current
|
|
83
84
|
* environment).
|
|
84
85
|
*/
|
|
85
|
-
export type ResolvedSandboxDefinition = Readonly<SandboxDefinition
|
|
86
|
+
export type ResolvedSandboxDefinition = Readonly<Omit<SandboxDefinition, "backend">> & ResolvedModuleSourceRef & {
|
|
87
|
+
/**
|
|
88
|
+
* Resolved backend value. The authored `SandboxDefinition.backend`
|
|
89
|
+
* accepts either a `SandboxBackend` or a `() => SandboxBackend`; by
|
|
90
|
+
* the time it reaches the runtime the function form has been
|
|
91
|
+
* unwrapped via `lazyBackend(...)` so consumers always see a plain
|
|
92
|
+
* value.
|
|
93
|
+
*/
|
|
94
|
+
readonly backend: SandboxBackend;
|
|
86
95
|
readonly description?: string;
|
|
87
96
|
};
|
|
88
97
|
/**
|
|
@@ -127,6 +136,12 @@ export type ResolvedToolDefinition = Readonly<Optional<InternalToolDefinitionWit
|
|
|
127
136
|
* history. See `packages/ash/src/execution/tool-compaction.ts`.
|
|
128
137
|
*/
|
|
129
138
|
readonly onCompact?: (input: CompactionHookInput) => CompactionHookResult | Promise<CompactionHookResult> | void | Promise<void>;
|
|
139
|
+
/**
|
|
140
|
+
* Optional projection that controls what the model sees as the tool
|
|
141
|
+
* result. The full `execute` return is still visible to channel event
|
|
142
|
+
* handlers and the stream. See {@link ToolModelOutput}.
|
|
143
|
+
*/
|
|
144
|
+
readonly toModelOutput?: (output: unknown) => ToolModelOutput | Promise<ToolModelOutput>;
|
|
130
145
|
};
|
|
131
146
|
/**
|
|
132
147
|
* Runtime-owned authored hook definition resolved from a compiled module
|