experimental-ash 0.7.5 → 0.7.6
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
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Development environment files loaded by
|
|
3
|
-
* lowest
|
|
2
|
+
* Development environment files loaded by local CLI commands such as
|
|
3
|
+
* `ash dev`, `ash build`, and `ash eval`, ordered from highest to lowest
|
|
4
|
+
* precedence.
|
|
4
5
|
*/
|
|
5
6
|
export declare const DEVELOPMENT_ENV_FILE_NAMES: readonly [".env.development.local", ".env.local", ".env.development", ".env"];
|
|
6
7
|
/**
|
package/dist/src/cli/run.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{t as e}from"../chunks/package-DmsQgn4v.js";import{createCliTheme as t,renderCliTaggedLine as n}from"./ui/output.js";import{i as r,n as i,r as a,t as o}from"../chunks/url-BVRhVE2O.js";import{resolve as s}from"node:path";async function c(){return(await import(`../chunks/host-33-Sb6vq.js`).then(e=>e.t)).buildHost}async function l(){return(await import(`./commands/info.js`)).printApplicationInfo}async function u(){return(await import(`./dev/repl.js`)).runDevelopmentRepl}async function d(){return(await import(`../evals/cli/eval.js`)).runEvalCommand}async function f(){return(await import(`../chunks/host-33-Sb6vq.js`).then(e=>e.t)).startHost}function p(e=process.cwd()){return s(e)}function m(e){return`Ash (v${e})`}function h(e){return e.name()===`info`||e.name()===`dev`}async function g(e){await new Promise((t,n)=>{let r=!1,i=()=>{process.off(`SIGINT`,a),process.off(`SIGTERM`,a)},a=()=>{r||(r=!0,i(),e.close().then(t,n))};process.once(`SIGINT`,a),process.once(`SIGTERM`,a)})}function _(e){if(!/^-?\d+$/.test(e))throw new r(`Expected a numeric port, received "${e}".`);let t=Number(e);if(!Number.isInteger(t))throw new r(`Expected a numeric port, received "${e}".`);if(t<0||t>65535)throw new r(`Expected a port between 0 and 65535, received "${e}".`);return t}function v(){return!!(process.stdin.isTTY&&process.stdout.isTTY)}function y(e){let t=e[1];return e[0]!==`dev`||e.length!==2||t===void 0||t.startsWith(`-`)?[...e]:[`dev`,`--url`,t]}function b(e){if(e.url){if(e.host!==void 0)throw new r(`The --host option cannot be used with --url.`);if(e.port!==void 0)throw new r(`The --port option cannot be used with --url.`);if(e.repl===!1)throw new r(`The --no-repl option cannot be used with --url.`);return e.url}}function x(r,a){let s=p(),y=e().version,x=new i,S=t();return x.name(`ash`).description(`Build and run an Ash application.`).version(y).showHelpAfterError().exitOverride().hook(`preAction`,(e,t)=>{h(t)&&r.log(m(y))}).configureOutput({writeErr:e=>{r.error(e.trimEnd())},writeOut:e=>{r.log(e.trimEnd())}}),x.command(`build`).description(`Build the current Ash application.`).action(async()=>{let e=await(a.buildHost??await c())(s);r.log(n(S,{message:`built output at ${
|
|
1
|
+
import{t as e}from"../chunks/package-DmsQgn4v.js";import{createCliTheme as t,renderCliTaggedLine as n}from"./ui/output.js";import{i as r,n as i,r as a,t as o}from"../chunks/url-BVRhVE2O.js";import{resolve as s}from"node:path";async function c(){return(await import(`../chunks/host-33-Sb6vq.js`).then(e=>e.t)).buildHost}async function l(){return(await import(`./commands/info.js`)).printApplicationInfo}async function u(){return(await import(`./dev/repl.js`)).runDevelopmentRepl}async function d(){return(await import(`../evals/cli/eval.js`)).runEvalCommand}async function f(){return(await import(`../chunks/host-33-Sb6vq.js`).then(e=>e.t)).startHost}function p(e=process.cwd()){return s(e)}function m(e){return`Ash (v${e})`}function h(e){return e.name()===`info`||e.name()===`dev`}async function g(e){await new Promise((t,n)=>{let r=!1,i=()=>{process.off(`SIGINT`,a),process.off(`SIGTERM`,a)},a=()=>{r||(r=!0,i(),e.close().then(t,n))};process.once(`SIGINT`,a),process.once(`SIGTERM`,a)})}function _(e){if(!/^-?\d+$/.test(e))throw new r(`Expected a numeric port, received "${e}".`);let t=Number(e);if(!Number.isInteger(t))throw new r(`Expected a numeric port, received "${e}".`);if(t<0||t>65535)throw new r(`Expected a port between 0 and 65535, received "${e}".`);return t}function v(){return!!(process.stdin.isTTY&&process.stdout.isTTY)}function y(e){let t=e[1];return e[0]!==`dev`||e.length!==2||t===void 0||t.startsWith(`-`)?[...e]:[`dev`,`--url`,t]}function b(e){if(e.url){if(e.host!==void 0)throw new r(`The --host option cannot be used with --url.`);if(e.port!==void 0)throw new r(`The --port option cannot be used with --url.`);if(e.repl===!1)throw new r(`The --no-repl option cannot be used with --url.`);return e.url}}function x(r,a){let s=p(),y=e().version,x=new i,S=t();return x.name(`ash`).description(`Build and run an Ash application.`).version(y).showHelpAfterError().exitOverride().hook(`preAction`,(e,t)=>{h(t)&&r.log(m(y))}).configureOutput({writeErr:e=>{r.error(e.trimEnd())},writeOut:e=>{r.log(e.trimEnd())}}),x.command(`build`).description(`Build the current Ash application.`).action(async()=>{let{loadDevelopmentEnvironmentFiles:e}=await import(`./dev/environment.js`);e(s);let t=await(a.buildHost??await c())(s);r.log(n(S,{message:`built output at ${t}`,tag:`build`,tone:`success`}))}),x.command(`dev`).description(`Start the Ash development server or connect the REPL to an existing URL.`).option(`--host <host>`,`Host interface to bind`).option(`--no-repl`,`Start the server without the interactive REPL`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 3000)`,_).option(`--schedules`,`Run scheduled tasks during development (off by default)`).option(`-u, --url <url>`,`Connect the REPL to an existing server URL`,o).addHelpText(`after`,`
|
|
2
2
|
You can also pass a bare URL as the only argument, for example: ash dev https://example.com
|
|
3
3
|
`).action(async e=>{let t=b(e),{loadDevelopmentEnvironmentFiles:i}=await import(`./dev/environment.js`);if(i(s),t){if(r.log(n(S,{message:`REPL connecting to ${t}`,tag:`dev`,tone:`info`})),!v()){r.log(n(S,{message:`Interactive REPL disabled because the current terminal is not a TTY.`,tag:`dev`,tone:`warning`}));return}r.log(``),await(a.runDevelopmentRepl??await u())({serverUrl:t});return}let o=await(a.startHost??await f())(s,{host:e.host,port:e.port,schedules:e.schedules===!0}),c=!1,l=async()=>{c||(c=!0,await o.close())};try{if(r.log(n(S,{message:`server listening at ${o.url}`,tag:`dev`,tone:`success`})),e.repl===!1)return await g({close:l});if(!v())return r.log(n(S,{message:`Interactive REPL disabled because the current terminal is not a TTY.`,tag:`dev`,tone:`warning`})),await g({close:l});r.log(``),await(a.runDevelopmentRepl??await u())({serverUrl:o.url})}finally{await l()}}),x.command(`info`).description(`Print resolved application information.`).action(async()=>{await(a.printApplicationInfo??await l())(r,s)}),x.command(`eval`).description(`Run eval suites against an Ash agent.`).option(`--suite <id...>`,`Suite IDs to run (repeatable)`).option(`--all`,`Run all discovered suites`).option(`--url <url>`,`Remote agent URL (skip local host startup)`).option(`--timeout <ms>`,`Per-case timeout in milliseconds`).option(`--max-concurrency <n>`,`Max concurrent case executions per suite`).option(`--json`,`Output results as JSON`).option(`--list-suites`,`List discovered suites and exit`).option(`--skip-report`,`Skip suite-defined reporters (e.g. Braintrust)`).action(async e=>{await(a.runEvalCommand??await d())(e,r)}),x}async function S(e=process.argv.slice(2),t=console,n={}){let r=x(t,n),i=e.length===0?[`info`]:y(e);try{await r.parseAsync(i,{from:`user`})}catch(e){if(e instanceof a){if(e.exitCode===0)return;throw Error(e.message)}throw e}}export{S as runCli};
|
|
@@ -314,9 +314,37 @@ export function createToolLoopHarness(config) {
|
|
|
314
314
|
* `console.error(error)` handler inside `streamText`. Errors are
|
|
315
315
|
* handled by the harness catch block and emitted as stream events.
|
|
316
316
|
*/
|
|
317
|
+
// Hydrate `ash-sandbox:` ref FileParts into inline bytes for the
|
|
318
|
+
// model call only. The result is transient — `messages` itself
|
|
319
|
+
// remains ref-only so it can flow into `session.history` without
|
|
320
|
+
// bloating every future step boundary.
|
|
321
|
+
const hydratedMessages = await hydrateSandboxAttachments(messages);
|
|
322
|
+
const ephemeralContext = stepInput.input?.modelContext;
|
|
323
|
+
// AI SDK rejects role:"system" in `messages` — route those entries
|
|
324
|
+
// to `instructions` instead.
|
|
325
|
+
const systemMessages = [];
|
|
326
|
+
const nonSystemMessages = [];
|
|
327
|
+
if (ephemeralContext !== undefined) {
|
|
328
|
+
for (const entry of ephemeralContext) {
|
|
329
|
+
if (entry.role === "system") {
|
|
330
|
+
systemMessages.push(entry);
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
nonSystemMessages.push(entry);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
const instructions = systemMessages.length > 0
|
|
338
|
+
? [
|
|
339
|
+
...(session.agent.system
|
|
340
|
+
? [{ role: "system", content: session.agent.system }]
|
|
341
|
+
: []),
|
|
342
|
+
...systemMessages,
|
|
343
|
+
]
|
|
344
|
+
: session.agent.system || undefined;
|
|
317
345
|
const agentSettings = {
|
|
318
346
|
headers: attributionHeaders,
|
|
319
|
-
instructions
|
|
347
|
+
instructions,
|
|
320
348
|
model,
|
|
321
349
|
onError() { },
|
|
322
350
|
onStepFinish: hooks.onStepFinish,
|
|
@@ -327,18 +355,7 @@ export function createToolLoopHarness(config) {
|
|
|
327
355
|
tools: effectiveTools,
|
|
328
356
|
};
|
|
329
357
|
const agent = new ToolLoopAgent(agentSettings);
|
|
330
|
-
|
|
331
|
-
// model call only. The result is transient — `messages` itself
|
|
332
|
-
// remains ref-only so it can flow into `session.history` without
|
|
333
|
-
// bloating every future step boundary.
|
|
334
|
-
const hydratedMessages = await hydrateSandboxAttachments(messages);
|
|
335
|
-
// Append ephemeral `lifecycle.{session,turn}` modelContext to the
|
|
336
|
-
// model call's message list. modelContext is one-shot per turn and
|
|
337
|
-
// never written back to `session.history`.
|
|
338
|
-
const ephemeralContext = stepInput.input?.modelContext;
|
|
339
|
-
const modelMessages = ephemeralContext !== undefined && ephemeralContext.length > 0
|
|
340
|
-
? [...hydratedMessages, ...ephemeralContext]
|
|
341
|
-
: hydratedMessages;
|
|
358
|
+
const modelMessages = nonSystemMessages.length > 0 ? [...hydratedMessages, ...nonSystemMessages] : hydratedMessages;
|
|
342
359
|
let result;
|
|
343
360
|
const executeModelCall = async () => {
|
|
344
361
|
if (emit) {
|
|
@@ -6,7 +6,7 @@ import { ASH_PACKAGE_NAME } from "#package-name.js";
|
|
|
6
6
|
let cachedPackageInfo;
|
|
7
7
|
// The package build stamps the published version into `dist` so bundled
|
|
8
8
|
// deployments can still report package metadata without resolving package.json.
|
|
9
|
-
const BUNDLED_FALLBACK_PACKAGE_VERSION = "0.7.
|
|
9
|
+
const BUNDLED_FALLBACK_PACKAGE_VERSION = "0.7.6";
|
|
10
10
|
const BUNDLED_FALLBACK_PACKAGE_VERSION_PLACEHOLDER = "__ASH_PACKAGE_VERSION_PLACEHOLDER__";
|
|
11
11
|
const WORKFLOW_MODULE_ALIASES = {
|
|
12
12
|
"workflow/api": "src/compiled/@workflow/core/runtime.js",
|