@hasna/testers 0.0.34 → 0.0.36
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/dist/cli/index.js +1224 -1063
- package/dist/db/workflows.d.ts.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +989 -214
- package/dist/lib/ai-client.d.ts +10 -2
- package/dist/lib/ai-client.d.ts.map +1 -1
- package/dist/lib/assertions.d.ts +4 -1
- package/dist/lib/assertions.d.ts.map +1 -1
- package/dist/lib/browser-compat.d.ts +14 -0
- package/dist/lib/browser-compat.d.ts.map +1 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/crawl-and-generate.d.ts +1 -1
- package/dist/lib/crawl-and-generate.d.ts.map +1 -1
- package/dist/lib/generator.d.ts.map +1 -1
- package/dist/lib/healer.d.ts.map +1 -1
- package/dist/lib/hybrid-runner.d.ts.map +1 -1
- package/dist/lib/judge.d.ts +3 -3
- package/dist/lib/judge.d.ts.map +1 -1
- package/dist/lib/repo-discovery.d.ts.map +1 -1
- package/dist/lib/repo-executor.d.ts.map +1 -1
- package/dist/lib/runner.d.ts +30 -1
- package/dist/lib/runner.d.ts.map +1 -1
- package/dist/lib/session-converter.d.ts.map +1 -1
- package/dist/lib/workflow-runner.d.ts +73 -5
- package/dist/lib/workflow-runner.d.ts.map +1 -1
- package/dist/mcp/http.d.ts +1 -1
- package/dist/mcp/index.js +1016 -851
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/sdk/index.d.ts +3 -3
- package/dist/sdk/index.d.ts.map +1 -1
- package/dist/server/index.js +942 -609
- package/dist/types/index.d.ts +23 -3
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +7 -6
package/dist/mcp/index.js
CHANGED
|
@@ -52,7 +52,7 @@ var package_default;
|
|
|
52
52
|
var init_package = __esm(() => {
|
|
53
53
|
package_default = {
|
|
54
54
|
name: "@hasna/testers",
|
|
55
|
-
version: "0.0.
|
|
55
|
+
version: "0.0.36",
|
|
56
56
|
description: "AI-powered QA testing CLI \u2014 spawns cheap AI agents to test web apps with headless browsers",
|
|
57
57
|
type: "module",
|
|
58
58
|
main: "dist/index.js",
|
|
@@ -76,10 +76,10 @@ var init_package = __esm(() => {
|
|
|
76
76
|
],
|
|
77
77
|
scripts: {
|
|
78
78
|
build: "bun run build:dashboard && bun run build:cli && bun run build:mcp && bun run build:server && bun run build:lib && bun run build:types",
|
|
79
|
-
"build:cli": "bun build src/cli/index.tsx --outdir dist/cli --target bun --external ink --external react --external chalk --external @modelcontextprotocol/sdk --external @anthropic-ai/sdk --external playwright --external @hasna/browser",
|
|
80
|
-
"build:mcp": "bun build src/mcp/index.ts --outdir dist/mcp --target bun --external @modelcontextprotocol/sdk --external @anthropic-ai/sdk --external playwright --external @hasna/browser",
|
|
81
|
-
"build:server": "bun build src/server/index.ts --outdir dist/server --target bun --external @anthropic-ai/sdk --external playwright --external @hasna/browser",
|
|
82
|
-
"build:lib": "bun build src/index.ts --outdir dist --target bun --external playwright --external @anthropic-ai/sdk --external @modelcontextprotocol/sdk --external @hasna/browser",
|
|
79
|
+
"build:cli": "bun build src/cli/index.tsx --outdir dist/cli --target bun --external ink --external react --external chalk --external @modelcontextprotocol/sdk --external @anthropic-ai/sdk --external playwright --external @hasna/browser --external @hasna/sandboxes",
|
|
80
|
+
"build:mcp": "bun build src/mcp/index.ts --outdir dist/mcp --target bun --external @modelcontextprotocol/sdk --external @anthropic-ai/sdk --external playwright --external @hasna/browser --external @hasna/sandboxes",
|
|
81
|
+
"build:server": "bun build src/server/index.ts --outdir dist/server --target bun --external @anthropic-ai/sdk --external playwright --external @hasna/browser --external @hasna/sandboxes",
|
|
82
|
+
"build:lib": "bun build src/index.ts --outdir dist --target bun --external playwright --external @anthropic-ai/sdk --external @modelcontextprotocol/sdk --external @hasna/browser --external @hasna/sandboxes",
|
|
83
83
|
"build:types": "NODE_OPTIONS='--max-old-space-size=8192' tsc --emitDeclarationOnly --outDir dist --skipLibCheck || true",
|
|
84
84
|
"build:dashboard": "cd dashboard && bun run build",
|
|
85
85
|
"build:ext": "cd extension && bun run build",
|
|
@@ -93,10 +93,11 @@ var init_package = __esm(() => {
|
|
|
93
93
|
},
|
|
94
94
|
dependencies: {
|
|
95
95
|
"@anthropic-ai/sdk": "^0.52.0",
|
|
96
|
-
"@hasna/browser": "^0.4.
|
|
96
|
+
"@hasna/browser": "^0.4.12",
|
|
97
97
|
"@hasna/cloud": "^0.1.24",
|
|
98
98
|
"@hasna/contacts": "^0.6.8",
|
|
99
99
|
"@hasna/projects": "^0.1.42",
|
|
100
|
+
"@hasna/sandboxes": "^0.1.27",
|
|
100
101
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
101
102
|
ai: "^6.0.175",
|
|
102
103
|
chalk: "^5.4.1",
|
|
@@ -5399,9 +5400,9 @@ async function syncTransfer(source, target, options, _direction) {
|
|
|
5399
5400
|
const batch = rows.slice(offset, offset + batchSize);
|
|
5400
5401
|
try {
|
|
5401
5402
|
if (isAsyncAdapter(target)) {
|
|
5402
|
-
await batchUpsertPg(target, table, columns, updateCols, pkColumns, batch
|
|
5403
|
+
await batchUpsertPg(target, table, columns, updateCols, pkColumns, batch);
|
|
5403
5404
|
} else {
|
|
5404
|
-
batchUpsertSqlite(target, table, columns, updateCols, pkColumns, batch
|
|
5405
|
+
batchUpsertSqlite(target, table, columns, updateCols, pkColumns, batch);
|
|
5405
5406
|
}
|
|
5406
5407
|
result.rowsWritten += batch.length;
|
|
5407
5408
|
} catch (err) {
|
|
@@ -5448,7 +5449,7 @@ async function syncTransfer(source, target, options, _direction) {
|
|
|
5448
5449
|
}
|
|
5449
5450
|
return results;
|
|
5450
5451
|
}
|
|
5451
|
-
async function batchUpsertPg(target, table, columns, updateCols, primaryKeys, batch
|
|
5452
|
+
async function batchUpsertPg(target, table, columns, updateCols, primaryKeys, batch) {
|
|
5452
5453
|
if (batch.length === 0)
|
|
5453
5454
|
return;
|
|
5454
5455
|
const colList = columns.map((c) => `"${c}"`).join(", ");
|
|
@@ -5458,22 +5459,20 @@ async function batchUpsertPg(target, table, columns, updateCols, primaryKeys, ba
|
|
|
5458
5459
|
}).join(", ");
|
|
5459
5460
|
const pkList = primaryKeys.map((c) => `"${c}"`).join(", ");
|
|
5460
5461
|
const setClause = updateCols.length > 0 ? updateCols.map((c) => `"${c}" = EXCLUDED."${c}"`).join(", ") : `"${primaryKeys[0]}" = EXCLUDED."${primaryKeys[0]}"`;
|
|
5461
|
-
const whereClause = conflictColumn && updateCols.includes(conflictColumn) ? ` WHERE "${table}"."${conflictColumn}" IS NULL OR EXCLUDED."${conflictColumn}" >= "${table}"."${conflictColumn}"` : "";
|
|
5462
5462
|
const sql = `INSERT INTO "${table}" (${colList}) VALUES ${valuePlaceholders}
|
|
5463
|
-
ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}
|
|
5463
|
+
ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}`;
|
|
5464
5464
|
const params = batch.flatMap((row) => columns.map((c) => row[c] ?? null));
|
|
5465
5465
|
await target.run(sql, ...params);
|
|
5466
5466
|
}
|
|
5467
|
-
function batchUpsertSqlite(target, table, columns, updateCols, primaryKeys, batch
|
|
5467
|
+
function batchUpsertSqlite(target, table, columns, updateCols, primaryKeys, batch) {
|
|
5468
5468
|
if (batch.length === 0)
|
|
5469
5469
|
return;
|
|
5470
5470
|
const colList = columns.map((c) => `"${c}"`).join(", ");
|
|
5471
5471
|
const valuePlaceholders = batch.map(() => `(${columns.map(() => "?").join(", ")})`).join(", ");
|
|
5472
5472
|
const pkList = primaryKeys.map((c) => `"${c}"`).join(", ");
|
|
5473
5473
|
const setClause = updateCols.length > 0 ? updateCols.map((c) => `"${c}" = EXCLUDED."${c}"`).join(", ") : `"${primaryKeys[0]}" = EXCLUDED."${primaryKeys[0]}"`;
|
|
5474
|
-
const whereClause = conflictColumn && updateCols.includes(conflictColumn) ? ` WHERE "${table}"."${conflictColumn}" IS NULL OR EXCLUDED."${conflictColumn}" >= "${table}"."${conflictColumn}"` : "";
|
|
5475
5474
|
const sql = `INSERT INTO "${table}" (${colList}) VALUES ${valuePlaceholders}
|
|
5476
|
-
ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}
|
|
5475
|
+
ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}`;
|
|
5477
5476
|
const params = batch.flatMap((row) => columns.map((c) => coerceForSqlite(row[c])));
|
|
5478
5477
|
target.run(sql, ...params);
|
|
5479
5478
|
}
|
|
@@ -5698,7 +5697,7 @@ class SyncProgressTracker {
|
|
|
5698
5697
|
}
|
|
5699
5698
|
}
|
|
5700
5699
|
}
|
|
5701
|
-
function registerCloudTools(server, serviceName
|
|
5700
|
+
function registerCloudTools(server, serviceName) {
|
|
5702
5701
|
server.tool(`${serviceName}_cloud_status`, "Show cloud configuration and connection health", {}, async () => {
|
|
5703
5702
|
const config = getCloudConfig();
|
|
5704
5703
|
const lines = [
|
|
@@ -5731,13 +5730,8 @@ function registerCloudTools(server, serviceName, opts = {}) {
|
|
|
5731
5730
|
isError: true
|
|
5732
5731
|
};
|
|
5733
5732
|
}
|
|
5734
|
-
const local = new SqliteAdapter(
|
|
5733
|
+
const local = new SqliteAdapter(getDbPath(serviceName));
|
|
5735
5734
|
const cloud = new PgAdapterAsync(getConnectionString(serviceName));
|
|
5736
|
-
if (opts.migrations?.length) {
|
|
5737
|
-
for (const sql of opts.migrations) {
|
|
5738
|
-
await cloud.run(sql);
|
|
5739
|
-
}
|
|
5740
|
-
}
|
|
5741
5735
|
const tableList = tablesStr ? tablesStr.split(",").map((t) => t.trim()) : listSqliteTables(local);
|
|
5742
5736
|
const results = await syncPush(local, cloud, { tables: tableList });
|
|
5743
5737
|
local.close();
|
|
@@ -5759,7 +5753,7 @@ function registerCloudTools(server, serviceName, opts = {}) {
|
|
|
5759
5753
|
isError: true
|
|
5760
5754
|
};
|
|
5761
5755
|
}
|
|
5762
|
-
const local = new SqliteAdapter(
|
|
5756
|
+
const local = new SqliteAdapter(getDbPath(serviceName));
|
|
5763
5757
|
const cloud = new PgAdapterAsync(getConnectionString(serviceName));
|
|
5764
5758
|
let tableList;
|
|
5765
5759
|
if (tablesStr) {
|
|
@@ -14141,6 +14135,56 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
|
|
|
14141
14135
|
});
|
|
14142
14136
|
|
|
14143
14137
|
// src/types/index.ts
|
|
14138
|
+
function isRecord(value) {
|
|
14139
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14140
|
+
}
|
|
14141
|
+
function stringValue(value) {
|
|
14142
|
+
return typeof value === "string" && value.trim() ? value : undefined;
|
|
14143
|
+
}
|
|
14144
|
+
function numberValue(value) {
|
|
14145
|
+
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
14146
|
+
}
|
|
14147
|
+
function stringMap(value) {
|
|
14148
|
+
if (!isRecord(value))
|
|
14149
|
+
return;
|
|
14150
|
+
const entries = Object.entries(value).filter((entry) => typeof entry[1] === "string");
|
|
14151
|
+
return entries.length > 0 ? Object.fromEntries(entries) : undefined;
|
|
14152
|
+
}
|
|
14153
|
+
function cleanupValue(value) {
|
|
14154
|
+
if (value === "delete" || value === "stop" || value === "keep")
|
|
14155
|
+
return value;
|
|
14156
|
+
return;
|
|
14157
|
+
}
|
|
14158
|
+
function workflowExecutionFromValue(value) {
|
|
14159
|
+
const input = isRecord(value) ? value : {};
|
|
14160
|
+
const rawTarget = stringValue(input["target"]) ?? "local";
|
|
14161
|
+
if (rawTarget === "local") {
|
|
14162
|
+
const timeoutMs2 = numberValue(input["timeoutMs"]);
|
|
14163
|
+
return timeoutMs2 === undefined ? { target: "local" } : { target: "local", timeoutMs: timeoutMs2 };
|
|
14164
|
+
}
|
|
14165
|
+
if (rawTarget !== "sandbox" && rawTarget !== "connector:e2b") {
|
|
14166
|
+
throw new Error(`Unsupported workflow execution target: ${rawTarget}`);
|
|
14167
|
+
}
|
|
14168
|
+
const provider = rawTarget === "connector:e2b" ? "e2b" : stringValue(input["provider"]) ?? stringValue(input["connector"]);
|
|
14169
|
+
const sandboxImage = stringValue(input["sandboxImage"]) ?? stringValue(input["sandboxTemplate"]);
|
|
14170
|
+
const sandboxRemoteDir = stringValue(input["sandboxRemoteDir"]);
|
|
14171
|
+
const sandboxCleanup = cleanupValue(input["sandboxCleanup"]);
|
|
14172
|
+
const setupCommand = stringValue(input["setupCommand"]);
|
|
14173
|
+
const packageSpec = stringValue(input["packageSpec"]);
|
|
14174
|
+
const timeoutMs = numberValue(input["timeoutMs"]);
|
|
14175
|
+
const env = stringMap(input["env"]);
|
|
14176
|
+
return {
|
|
14177
|
+
target: "sandbox",
|
|
14178
|
+
...provider ? { provider } : {},
|
|
14179
|
+
...sandboxImage ? { sandboxImage } : {},
|
|
14180
|
+
...sandboxRemoteDir ? { sandboxRemoteDir } : {},
|
|
14181
|
+
...sandboxCleanup ? { sandboxCleanup } : {},
|
|
14182
|
+
...setupCommand ? { setupCommand } : {},
|
|
14183
|
+
...packageSpec ? { packageSpec } : {},
|
|
14184
|
+
...timeoutMs !== undefined ? { timeoutMs } : {},
|
|
14185
|
+
...env ? { env } : {}
|
|
14186
|
+
};
|
|
14187
|
+
}
|
|
14144
14188
|
function workflowFromRow(row) {
|
|
14145
14189
|
return {
|
|
14146
14190
|
id: row.id,
|
|
@@ -14150,7 +14194,7 @@ function workflowFromRow(row) {
|
|
|
14150
14194
|
scenarioFilter: JSON.parse(row.scenario_filter || "{}"),
|
|
14151
14195
|
personaIds: JSON.parse(row.persona_ids || "[]"),
|
|
14152
14196
|
goal: row.goal ? JSON.parse(row.goal) : null,
|
|
14153
|
-
execution: JSON.parse(row.execution || '{"target":"local"}'),
|
|
14197
|
+
execution: workflowExecutionFromValue(JSON.parse(row.execution || '{"target":"local"}')),
|
|
14154
14198
|
settings: JSON.parse(row.settings || "{}"),
|
|
14155
14199
|
enabled: row.enabled === 1,
|
|
14156
14200
|
createdAt: row.created_at,
|
|
@@ -16556,6 +16600,10 @@ function loadConfig() {
|
|
|
16556
16600
|
if (envApiKey) {
|
|
16557
16601
|
config.anthropicApiKey = envApiKey;
|
|
16558
16602
|
}
|
|
16603
|
+
const envSelfHeal = process.env["TESTERS_SELF_HEAL"];
|
|
16604
|
+
if (envSelfHeal !== undefined) {
|
|
16605
|
+
config.selfHeal = ["1", "true", "yes", "on"].includes(envSelfHeal.toLowerCase());
|
|
16606
|
+
}
|
|
16559
16607
|
return config;
|
|
16560
16608
|
}
|
|
16561
16609
|
function resolveModel(nameOrId) {
|
|
@@ -16598,12 +16646,11 @@ Original selector that failed: "${request.failedSelector}"
|
|
|
16598
16646
|
Please identify the correct selector from the screenshot.`;
|
|
16599
16647
|
let rawResponse = "";
|
|
16600
16648
|
try {
|
|
16601
|
-
if (provider
|
|
16602
|
-
const
|
|
16603
|
-
const apiKey = provider === "openai" ? process.env["OPENAI_API_KEY"] ?? "" : process.env["GOOGLE_API_KEY"] ?? "";
|
|
16649
|
+
if (provider !== "anthropic") {
|
|
16650
|
+
const compat = createOpenAICompatibleConfig(provider);
|
|
16604
16651
|
const resp = await callOpenAICompatible({
|
|
16605
|
-
baseUrl,
|
|
16606
|
-
apiKey,
|
|
16652
|
+
baseUrl: compat.baseUrl,
|
|
16653
|
+
apiKey: compat.apiKey,
|
|
16607
16654
|
model,
|
|
16608
16655
|
system: HEAL_SYSTEM,
|
|
16609
16656
|
messages: [{ role: "user", content: userMessage }],
|
|
@@ -16697,12 +16744,15 @@ var init_healer = __esm(() => {
|
|
|
16697
16744
|
var exports_ai_client = {};
|
|
16698
16745
|
__export(exports_ai_client, {
|
|
16699
16746
|
runAgentLoop: () => runAgentLoop,
|
|
16747
|
+
resolveProviderApiKeyForModel: () => resolveProviderApiKeyForModel,
|
|
16700
16748
|
resolveModel: () => resolveModel2,
|
|
16701
16749
|
executeTool: () => executeTool,
|
|
16702
16750
|
detectProvider: () => detectProvider,
|
|
16751
|
+
createOpenAICompatibleConfig: () => createOpenAICompatibleConfig,
|
|
16703
16752
|
createClientForModel: () => createClientForModel,
|
|
16704
16753
|
createClient: () => createClient,
|
|
16705
16754
|
callOpenAICompatible: () => callOpenAICompatible,
|
|
16755
|
+
buildScenarioUserMessage: () => buildScenarioUserMessage,
|
|
16706
16756
|
BROWSER_TOOLS: () => BROWSER_TOOLS
|
|
16707
16757
|
});
|
|
16708
16758
|
import Anthropic2 from "@anthropic-ai/sdk";
|
|
@@ -17115,7 +17165,6 @@ async function executeTool(page, screenshotter, toolName, toolInput, context) {
|
|
|
17115
17165
|
const assertionType = toolInput.assertion_type;
|
|
17116
17166
|
const selector = toolInput.selector;
|
|
17117
17167
|
const expected = toolInput.expected;
|
|
17118
|
-
const sessionId = context.sessionId ?? "default";
|
|
17119
17168
|
switch (assertionType) {
|
|
17120
17169
|
case "element_exists": {
|
|
17121
17170
|
if (!selector)
|
|
@@ -17180,7 +17229,6 @@ async function executeTool(page, screenshotter, toolName, toolInput, context) {
|
|
|
17180
17229
|
case "browser_intercept": {
|
|
17181
17230
|
const action = toolInput.action;
|
|
17182
17231
|
const pattern = toolInput.pattern;
|
|
17183
|
-
const interceptAction = toolInput.intercept_action;
|
|
17184
17232
|
const statusCode = toolInput.status_code;
|
|
17185
17233
|
const body = toolInput.body;
|
|
17186
17234
|
const sessionId = context.sessionId ?? "default";
|
|
@@ -17257,7 +17305,28 @@ ${JSON.stringify(har, null, 2)}` };
|
|
|
17257
17305
|
}
|
|
17258
17306
|
case "browser_a11y": {
|
|
17259
17307
|
const level = toolInput.level ?? "AA";
|
|
17260
|
-
const snapshot = await page.
|
|
17308
|
+
const snapshot = await page.evaluate(() => {
|
|
17309
|
+
function readRole(el) {
|
|
17310
|
+
return el.getAttribute("role") ?? el.tagName.toLowerCase();
|
|
17311
|
+
}
|
|
17312
|
+
function readName(el) {
|
|
17313
|
+
const labelledBy = el.getAttribute("aria-labelledby");
|
|
17314
|
+
if (labelledBy) {
|
|
17315
|
+
const labelledText = labelledBy.split(/\s+/).map((id) => document.getElementById(id)?.textContent?.trim()).filter(Boolean).join(" ");
|
|
17316
|
+
if (labelledText)
|
|
17317
|
+
return labelledText;
|
|
17318
|
+
}
|
|
17319
|
+
return el.getAttribute("aria-label") ?? el.getAttribute("alt") ?? el.textContent?.trim() ?? "";
|
|
17320
|
+
}
|
|
17321
|
+
function walk(el) {
|
|
17322
|
+
return {
|
|
17323
|
+
role: readRole(el),
|
|
17324
|
+
name: readName(el),
|
|
17325
|
+
children: Array.from(el.children).map((child) => walk(child))
|
|
17326
|
+
};
|
|
17327
|
+
}
|
|
17328
|
+
return document.body ? walk(document.body) : null;
|
|
17329
|
+
});
|
|
17261
17330
|
if (!snapshot)
|
|
17262
17331
|
return { result: "Error: could not capture accessibility tree" };
|
|
17263
17332
|
const issues = [];
|
|
@@ -17299,6 +17368,38 @@ ${filtered.join(`
|
|
|
17299
17368
|
return { result: `Error executing ${toolName}: ${message}` };
|
|
17300
17369
|
}
|
|
17301
17370
|
}
|
|
17371
|
+
function resolveStartUrl(baseUrl, targetPath) {
|
|
17372
|
+
try {
|
|
17373
|
+
return new URL(targetPath, baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`).toString();
|
|
17374
|
+
} catch {
|
|
17375
|
+
return `${baseUrl.replace(/\/+$/, "")}/${targetPath.replace(/^\/+/, "")}`;
|
|
17376
|
+
}
|
|
17377
|
+
}
|
|
17378
|
+
function buildScenarioUserMessage(scenario, baseUrl) {
|
|
17379
|
+
const userParts = [
|
|
17380
|
+
`**Scenario:** ${scenario.name}`,
|
|
17381
|
+
`**Description:** ${scenario.description}`
|
|
17382
|
+
];
|
|
17383
|
+
if (baseUrl) {
|
|
17384
|
+
const normalizedBaseUrl = baseUrl.replace(/\/+$/, "");
|
|
17385
|
+
userParts.push(`**Base URL:** ${normalizedBaseUrl}`);
|
|
17386
|
+
if (scenario.targetPath) {
|
|
17387
|
+
userParts.push(`**Start URL:** ${resolveStartUrl(normalizedBaseUrl, scenario.targetPath)}`);
|
|
17388
|
+
}
|
|
17389
|
+
userParts.push("**Navigation Boundary:** Treat the Base URL as the application under test. Resolve relative paths and in-app navigation against this origin. Do not navigate to another host unless a step explicitly includes an absolute external URL.");
|
|
17390
|
+
}
|
|
17391
|
+
if (scenario.targetPath) {
|
|
17392
|
+
userParts.push(`**Target Path:** ${scenario.targetPath}`);
|
|
17393
|
+
}
|
|
17394
|
+
if (scenario.steps.length > 0) {
|
|
17395
|
+
userParts.push("**Steps:**");
|
|
17396
|
+
for (let i = 0;i < scenario.steps.length; i++) {
|
|
17397
|
+
userParts.push(`${i + 1}. ${scenario.steps[i]}`);
|
|
17398
|
+
}
|
|
17399
|
+
}
|
|
17400
|
+
return userParts.join(`
|
|
17401
|
+
`);
|
|
17402
|
+
}
|
|
17302
17403
|
async function runAgentLoop(options) {
|
|
17303
17404
|
const {
|
|
17304
17405
|
client,
|
|
@@ -17308,6 +17409,7 @@ async function runAgentLoop(options) {
|
|
|
17308
17409
|
model,
|
|
17309
17410
|
runId,
|
|
17310
17411
|
sessionId,
|
|
17412
|
+
baseUrl,
|
|
17311
17413
|
maxTurns = 30,
|
|
17312
17414
|
onStep,
|
|
17313
17415
|
persona,
|
|
@@ -17355,21 +17457,7 @@ Instructions: ${persona.instructions}` : "",
|
|
|
17355
17457
|
"- Verify both positive and negative states"
|
|
17356
17458
|
].join(`
|
|
17357
17459
|
`) + personaSection;
|
|
17358
|
-
const
|
|
17359
|
-
`**Scenario:** ${scenario.name}`,
|
|
17360
|
-
`**Description:** ${scenario.description}`
|
|
17361
|
-
];
|
|
17362
|
-
if (scenario.targetPath) {
|
|
17363
|
-
userParts.push(`**Target Path:** ${scenario.targetPath}`);
|
|
17364
|
-
}
|
|
17365
|
-
if (scenario.steps.length > 0) {
|
|
17366
|
-
userParts.push("**Steps:**");
|
|
17367
|
-
for (let i = 0;i < scenario.steps.length; i++) {
|
|
17368
|
-
userParts.push(`${i + 1}. ${scenario.steps[i]}`);
|
|
17369
|
-
}
|
|
17370
|
-
}
|
|
17371
|
-
const userMessage = userParts.join(`
|
|
17372
|
-
`);
|
|
17460
|
+
const userMessage = buildScenarioUserMessage(scenario, baseUrl);
|
|
17373
17461
|
const screenshots = [];
|
|
17374
17462
|
let tokensUsed = 0;
|
|
17375
17463
|
let stepNumber = 0;
|
|
@@ -17432,7 +17520,7 @@ Instructions: ${persona.instructions}` : "",
|
|
|
17432
17520
|
if (onStep) {
|
|
17433
17521
|
onStep({ type: "tool_call", toolName: toolBlock.name, toolInput, stepNumber });
|
|
17434
17522
|
}
|
|
17435
|
-
const execResult = await executeTool(page, screenshotter, toolBlock.name, toolInput, { runId, scenarioSlug, stepNumber, sessionId, a11y });
|
|
17523
|
+
const execResult = await executeTool(page, screenshotter, toolBlock.name, toolInput, { runId, scenarioSlug, stepNumber, sessionId: sessionId ?? runId, a11y });
|
|
17436
17524
|
if (onStep) {
|
|
17437
17525
|
onStep({ type: "tool_result", toolName: toolBlock.name, toolResult: execResult.result, stepNumber });
|
|
17438
17526
|
}
|
|
@@ -17483,10 +17571,17 @@ function detectProvider(model) {
|
|
|
17483
17571
|
return "openai";
|
|
17484
17572
|
if (model.startsWith("gemini-"))
|
|
17485
17573
|
return "google";
|
|
17574
|
+
if (model.startsWith("glm-") || model.startsWith("zai/") || model.startsWith("zai-"))
|
|
17575
|
+
return "zai";
|
|
17486
17576
|
if (model.startsWith("llama-") || model.startsWith("qwen-") || model.includes("cerebras"))
|
|
17487
17577
|
return "cerebras";
|
|
17488
17578
|
return "anthropic";
|
|
17489
17579
|
}
|
|
17580
|
+
function resolveProviderApiKeyForModel(model, explicitApiKey, configuredAnthropicApiKey) {
|
|
17581
|
+
if (explicitApiKey)
|
|
17582
|
+
return explicitApiKey;
|
|
17583
|
+
return detectProvider(model) === "anthropic" ? configuredAnthropicApiKey : undefined;
|
|
17584
|
+
}
|
|
17490
17585
|
function createClient(apiKey) {
|
|
17491
17586
|
const key = apiKey ?? process.env["ANTHROPIC_API_KEY"];
|
|
17492
17587
|
if (!key) {
|
|
@@ -17564,26 +17659,34 @@ async function callOpenAICompatible(options) {
|
|
|
17564
17659
|
const usage = { input_tokens: data.usage?.prompt_tokens ?? 0, output_tokens: data.usage?.completion_tokens ?? 0 };
|
|
17565
17660
|
return { content, stop_reason: stopReason, usage };
|
|
17566
17661
|
}
|
|
17567
|
-
function
|
|
17568
|
-
const provider = detectProvider(model);
|
|
17662
|
+
function createOpenAICompatibleConfig(provider, apiKey) {
|
|
17569
17663
|
if (provider === "openai") {
|
|
17570
|
-
const
|
|
17571
|
-
if (!
|
|
17664
|
+
const key2 = apiKey ?? process.env["OPENAI_API_KEY"];
|
|
17665
|
+
if (!key2)
|
|
17572
17666
|
throw new AIClientError("No OpenAI API key. Set OPENAI_API_KEY or pass it explicitly.");
|
|
17573
|
-
return { provider: "openai", baseUrl: "https://api.openai.com/v1", apiKey:
|
|
17667
|
+
return { provider: "openai", baseUrl: "https://api.openai.com/v1", apiKey: key2 };
|
|
17574
17668
|
}
|
|
17575
17669
|
if (provider === "google") {
|
|
17576
|
-
const
|
|
17577
|
-
if (!
|
|
17670
|
+
const key2 = apiKey ?? process.env["GOOGLE_API_KEY"];
|
|
17671
|
+
if (!key2)
|
|
17578
17672
|
throw new AIClientError("No Google API key. Set GOOGLE_API_KEY or pass it explicitly.");
|
|
17579
|
-
return { provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta/openai", apiKey:
|
|
17673
|
+
return { provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta/openai", apiKey: key2 };
|
|
17580
17674
|
}
|
|
17581
17675
|
if (provider === "cerebras") {
|
|
17582
|
-
const
|
|
17583
|
-
if (!
|
|
17676
|
+
const key2 = apiKey ?? process.env["CEREBRAS_API_KEY"];
|
|
17677
|
+
if (!key2)
|
|
17584
17678
|
throw new AIClientError("No Cerebras API key. Set CEREBRAS_API_KEY or pass it explicitly.");
|
|
17585
|
-
return { provider: "cerebras", baseUrl: "https://api.cerebras.ai/v1", apiKey:
|
|
17679
|
+
return { provider: "cerebras", baseUrl: "https://api.cerebras.ai/v1", apiKey: key2 };
|
|
17586
17680
|
}
|
|
17681
|
+
const key = apiKey ?? process.env["ZAI_API_KEY"];
|
|
17682
|
+
if (!key)
|
|
17683
|
+
throw new AIClientError("No Z.AI API key. Set ZAI_API_KEY or pass it explicitly.");
|
|
17684
|
+
return { provider: "zai", baseUrl: "https://api.z.ai/api/paas/v4", apiKey: key };
|
|
17685
|
+
}
|
|
17686
|
+
function createClientForModel(model, apiKey) {
|
|
17687
|
+
const provider = detectProvider(model);
|
|
17688
|
+
if (provider !== "anthropic")
|
|
17689
|
+
return createOpenAICompatibleConfig(provider, apiKey);
|
|
17587
17690
|
return createClient(apiKey);
|
|
17588
17691
|
}
|
|
17589
17692
|
var activeHARs, activeCoverage, BROWSER_TOOLS;
|
|
@@ -18160,22 +18263,22 @@ function resolveJudgeModel(config) {
|
|
|
18160
18263
|
apiKey = process.env["GOOGLE_API_KEY"];
|
|
18161
18264
|
else if (provider === "cerebras")
|
|
18162
18265
|
apiKey = process.env["CEREBRAS_API_KEY"];
|
|
18266
|
+
else if (provider === "zai")
|
|
18267
|
+
apiKey = process.env["ZAI_API_KEY"];
|
|
18163
18268
|
}
|
|
18164
18269
|
if (!apiKey) {
|
|
18165
|
-
|
|
18166
|
-
if (!apiKey)
|
|
18167
|
-
throw new AIClientError("No API key found for judge. Set ANTHROPIC_API_KEY, CEREBRAS_API_KEY, OPENAI_API_KEY, or GOOGLE_API_KEY.");
|
|
18270
|
+
throw new AIClientError(`No API key found for ${provider} judge provider.`);
|
|
18168
18271
|
}
|
|
18169
18272
|
return { model, provider, apiKey };
|
|
18170
18273
|
}
|
|
18171
18274
|
async function callJudge(prompt, config) {
|
|
18172
18275
|
const { model, provider, apiKey } = resolveJudgeModel(config);
|
|
18173
18276
|
const threshold = 0.7;
|
|
18174
|
-
if (provider
|
|
18175
|
-
const
|
|
18277
|
+
if (provider !== "anthropic") {
|
|
18278
|
+
const compat = createOpenAICompatibleConfig(provider, apiKey);
|
|
18176
18279
|
const resp2 = await callOpenAICompatible({
|
|
18177
|
-
baseUrl,
|
|
18178
|
-
apiKey,
|
|
18280
|
+
baseUrl: compat.baseUrl,
|
|
18281
|
+
apiKey: compat.apiKey,
|
|
18179
18282
|
model,
|
|
18180
18283
|
system: LLM_SYSTEM,
|
|
18181
18284
|
messages: [{ role: "user", content: prompt }],
|
|
@@ -20631,6 +20734,292 @@ var init_failure_pipeline = __esm(() => {
|
|
|
20631
20734
|
init_todos_connector();
|
|
20632
20735
|
});
|
|
20633
20736
|
|
|
20737
|
+
// src/lib/a11y-audit.ts
|
|
20738
|
+
async function runA11yAudit(page, options = {}) {
|
|
20739
|
+
const { level = "AA", rules, exclude = [] } = options;
|
|
20740
|
+
await page.addScriptTag({ url: "https://cdnjs.cloudflare.com/ajax/libs/axe-core/4.9.1/axe.min.js" });
|
|
20741
|
+
const config = {
|
|
20742
|
+
runOnly: {
|
|
20743
|
+
type: level === "AAA" ? "standard" : "tag",
|
|
20744
|
+
values: level === "AAA" ? undefined : [level, "best-practice"]
|
|
20745
|
+
}
|
|
20746
|
+
};
|
|
20747
|
+
if (rules && rules.length > 0) {
|
|
20748
|
+
config.rules = Object.fromEntries(rules.map((r) => [r, { enabled: true }]));
|
|
20749
|
+
}
|
|
20750
|
+
if (exclude.length > 0) {
|
|
20751
|
+
config.exclude = exclude;
|
|
20752
|
+
}
|
|
20753
|
+
const result = await page.evaluate(async (auditConfig) => {
|
|
20754
|
+
const axeResult = await window.axe.run(auditConfig);
|
|
20755
|
+
return axeResult;
|
|
20756
|
+
}, config);
|
|
20757
|
+
const violations = (result.violations ?? []).map((v) => ({
|
|
20758
|
+
id: v.id,
|
|
20759
|
+
impact: v.impact,
|
|
20760
|
+
description: v.description,
|
|
20761
|
+
help: v.help,
|
|
20762
|
+
helpUrl: v.helpUrl,
|
|
20763
|
+
nodes: (v.nodes ?? []).map((n) => ({
|
|
20764
|
+
html: n.html,
|
|
20765
|
+
target: n.target,
|
|
20766
|
+
failureSummary: n.failureSummary
|
|
20767
|
+
}))
|
|
20768
|
+
}));
|
|
20769
|
+
const passes = (result.passes ?? []).map((p) => ({
|
|
20770
|
+
id: p.id,
|
|
20771
|
+
description: p.description
|
|
20772
|
+
}));
|
|
20773
|
+
const incomplete = (result.incomplete ?? []).map((i) => ({
|
|
20774
|
+
id: i.id,
|
|
20775
|
+
description: i.description,
|
|
20776
|
+
impact: i.impact
|
|
20777
|
+
}));
|
|
20778
|
+
const criticalCount = violations.filter((v) => v.impact === "critical").length;
|
|
20779
|
+
const seriousCount = violations.filter((v) => v.impact === "serious").length;
|
|
20780
|
+
const moderateCount = violations.filter((v) => v.impact === "moderate").length;
|
|
20781
|
+
const minorCount = violations.filter((v) => v.impact === "minor").length;
|
|
20782
|
+
return {
|
|
20783
|
+
violations,
|
|
20784
|
+
passes,
|
|
20785
|
+
incomplete,
|
|
20786
|
+
url: page.url(),
|
|
20787
|
+
timestamp: new Date().toISOString(),
|
|
20788
|
+
totalViolations: violations.length,
|
|
20789
|
+
criticalCount,
|
|
20790
|
+
seriousCount,
|
|
20791
|
+
moderateCount,
|
|
20792
|
+
minorCount
|
|
20793
|
+
};
|
|
20794
|
+
}
|
|
20795
|
+
|
|
20796
|
+
// src/lib/assertions.ts
|
|
20797
|
+
async function evaluateAssertions(page, assertions, context = {}) {
|
|
20798
|
+
const results = [];
|
|
20799
|
+
for (const assertion of assertions) {
|
|
20800
|
+
try {
|
|
20801
|
+
const result = await evaluateOne(page, assertion, context);
|
|
20802
|
+
results.push(result);
|
|
20803
|
+
} catch (err) {
|
|
20804
|
+
results.push({
|
|
20805
|
+
assertion,
|
|
20806
|
+
passed: false,
|
|
20807
|
+
actual: "",
|
|
20808
|
+
error: err instanceof Error ? err.message : String(err)
|
|
20809
|
+
});
|
|
20810
|
+
}
|
|
20811
|
+
}
|
|
20812
|
+
return results;
|
|
20813
|
+
}
|
|
20814
|
+
async function evaluateOne(page, assertion, context) {
|
|
20815
|
+
switch (assertion.type) {
|
|
20816
|
+
case "visible": {
|
|
20817
|
+
const visible = await page.locator(assertion.selector).isVisible();
|
|
20818
|
+
return {
|
|
20819
|
+
assertion,
|
|
20820
|
+
passed: visible,
|
|
20821
|
+
actual: String(visible)
|
|
20822
|
+
};
|
|
20823
|
+
}
|
|
20824
|
+
case "not_visible": {
|
|
20825
|
+
const visible = await page.locator(assertion.selector).isVisible();
|
|
20826
|
+
return {
|
|
20827
|
+
assertion,
|
|
20828
|
+
passed: !visible,
|
|
20829
|
+
actual: String(visible)
|
|
20830
|
+
};
|
|
20831
|
+
}
|
|
20832
|
+
case "text_contains": {
|
|
20833
|
+
const text = await page.locator(assertion.selector).textContent() ?? "";
|
|
20834
|
+
const expected = String(assertion.expected ?? "");
|
|
20835
|
+
return {
|
|
20836
|
+
assertion,
|
|
20837
|
+
passed: text.includes(expected),
|
|
20838
|
+
actual: text
|
|
20839
|
+
};
|
|
20840
|
+
}
|
|
20841
|
+
case "text_equals": {
|
|
20842
|
+
const text = await page.locator(assertion.selector).textContent() ?? "";
|
|
20843
|
+
const expected = String(assertion.expected ?? "");
|
|
20844
|
+
return {
|
|
20845
|
+
assertion,
|
|
20846
|
+
passed: text.trim() === expected.trim(),
|
|
20847
|
+
actual: text
|
|
20848
|
+
};
|
|
20849
|
+
}
|
|
20850
|
+
case "element_count": {
|
|
20851
|
+
const count = await page.locator(assertion.selector).count();
|
|
20852
|
+
const expected = Number(assertion.expected ?? 0);
|
|
20853
|
+
return {
|
|
20854
|
+
assertion,
|
|
20855
|
+
passed: count === expected,
|
|
20856
|
+
actual: String(count)
|
|
20857
|
+
};
|
|
20858
|
+
}
|
|
20859
|
+
case "no_console_errors": {
|
|
20860
|
+
if (context.consoleErrors !== undefined) {
|
|
20861
|
+
const errors2 = context.consoleErrors.filter(Boolean);
|
|
20862
|
+
return {
|
|
20863
|
+
assertion,
|
|
20864
|
+
passed: errors2.length === 0,
|
|
20865
|
+
actual: errors2.length === 0 ? "No console errors captured" : errors2.slice(0, 3).join(" | ")
|
|
20866
|
+
};
|
|
20867
|
+
}
|
|
20868
|
+
const errorElements = await page.locator('[role="alert"], .error, .error-message, [data-testid="error"]').count();
|
|
20869
|
+
return {
|
|
20870
|
+
assertion,
|
|
20871
|
+
passed: errorElements === 0,
|
|
20872
|
+
actual: `${errorElements} error element(s) found`
|
|
20873
|
+
};
|
|
20874
|
+
}
|
|
20875
|
+
case "no_a11y_violations": {
|
|
20876
|
+
try {
|
|
20877
|
+
const auditResult = await runA11yAudit(page);
|
|
20878
|
+
const hasIssues = auditResult.violations.length > 0;
|
|
20879
|
+
return {
|
|
20880
|
+
assertion,
|
|
20881
|
+
passed: !hasIssues,
|
|
20882
|
+
actual: hasIssues ? `${auditResult.totalViolations} violation(s): ${auditResult.violations.map((v) => v.id).join(", ")}` : "No accessibility violations found"
|
|
20883
|
+
};
|
|
20884
|
+
} catch (err) {
|
|
20885
|
+
return {
|
|
20886
|
+
assertion,
|
|
20887
|
+
passed: false,
|
|
20888
|
+
actual: "",
|
|
20889
|
+
error: err instanceof Error ? err.message : String(err)
|
|
20890
|
+
};
|
|
20891
|
+
}
|
|
20892
|
+
}
|
|
20893
|
+
case "url_contains": {
|
|
20894
|
+
const url = page.url();
|
|
20895
|
+
const expected = String(assertion.expected ?? "");
|
|
20896
|
+
return {
|
|
20897
|
+
assertion,
|
|
20898
|
+
passed: url.includes(expected),
|
|
20899
|
+
actual: url
|
|
20900
|
+
};
|
|
20901
|
+
}
|
|
20902
|
+
case "title_contains": {
|
|
20903
|
+
const title = await page.title();
|
|
20904
|
+
const expected = String(assertion.expected ?? "");
|
|
20905
|
+
return {
|
|
20906
|
+
assertion,
|
|
20907
|
+
passed: title.includes(expected),
|
|
20908
|
+
actual: title
|
|
20909
|
+
};
|
|
20910
|
+
}
|
|
20911
|
+
case "cookie_exists": {
|
|
20912
|
+
const cookieName = assertion.expected;
|
|
20913
|
+
const cookies = await page.context().cookies();
|
|
20914
|
+
const found = cookies.some((c) => c.name === cookieName);
|
|
20915
|
+
return {
|
|
20916
|
+
assertion,
|
|
20917
|
+
passed: found,
|
|
20918
|
+
actual: found ? `Cookie "${cookieName}" exists` : `Cookie "${cookieName}" not found`
|
|
20919
|
+
};
|
|
20920
|
+
}
|
|
20921
|
+
case "cookie_not_exists": {
|
|
20922
|
+
const cookieName = assertion.expected;
|
|
20923
|
+
const cookies = await page.context().cookies();
|
|
20924
|
+
const found = cookies.some((c) => c.name === cookieName);
|
|
20925
|
+
return {
|
|
20926
|
+
assertion,
|
|
20927
|
+
passed: !found,
|
|
20928
|
+
actual: found ? `Cookie "${cookieName}" found (unexpected)` : `Cookie "${cookieName}" does not exist`
|
|
20929
|
+
};
|
|
20930
|
+
}
|
|
20931
|
+
case "cookie_value": {
|
|
20932
|
+
const [cookieName, expectedValue] = assertion.expected.split("=", 2);
|
|
20933
|
+
const cookies = await page.context().cookies();
|
|
20934
|
+
const cookie = cookies.find((c) => c.name === cookieName);
|
|
20935
|
+
const actualValue = cookie?.value ?? "";
|
|
20936
|
+
return {
|
|
20937
|
+
assertion,
|
|
20938
|
+
passed: actualValue === expectedValue,
|
|
20939
|
+
actual: cookie ? `${cookieName}=${actualValue}` : `Cookie "${cookieName}" not found`
|
|
20940
|
+
};
|
|
20941
|
+
}
|
|
20942
|
+
case "local_storage_exists": {
|
|
20943
|
+
const key = assertion.expected;
|
|
20944
|
+
const value = await page.evaluate((k) => localStorage.getItem(k), key);
|
|
20945
|
+
return {
|
|
20946
|
+
assertion,
|
|
20947
|
+
passed: value !== null,
|
|
20948
|
+
actual: value !== null ? `Key "${key}" exists with value "${value}"` : `Key "${key}" not found in localStorage`
|
|
20949
|
+
};
|
|
20950
|
+
}
|
|
20951
|
+
case "local_storage_not_exists": {
|
|
20952
|
+
const key = assertion.expected;
|
|
20953
|
+
const value = await page.evaluate((k) => localStorage.getItem(k), key);
|
|
20954
|
+
return {
|
|
20955
|
+
assertion,
|
|
20956
|
+
passed: value === null,
|
|
20957
|
+
actual: value !== null ? `Key "${key}" exists (unexpected)` : `Key "${key}" does not exist in localStorage`
|
|
20958
|
+
};
|
|
20959
|
+
}
|
|
20960
|
+
case "local_storage_value": {
|
|
20961
|
+
const [lsKey, expectedValue] = assertion.expected.split("=", 2);
|
|
20962
|
+
const value = await page.evaluate((k) => localStorage.getItem(k), lsKey ?? "");
|
|
20963
|
+
return {
|
|
20964
|
+
assertion,
|
|
20965
|
+
passed: value === expectedValue,
|
|
20966
|
+
actual: value !== null ? `${lsKey}=${value}` : `Key "${lsKey}" not found in localStorage`
|
|
20967
|
+
};
|
|
20968
|
+
}
|
|
20969
|
+
case "session_storage_value": {
|
|
20970
|
+
const [ssKey, expectedValue] = assertion.expected.split("=", 2);
|
|
20971
|
+
const value = await page.evaluate((k) => sessionStorage.getItem(k), ssKey ?? "");
|
|
20972
|
+
return {
|
|
20973
|
+
assertion,
|
|
20974
|
+
passed: value === expectedValue,
|
|
20975
|
+
actual: value !== null ? `${ssKey}=${value}` : `Key "${ssKey}" not found in sessionStorage`
|
|
20976
|
+
};
|
|
20977
|
+
}
|
|
20978
|
+
case "session_storage_not_exists": {
|
|
20979
|
+
const key = assertion.expected;
|
|
20980
|
+
const value = await page.evaluate((k) => sessionStorage.getItem(k), key);
|
|
20981
|
+
return {
|
|
20982
|
+
assertion,
|
|
20983
|
+
passed: value === null,
|
|
20984
|
+
actual: value !== null ? `Key "${key}" exists (unexpected)` : `Key "${key}" does not exist in sessionStorage`
|
|
20985
|
+
};
|
|
20986
|
+
}
|
|
20987
|
+
default: {
|
|
20988
|
+
return {
|
|
20989
|
+
assertion,
|
|
20990
|
+
passed: false,
|
|
20991
|
+
actual: "",
|
|
20992
|
+
error: `Unknown assertion type: ${assertion.type}`
|
|
20993
|
+
};
|
|
20994
|
+
}
|
|
20995
|
+
}
|
|
20996
|
+
}
|
|
20997
|
+
function allAssertionsPassed(results) {
|
|
20998
|
+
return results.every((r) => r.passed);
|
|
20999
|
+
}
|
|
21000
|
+
function formatAssertionResults(results) {
|
|
21001
|
+
if (results.length === 0)
|
|
21002
|
+
return "No assertions.";
|
|
21003
|
+
const lines = [];
|
|
21004
|
+
for (const r of results) {
|
|
21005
|
+
const icon = r.passed ? "PASS" : "FAIL";
|
|
21006
|
+
const desc = r.assertion.description || `${r.assertion.type}${r.assertion.selector ? ` ${r.assertion.selector}` : ""}`;
|
|
21007
|
+
let line = ` [${icon}] ${desc}`;
|
|
21008
|
+
if (!r.passed) {
|
|
21009
|
+
line += ` (actual: ${r.actual})`;
|
|
21010
|
+
if (r.error)
|
|
21011
|
+
line += ` \u2014 ${r.error}`;
|
|
21012
|
+
}
|
|
21013
|
+
lines.push(line);
|
|
21014
|
+
}
|
|
21015
|
+
const passed = results.filter((r) => r.passed).length;
|
|
21016
|
+
lines.push(`
|
|
21017
|
+
${passed}/${results.length} assertions passed.`);
|
|
21018
|
+
return lines.join(`
|
|
21019
|
+
`);
|
|
21020
|
+
}
|
|
21021
|
+
var init_assertions = () => {};
|
|
21022
|
+
|
|
20634
21023
|
// src/db/flows.ts
|
|
20635
21024
|
var exports_flows = {};
|
|
20636
21025
|
__export(exports_flows, {
|
|
@@ -20789,7 +21178,10 @@ __export(exports_runner, {
|
|
|
20789
21178
|
runSingleScenario: () => runSingleScenario,
|
|
20790
21179
|
runByFilter: () => runByFilter,
|
|
20791
21180
|
runBatch: () => runBatch,
|
|
20792
|
-
|
|
21181
|
+
resolveScenariosForRun: () => resolveScenariosForRun,
|
|
21182
|
+
resolveAgentApiKeyForModel: () => resolveAgentApiKeyForModel,
|
|
21183
|
+
onRunEvent: () => onRunEvent,
|
|
21184
|
+
applyStructuredAssertionsToResult: () => applyStructuredAssertionsToResult
|
|
20793
21185
|
});
|
|
20794
21186
|
import { mkdirSync as mkdirSync8 } from "fs";
|
|
20795
21187
|
import { join as join13 } from "path";
|
|
@@ -20801,6 +21193,57 @@ function emit(event) {
|
|
|
20801
21193
|
if (eventHandler)
|
|
20802
21194
|
eventHandler(event);
|
|
20803
21195
|
}
|
|
21196
|
+
function resolveAgentApiKeyForModel(model, explicitApiKey, configuredAnthropicApiKey) {
|
|
21197
|
+
return resolveProviderApiKeyForModel(model, explicitApiKey, configuredAnthropicApiKey);
|
|
21198
|
+
}
|
|
21199
|
+
function assertionDescription(result) {
|
|
21200
|
+
return result.assertion.description || `${result.assertion.type}${result.assertion.selector ? ` ${result.assertion.selector}` : ""}`;
|
|
21201
|
+
}
|
|
21202
|
+
function summarizeAssertionResult(result) {
|
|
21203
|
+
const description = assertionDescription(result);
|
|
21204
|
+
if (result.passed)
|
|
21205
|
+
return description;
|
|
21206
|
+
const suffix = result.error ? `; ${result.error}` : "";
|
|
21207
|
+
return `${description} (actual: ${result.actual}${suffix})`;
|
|
21208
|
+
}
|
|
21209
|
+
async function applyStructuredAssertionsToResult(input) {
|
|
21210
|
+
const assertions = input.scenario.assertions ?? [];
|
|
21211
|
+
if (assertions.length === 0) {
|
|
21212
|
+
return {
|
|
21213
|
+
status: input.status,
|
|
21214
|
+
reasoning: input.reasoning,
|
|
21215
|
+
assertionsPassed: [],
|
|
21216
|
+
assertionsFailed: [],
|
|
21217
|
+
assertionResults: []
|
|
21218
|
+
};
|
|
21219
|
+
}
|
|
21220
|
+
const results = await evaluateAssertions(input.page, assertions, {
|
|
21221
|
+
consoleErrors: input.consoleErrors
|
|
21222
|
+
});
|
|
21223
|
+
const assertionsPassed = results.filter((r) => r.passed).map(summarizeAssertionResult);
|
|
21224
|
+
const assertionsFailed = results.filter((r) => !r.passed).map(summarizeAssertionResult);
|
|
21225
|
+
const assertionResults = results.map((result) => ({
|
|
21226
|
+
type: result.assertion.type,
|
|
21227
|
+
description: assertionDescription(result),
|
|
21228
|
+
passed: result.passed,
|
|
21229
|
+
actual: result.actual,
|
|
21230
|
+
...result.error ? { error: result.error } : {}
|
|
21231
|
+
}));
|
|
21232
|
+
const assertionsOk = allAssertionsPassed(results);
|
|
21233
|
+
const status = assertionsOk || input.status !== "passed" ? input.status : "failed";
|
|
21234
|
+
const assertionHeading = assertionsOk ? "Structured assertions passed:" : "Structured assertions failed:";
|
|
21235
|
+
const reasoningParts = [input.reasoning, `${assertionHeading}
|
|
21236
|
+
${formatAssertionResults(results)}`].map((part) => part.trim()).filter(Boolean);
|
|
21237
|
+
return {
|
|
21238
|
+
status,
|
|
21239
|
+
reasoning: reasoningParts.join(`
|
|
21240
|
+
|
|
21241
|
+
`),
|
|
21242
|
+
assertionsPassed,
|
|
21243
|
+
assertionsFailed,
|
|
21244
|
+
assertionResults
|
|
21245
|
+
};
|
|
21246
|
+
}
|
|
20804
21247
|
function withTimeout(promise, ms, label) {
|
|
20805
21248
|
return new Promise((resolve, reject) => {
|
|
20806
21249
|
const warningAt = Math.floor(ms * 0.8);
|
|
@@ -20861,7 +21304,7 @@ async function runSingleScenario(scenario, runId, options) {
|
|
|
20861
21304
|
});
|
|
20862
21305
|
}
|
|
20863
21306
|
}
|
|
20864
|
-
const client = createClientForModel(model, effectiveOptions.apiKey
|
|
21307
|
+
const client = createClientForModel(model, resolveAgentApiKeyForModel(model, effectiveOptions.apiKey, config.anthropicApiKey));
|
|
20865
21308
|
const screenshotter = new Screenshotter({
|
|
20866
21309
|
baseDir: effectiveOptions.screenshotDir ?? config.screenshots.dir
|
|
20867
21310
|
});
|
|
@@ -20971,6 +21414,7 @@ async function runSingleScenario(scenario, runId, options) {
|
|
|
20971
21414
|
model,
|
|
20972
21415
|
runId,
|
|
20973
21416
|
sessionId: result.id,
|
|
21417
|
+
baseUrl: options.url,
|
|
20974
21418
|
maxTurns: effectiveOptions.minimal ? 10 : 30,
|
|
20975
21419
|
a11y: effectiveOptions.a11y,
|
|
20976
21420
|
persona: persona ? {
|
|
@@ -21053,27 +21497,46 @@ async function runSingleScenario(scenario, runId, options) {
|
|
|
21053
21497
|
closeSession(result.id);
|
|
21054
21498
|
const lightpandaNote = options.engine === "lightpanda" ? " (Running with Lightpanda \u2014 no screenshots)" : options.engine === "bun" ? " (Running with Bun.WebView \u2014 native, ~11x faster)" : "";
|
|
21055
21499
|
const networkMeta = networkErrors.length > 0 ? { networkErrors: networkErrors.slice(0, 20) } : {};
|
|
21056
|
-
|
|
21500
|
+
const baseReasoning = agentResult.reasoning ? agentResult.reasoning + lightpandaNote : lightpandaNote || "";
|
|
21501
|
+
const assertionOutcome = await applyStructuredAssertionsToResult({
|
|
21502
|
+
page,
|
|
21503
|
+
scenario,
|
|
21504
|
+
consoleErrors,
|
|
21057
21505
|
status: agentResult.status,
|
|
21058
|
-
reasoning:
|
|
21506
|
+
reasoning: baseReasoning
|
|
21507
|
+
});
|
|
21508
|
+
const structuredAssertionMeta = assertionOutcome.assertionResults.length > 0 ? {
|
|
21509
|
+
structuredAssertions: {
|
|
21510
|
+
passed: assertionOutcome.assertionsPassed,
|
|
21511
|
+
failed: assertionOutcome.assertionsFailed,
|
|
21512
|
+
results: assertionOutcome.assertionResults
|
|
21513
|
+
}
|
|
21514
|
+
} : {};
|
|
21515
|
+
let updatedResult = updateResult(result.id, {
|
|
21516
|
+
status: assertionOutcome.status,
|
|
21517
|
+
reasoning: assertionOutcome.reasoning || undefined,
|
|
21059
21518
|
stepsCompleted: agentResult.stepsCompleted,
|
|
21060
21519
|
durationMs: Date.now() - new Date(result.createdAt).getTime(),
|
|
21061
21520
|
tokensUsed: agentResult.tokensUsed,
|
|
21062
21521
|
costCents: estimateCost(model, agentResult.tokensUsed),
|
|
21063
|
-
metadata: {
|
|
21522
|
+
metadata: {
|
|
21523
|
+
consoleLogs,
|
|
21524
|
+
...networkErrors.length > 0 ? networkMeta : {},
|
|
21525
|
+
...structuredAssertionMeta
|
|
21526
|
+
}
|
|
21064
21527
|
});
|
|
21065
|
-
if (
|
|
21066
|
-
const failureAnalysis = analyzeFailure(null,
|
|
21528
|
+
if (assertionOutcome.status === "failed" || assertionOutcome.status === "error") {
|
|
21529
|
+
const failureAnalysis = analyzeFailure(null, assertionOutcome.reasoning ?? null);
|
|
21067
21530
|
if (failureAnalysis) {
|
|
21068
21531
|
updatedResult = updateResult(result.id, { failureAnalysis });
|
|
21069
21532
|
}
|
|
21070
21533
|
}
|
|
21071
|
-
if (
|
|
21534
|
+
if (assertionOutcome.status === "passed") {
|
|
21072
21535
|
try {
|
|
21073
21536
|
updateScenarioPassedCache(scenario.id, options.url);
|
|
21074
21537
|
} catch {}
|
|
21075
21538
|
}
|
|
21076
|
-
const eventType =
|
|
21539
|
+
const eventType = assertionOutcome.status === "passed" ? "scenario:pass" : "scenario:fail";
|
|
21077
21540
|
emit({ type: eventType, scenarioId: scenario.id, scenarioName: scenario.name, resultId: result.id, runId });
|
|
21078
21541
|
return updatedResult;
|
|
21079
21542
|
} catch (error) {
|
|
@@ -21098,7 +21561,8 @@ async function runSingleScenario(scenario, runId, options) {
|
|
|
21098
21561
|
} finally {
|
|
21099
21562
|
if (harPath) {
|
|
21100
21563
|
try {
|
|
21101
|
-
|
|
21564
|
+
const existing = getResult(result.id);
|
|
21565
|
+
updateResult(result.id, { metadata: { ...existing?.metadata ?? {}, harPath } });
|
|
21102
21566
|
} catch {}
|
|
21103
21567
|
}
|
|
21104
21568
|
if (browser) {
|
|
@@ -21270,22 +21734,31 @@ async function runBatch(scenarios, options) {
|
|
|
21270
21734
|
}
|
|
21271
21735
|
return { run: finalRun, results };
|
|
21272
21736
|
}
|
|
21273
|
-
|
|
21274
|
-
|
|
21737
|
+
function findScenarioInList(scenarios, id) {
|
|
21738
|
+
return scenarios.find((scenario) => scenario.id === id || scenario.shortId === id || scenario.id.startsWith(id)) ?? null;
|
|
21739
|
+
}
|
|
21740
|
+
function resolveScenariosForRun(options) {
|
|
21275
21741
|
if (options.scenarioIds && options.scenarioIds.length > 0) {
|
|
21276
|
-
const
|
|
21277
|
-
|
|
21278
|
-
|
|
21279
|
-
|
|
21280
|
-
|
|
21742
|
+
const scoped = listScenarios({ projectId: options.projectId });
|
|
21743
|
+
const resolved = [];
|
|
21744
|
+
const seen = new Set;
|
|
21745
|
+
for (const id of options.scenarioIds) {
|
|
21746
|
+
const scenario = findScenarioInList(scoped, id) ?? getScenario(id);
|
|
21747
|
+
if (scenario && !seen.has(scenario.id)) {
|
|
21748
|
+
resolved.push(scenario);
|
|
21749
|
+
seen.add(scenario.id);
|
|
21750
|
+
}
|
|
21281
21751
|
}
|
|
21282
|
-
|
|
21283
|
-
scenarios = listScenarios({
|
|
21284
|
-
projectId: options.projectId,
|
|
21285
|
-
tags: options.tags,
|
|
21286
|
-
priority: options.priority
|
|
21287
|
-
});
|
|
21752
|
+
return resolved;
|
|
21288
21753
|
}
|
|
21754
|
+
return listScenarios({
|
|
21755
|
+
projectId: options.projectId,
|
|
21756
|
+
tags: options.tags,
|
|
21757
|
+
priority: options.priority
|
|
21758
|
+
});
|
|
21759
|
+
}
|
|
21760
|
+
async function runByFilter(options) {
|
|
21761
|
+
const scenarios = resolveScenariosForRun(options);
|
|
21289
21762
|
if (scenarios.length === 0) {
|
|
21290
21763
|
const config = loadConfig();
|
|
21291
21764
|
const model = resolveModel2(options.model ?? config.defaultModel);
|
|
@@ -21298,17 +21771,7 @@ async function runByFilter(options) {
|
|
|
21298
21771
|
function startRunAsync(options) {
|
|
21299
21772
|
const config = loadConfig();
|
|
21300
21773
|
const model = resolveModel2(options.model ?? config.defaultModel);
|
|
21301
|
-
|
|
21302
|
-
if (options.scenarioIds && options.scenarioIds.length > 0) {
|
|
21303
|
-
const all = listScenarios({ projectId: options.projectId });
|
|
21304
|
-
scenarios = all.filter((s) => options.scenarioIds.includes(s.id) || options.scenarioIds.includes(s.shortId));
|
|
21305
|
-
} else {
|
|
21306
|
-
scenarios = listScenarios({
|
|
21307
|
-
projectId: options.projectId,
|
|
21308
|
-
tags: options.tags,
|
|
21309
|
-
priority: options.priority
|
|
21310
|
-
});
|
|
21311
|
-
}
|
|
21774
|
+
const scenarios = resolveScenariosForRun(options);
|
|
21312
21775
|
if (!options.skipBudgetCheck) {
|
|
21313
21776
|
const cap = options.maxCostCents ?? config.defaultMaxCostCents;
|
|
21314
21777
|
if (cap !== undefined && cap > 0 && scenarios.length > 0) {
|
|
@@ -21412,6 +21875,7 @@ var init_runner = __esm(() => {
|
|
|
21412
21875
|
init_session_tracker();
|
|
21413
21876
|
init_webhooks();
|
|
21414
21877
|
init_failure_pipeline();
|
|
21878
|
+
init_assertions();
|
|
21415
21879
|
});
|
|
21416
21880
|
|
|
21417
21881
|
// src/lib/affected.ts
|
|
@@ -22886,18 +23350,7 @@ function normalizeFilter(input) {
|
|
|
22886
23350
|
};
|
|
22887
23351
|
}
|
|
22888
23352
|
function normalizeExecution(input) {
|
|
22889
|
-
|
|
22890
|
-
if (target === "connector:e2b") {
|
|
22891
|
-
return {
|
|
22892
|
-
target,
|
|
22893
|
-
connector: input?.connector ?? "e2b",
|
|
22894
|
-
operation: input?.operation ?? "run",
|
|
22895
|
-
sandboxTemplate: input?.sandboxTemplate,
|
|
22896
|
-
timeoutMs: input?.timeoutMs,
|
|
22897
|
-
env: input?.env
|
|
22898
|
-
};
|
|
22899
|
-
}
|
|
22900
|
-
return { ...DEFAULT_EXECUTION, timeoutMs: input?.timeoutMs };
|
|
23353
|
+
return input ? workflowExecutionFromValue(input) : DEFAULT_EXECUTION;
|
|
22901
23354
|
}
|
|
22902
23355
|
function createTestingWorkflow(input) {
|
|
22903
23356
|
const db2 = getDatabase();
|
|
@@ -22948,6 +23401,9 @@ var init_workflows = __esm(() => {
|
|
|
22948
23401
|
});
|
|
22949
23402
|
|
|
22950
23403
|
// src/lib/workflow-runner.ts
|
|
23404
|
+
import { mkdtempSync, rmSync, writeFileSync as writeFileSync3 } from "fs";
|
|
23405
|
+
import { tmpdir } from "os";
|
|
23406
|
+
import { join as join14 } from "path";
|
|
22951
23407
|
function buildWorkflowRunPlan(workflow, options) {
|
|
22952
23408
|
const runOptions = {
|
|
22953
23409
|
url: options.url,
|
|
@@ -22964,10 +23420,10 @@ function buildWorkflowRunPlan(workflow, options) {
|
|
|
22964
23420
|
return {
|
|
22965
23421
|
workflow,
|
|
22966
23422
|
runOptions,
|
|
22967
|
-
|
|
23423
|
+
sandbox: workflow.execution.target === "sandbox" ? buildSandboxPlan(workflow, workflow.execution, runOptions) : null
|
|
22968
23424
|
};
|
|
22969
23425
|
}
|
|
22970
|
-
async function runTestingWorkflow(workflowId, options) {
|
|
23426
|
+
async function runTestingWorkflow(workflowId, options, dependencies = {}) {
|
|
22971
23427
|
const workflow = getTestingWorkflow(workflowId);
|
|
22972
23428
|
if (!workflow)
|
|
22973
23429
|
throw new Error(`Testing workflow not found: ${workflowId}`);
|
|
@@ -22977,13 +23433,25 @@ async function runTestingWorkflow(workflowId, options) {
|
|
|
22977
23433
|
const plan = buildWorkflowRunPlan(workflow, options);
|
|
22978
23434
|
if (options.dryRun)
|
|
22979
23435
|
return { run: null, results: [], plan };
|
|
22980
|
-
if (workflow.execution.target === "
|
|
22981
|
-
const
|
|
22982
|
-
return { run: null, results: [], plan,
|
|
23436
|
+
if (workflow.execution.target === "sandbox") {
|
|
23437
|
+
const sandboxResult = await runViaSandbox(plan, dependencies);
|
|
23438
|
+
return { run: null, results: [], plan, sandboxResult };
|
|
22983
23439
|
}
|
|
22984
|
-
const
|
|
23440
|
+
const runLocal = dependencies.runByFilter ?? runByFilter;
|
|
23441
|
+
const { run, results } = await runLocal(plan.runOptions);
|
|
22985
23442
|
return { run, results, plan };
|
|
22986
23443
|
}
|
|
23444
|
+
function createWorkflowDatabaseBundle(workflow, plan) {
|
|
23445
|
+
if (!plan.sandbox)
|
|
23446
|
+
throw new Error(`Workflow is not configured for sandbox execution: ${workflow.name}`);
|
|
23447
|
+
const localDir = mkdtempSync(join14(tmpdir(), `testers-workflow-${workflow.id.slice(0, 8)}-`));
|
|
23448
|
+
writeFileSync3(join14(localDir, "testers.db"), getDatabase().serialize());
|
|
23449
|
+
return {
|
|
23450
|
+
localDir,
|
|
23451
|
+
remoteDir: plan.sandbox.stateRemoteDir,
|
|
23452
|
+
cleanup: () => rmSync(localDir, { recursive: true, force: true })
|
|
23453
|
+
};
|
|
23454
|
+
}
|
|
22987
23455
|
function validatePersonaIds(workflow) {
|
|
22988
23456
|
for (const personaId of workflow.personaIds) {
|
|
22989
23457
|
if (!getPersona(personaId)) {
|
|
@@ -22991,48 +23459,112 @@ function validatePersonaIds(workflow) {
|
|
|
22991
23459
|
}
|
|
22992
23460
|
}
|
|
22993
23461
|
}
|
|
22994
|
-
function
|
|
22995
|
-
const
|
|
22996
|
-
const
|
|
22997
|
-
|
|
22998
|
-
|
|
22999
|
-
|
|
23462
|
+
function buildSandboxPlan(workflow, execution, runOptions) {
|
|
23463
|
+
const remoteDir = execution.sandboxRemoteDir ?? `/tmp/testers-workflow-${workflow.id.slice(0, 8)}`;
|
|
23464
|
+
const stateRemoteDir = `${remoteDir.replace(/\/+$/, "")}/.testers-state`;
|
|
23465
|
+
return {
|
|
23466
|
+
provider: execution.provider,
|
|
23467
|
+
image: execution.sandboxImage,
|
|
23468
|
+
name: `testers-${workflow.id.slice(0, 8)}`,
|
|
23469
|
+
remoteDir,
|
|
23470
|
+
stateRemoteDir,
|
|
23471
|
+
cleanup: execution.sandboxCleanup ?? "delete",
|
|
23000
23472
|
timeoutMs: execution.timeoutMs,
|
|
23001
|
-
env: execution.env
|
|
23002
|
-
command:
|
|
23003
|
-
|
|
23004
|
-
|
|
23005
|
-
|
|
23006
|
-
|
|
23007
|
-
|
|
23008
|
-
|
|
23009
|
-
|
|
23010
|
-
...runOptions.projectId ? ["--project", runOptions.projectId] : [],
|
|
23011
|
-
...runOptions.model ? ["--model", runOptions.model] : [],
|
|
23012
|
-
"--json"
|
|
23013
|
-
]
|
|
23014
|
-
});
|
|
23015
|
-
return ["connectors", "run", connector, operation, payload];
|
|
23473
|
+
env: execution.env,
|
|
23474
|
+
command: buildSandboxCommand({
|
|
23475
|
+
runOptions,
|
|
23476
|
+
remoteDir,
|
|
23477
|
+
dbPath: `${stateRemoteDir}/testers.db`,
|
|
23478
|
+
setupCommand: execution.setupCommand,
|
|
23479
|
+
packageSpec: execution.packageSpec ?? "@hasna/testers"
|
|
23480
|
+
})
|
|
23481
|
+
};
|
|
23016
23482
|
}
|
|
23017
|
-
|
|
23018
|
-
|
|
23019
|
-
|
|
23020
|
-
|
|
23021
|
-
|
|
23022
|
-
|
|
23023
|
-
|
|
23024
|
-
|
|
23025
|
-
|
|
23026
|
-
|
|
23027
|
-
|
|
23028
|
-
|
|
23029
|
-
|
|
23030
|
-
|
|
23031
|
-
|
|
23483
|
+
function buildSandboxCommand(input) {
|
|
23484
|
+
const args = [
|
|
23485
|
+
"bunx",
|
|
23486
|
+
input.packageSpec,
|
|
23487
|
+
"run",
|
|
23488
|
+
input.runOptions.url,
|
|
23489
|
+
...input.runOptions.scenarioIds?.length ? ["--scenario", input.runOptions.scenarioIds.join(",")] : [],
|
|
23490
|
+
...input.runOptions.tags?.length ? input.runOptions.tags.flatMap((tag) => ["--tag", tag]) : [],
|
|
23491
|
+
...input.runOptions.priority ? ["--priority", input.runOptions.priority] : [],
|
|
23492
|
+
...input.runOptions.projectId ? ["--project", input.runOptions.projectId] : [],
|
|
23493
|
+
...input.runOptions.model ? ["--model", input.runOptions.model] : [],
|
|
23494
|
+
...input.runOptions.headed ? ["--headed"] : [],
|
|
23495
|
+
...input.runOptions.parallel ? ["--parallel", String(input.runOptions.parallel)] : [],
|
|
23496
|
+
...input.runOptions.timeout ? ["--timeout", String(input.runOptions.timeout)] : [],
|
|
23497
|
+
...input.runOptions.personaIds?.length ? ["--persona", input.runOptions.personaIds.join(",")] : [],
|
|
23498
|
+
"--no-auto-generate",
|
|
23499
|
+
"--json"
|
|
23500
|
+
];
|
|
23501
|
+
return [
|
|
23502
|
+
"set -euo pipefail",
|
|
23503
|
+
`mkdir -p ${shellQuote(input.remoteDir)}`,
|
|
23504
|
+
`cd ${shellQuote(input.remoteDir)}`,
|
|
23505
|
+
input.setupCommand,
|
|
23506
|
+
`HASNA_TESTERS_DB_PATH=${shellQuote(input.dbPath)} ${args.map(shellQuote).join(" ")}`
|
|
23507
|
+
].filter(Boolean).join(`
|
|
23508
|
+
`);
|
|
23509
|
+
}
|
|
23510
|
+
async function runViaSandbox(plan, dependencies) {
|
|
23511
|
+
if (!plan.sandbox)
|
|
23512
|
+
throw new Error("Workflow does not have a sandbox plan");
|
|
23513
|
+
const sandboxes = await resolveSandboxesRuntime(dependencies);
|
|
23514
|
+
const createBundle = dependencies.createDatabaseBundle ?? createWorkflowDatabaseBundle;
|
|
23515
|
+
const bundle = createBundle(plan.workflow, plan);
|
|
23516
|
+
try {
|
|
23517
|
+
const raw = await sandboxes.runCommandInSandbox({
|
|
23518
|
+
command: plan.sandbox.command,
|
|
23519
|
+
provider: plan.sandbox.provider,
|
|
23520
|
+
name: plan.sandbox.name,
|
|
23521
|
+
image: plan.sandbox.image,
|
|
23522
|
+
sandboxTimeout: plan.sandbox.timeoutMs,
|
|
23523
|
+
commandTimeoutMs: plan.sandbox.timeoutMs,
|
|
23524
|
+
projectId: plan.workflow.projectId ?? undefined,
|
|
23525
|
+
config: {
|
|
23526
|
+
source: "testers",
|
|
23527
|
+
workflowId: plan.workflow.id,
|
|
23528
|
+
workflowName: plan.workflow.name
|
|
23529
|
+
},
|
|
23530
|
+
sandboxEnvVars: plan.sandbox.env,
|
|
23531
|
+
cleanup: plan.sandbox.cleanup,
|
|
23532
|
+
upload: {
|
|
23533
|
+
localDir: bundle.localDir,
|
|
23534
|
+
remoteDir: bundle.remoteDir
|
|
23535
|
+
}
|
|
23536
|
+
});
|
|
23537
|
+
const exitCode = raw.result.exit_code ?? raw.result.exitCode ?? 0;
|
|
23538
|
+
const stdout = raw.result.stdout ?? "";
|
|
23539
|
+
const stderr = raw.result.stderr ?? "";
|
|
23540
|
+
if (exitCode !== 0) {
|
|
23541
|
+
throw new Error(`Sandbox workflow execution failed (${exitCode}): ${stderr || stdout}`);
|
|
23542
|
+
}
|
|
23543
|
+
return {
|
|
23544
|
+
sandboxId: raw.sandbox.id,
|
|
23545
|
+
sessionId: raw.session.id,
|
|
23546
|
+
exitCode,
|
|
23547
|
+
stdout,
|
|
23548
|
+
stderr,
|
|
23549
|
+
cleanup: raw.cleanup
|
|
23550
|
+
};
|
|
23551
|
+
} finally {
|
|
23552
|
+
bundle.cleanup?.();
|
|
23032
23553
|
}
|
|
23033
|
-
|
|
23554
|
+
}
|
|
23555
|
+
async function resolveSandboxesRuntime(dependencies) {
|
|
23556
|
+
if (dependencies.sandboxes)
|
|
23557
|
+
return dependencies.sandboxes;
|
|
23558
|
+
if (dependencies.createSandboxesSDK)
|
|
23559
|
+
return dependencies.createSandboxesSDK();
|
|
23560
|
+
const mod = await import("@hasna/sandboxes");
|
|
23561
|
+
return mod.createSandboxesSDK();
|
|
23562
|
+
}
|
|
23563
|
+
function shellQuote(value) {
|
|
23564
|
+
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
23034
23565
|
}
|
|
23035
23566
|
var init_workflow_runner = __esm(() => {
|
|
23567
|
+
init_database();
|
|
23036
23568
|
init_workflows();
|
|
23037
23569
|
init_personas();
|
|
23038
23570
|
init_runner();
|
|
@@ -34705,34 +35237,27 @@ var init_v3 = __esm(() => {
|
|
|
34705
35237
|
|
|
34706
35238
|
// node_modules/@ai-sdk/provider-utils/node_modules/eventsource-parser/dist/index.js
|
|
34707
35239
|
function noop(_arg) {}
|
|
34708
|
-
function createParser(
|
|
34709
|
-
if (typeof
|
|
34710
|
-
throw new TypeError("`
|
|
34711
|
-
const { onEvent = noop, onError = noop, onRetry = noop, onComment
|
|
34712
|
-
let
|
|
35240
|
+
function createParser(callbacks) {
|
|
35241
|
+
if (typeof callbacks == "function")
|
|
35242
|
+
throw new TypeError("`callbacks` must be an object, got a function instead. Did you mean `{onEvent: fn}`?");
|
|
35243
|
+
const { onEvent = noop, onError = noop, onRetry = noop, onComment } = callbacks, pendingFragments = [];
|
|
35244
|
+
let isFirstChunk = true, id, data = "", dataLines = 0, eventType;
|
|
34713
35245
|
function feed(chunk) {
|
|
34714
|
-
if (terminated)
|
|
34715
|
-
throw new Error("Cannot feed parser: it was terminated after exceeding the configured max buffer size. Call `reset()` to resume parsing.");
|
|
34716
35246
|
if (isFirstChunk && (isFirstChunk = false, chunk.charCodeAt(0) === 239 && chunk.charCodeAt(1) === 187 && chunk.charCodeAt(2) === 191 && (chunk = chunk.slice(3))), pendingFragments.length === 0) {
|
|
34717
35247
|
const trailing2 = processLines(chunk);
|
|
34718
|
-
trailing2 !== "" &&
|
|
35248
|
+
trailing2 !== "" && pendingFragments.push(trailing2);
|
|
34719
35249
|
return;
|
|
34720
35250
|
}
|
|
34721
35251
|
if (chunk.indexOf(`
|
|
34722
35252
|
`) === -1 && chunk.indexOf("\r") === -1) {
|
|
34723
|
-
pendingFragments.push(chunk)
|
|
35253
|
+
pendingFragments.push(chunk);
|
|
34724
35254
|
return;
|
|
34725
35255
|
}
|
|
34726
35256
|
pendingFragments.push(chunk);
|
|
34727
35257
|
const input = pendingFragments.join("");
|
|
34728
|
-
pendingFragments.length = 0
|
|
35258
|
+
pendingFragments.length = 0;
|
|
34729
35259
|
const trailing = processLines(input);
|
|
34730
|
-
trailing !== "" &&
|
|
34731
|
-
}
|
|
34732
|
-
function checkBufferSize() {
|
|
34733
|
-
maxBufferSize !== undefined && (pendingFragmentsLength + data.length <= maxBufferSize || (terminated = true, pendingFragments.length = 0, pendingFragmentsLength = 0, id = undefined, data = "", dataLines = 0, eventType = undefined, onError(new ParseError(`Buffered data exceeded max buffer size of ${maxBufferSize} characters`, {
|
|
34734
|
-
type: "max-buffer-size-exceeded"
|
|
34735
|
-
}))));
|
|
35260
|
+
trailing !== "" && pendingFragments.push(trailing);
|
|
34736
35261
|
}
|
|
34737
35262
|
function processLines(chunk) {
|
|
34738
35263
|
let searchIndex = 0;
|
|
@@ -34844,7 +35369,7 @@ ${value}`, dataLines++;
|
|
|
34844
35369
|
const incompleteLine = pendingFragments.join("");
|
|
34845
35370
|
parseLine(incompleteLine, 0, incompleteLine.length);
|
|
34846
35371
|
}
|
|
34847
|
-
isFirstChunk = true, id = undefined, data = "", dataLines = 0, eventType = undefined, pendingFragments.length = 0
|
|
35372
|
+
isFirstChunk = true, id = undefined, data = "", dataLines = 0, eventType = undefined, pendingFragments.length = 0;
|
|
34848
35373
|
}
|
|
34849
35374
|
return { feed, reset };
|
|
34850
35375
|
}
|
|
@@ -34868,7 +35393,7 @@ var EventSourceParserStream;
|
|
|
34868
35393
|
var init_stream = __esm(() => {
|
|
34869
35394
|
init_dist3();
|
|
34870
35395
|
EventSourceParserStream = class EventSourceParserStream extends TransformStream {
|
|
34871
|
-
constructor({ onError, onRetry, onComment
|
|
35396
|
+
constructor({ onError, onRetry, onComment } = {}) {
|
|
34872
35397
|
let parser;
|
|
34873
35398
|
super({
|
|
34874
35399
|
start(controller) {
|
|
@@ -34877,11 +35402,10 @@ var init_stream = __esm(() => {
|
|
|
34877
35402
|
controller.enqueue(event);
|
|
34878
35403
|
},
|
|
34879
35404
|
onError(error40) {
|
|
34880
|
-
|
|
35405
|
+
onError === "terminate" ? controller.error(error40) : typeof onError == "function" && onError(error40);
|
|
34881
35406
|
},
|
|
34882
35407
|
onRetry,
|
|
34883
|
-
onComment
|
|
34884
|
-
maxBufferSize
|
|
35408
|
+
onComment
|
|
34885
35409
|
});
|
|
34886
35410
|
},
|
|
34887
35411
|
transform(chunk) {
|
|
@@ -36320,7 +36844,7 @@ var DelayedPromise = class {
|
|
|
36320
36844
|
});
|
|
36321
36845
|
}
|
|
36322
36846
|
return () => `${prefix}${separator}${generator()}`;
|
|
36323
|
-
}, generateId, FETCH_FAILED_ERROR_MESSAGES, BUN_ERROR_CODES, VERSION = "4.0.
|
|
36847
|
+
}, generateId, FETCH_FAILED_ERROR_MESSAGES, BUN_ERROR_CODES, VERSION = "4.0.26", getOriginalFetch = () => globalThis.fetch, getFromApi = async ({
|
|
36324
36848
|
url: url2,
|
|
36325
36849
|
headers = {},
|
|
36326
36850
|
successfulResponseHandler,
|
|
@@ -38459,7 +38983,7 @@ var import_oidc, import_oidc2, marker17 = "vercel.ai.gateway.error", symbol18, _
|
|
|
38459
38983
|
"ai-model-id": this.modelId
|
|
38460
38984
|
};
|
|
38461
38985
|
}
|
|
38462
|
-
}, gatewayRerankingResponseSchema, parallelSearchInputSchema, parallelSearchOutputSchema, parallelSearchToolFactory, parallelSearch = (config2 = {}) => parallelSearchToolFactory(config2), perplexitySearchInputSchema, perplexitySearchOutputSchema, perplexitySearchToolFactory, perplexitySearch = (config2 = {}) => perplexitySearchToolFactory(config2), gatewayTools, VERSION2 = "3.0.
|
|
38986
|
+
}, gatewayRerankingResponseSchema, parallelSearchInputSchema, parallelSearchOutputSchema, parallelSearchToolFactory, parallelSearch = (config2 = {}) => parallelSearchToolFactory(config2), perplexitySearchInputSchema, perplexitySearchOutputSchema, perplexitySearchToolFactory, perplexitySearch = (config2 = {}) => perplexitySearchToolFactory(config2), gatewayTools, VERSION2 = "3.0.110", AI_GATEWAY_PROTOCOL_VERSION = "0.0.1", gateway;
|
|
38463
38987
|
var init_dist5 = __esm(() => {
|
|
38464
38988
|
init_dist4();
|
|
38465
38989
|
init_dist2();
|
|
@@ -38498,15 +39022,13 @@ var init_dist5 = __esm(() => {
|
|
|
38498
39022
|
message,
|
|
38499
39023
|
statusCode = 500,
|
|
38500
39024
|
cause,
|
|
38501
|
-
generationId
|
|
38502
|
-
isRetryable = statusCode != null && (statusCode === 408 || statusCode === 409 || statusCode === 429 || statusCode >= 500)
|
|
39025
|
+
generationId
|
|
38503
39026
|
}) {
|
|
38504
39027
|
super(generationId ? `${message} [${generationId}]` : message);
|
|
38505
39028
|
this[_a17] = true;
|
|
38506
39029
|
this.statusCode = statusCode;
|
|
38507
39030
|
this.cause = cause;
|
|
38508
39031
|
this.generationId = generationId;
|
|
38509
|
-
this.isRetryable = isRetryable;
|
|
38510
39032
|
}
|
|
38511
39033
|
static isInstance(error40) {
|
|
38512
39034
|
return _GatewayError.hasMarker(error40);
|
|
@@ -39029,11 +39551,62 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
|
|
|
39029
39551
|
gateway = createGatewayProvider();
|
|
39030
39552
|
});
|
|
39031
39553
|
|
|
39554
|
+
// node_modules/@opentelemetry/api/build/src/platform/node/globalThis.js
|
|
39555
|
+
var require_globalThis = __commonJS((exports) => {
|
|
39556
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39557
|
+
exports._globalThis = undefined;
|
|
39558
|
+
exports._globalThis = typeof globalThis === "object" ? globalThis : global;
|
|
39559
|
+
});
|
|
39560
|
+
|
|
39561
|
+
// node_modules/@opentelemetry/api/build/src/platform/node/index.js
|
|
39562
|
+
var require_node = __commonJS((exports) => {
|
|
39563
|
+
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
39564
|
+
if (k2 === undefined)
|
|
39565
|
+
k2 = k;
|
|
39566
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() {
|
|
39567
|
+
return m[k];
|
|
39568
|
+
} });
|
|
39569
|
+
} : function(o, m, k, k2) {
|
|
39570
|
+
if (k2 === undefined)
|
|
39571
|
+
k2 = k;
|
|
39572
|
+
o[k2] = m[k];
|
|
39573
|
+
});
|
|
39574
|
+
var __exportStar = exports && exports.__exportStar || function(m, exports2) {
|
|
39575
|
+
for (var p in m)
|
|
39576
|
+
if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p))
|
|
39577
|
+
__createBinding(exports2, m, p);
|
|
39578
|
+
};
|
|
39579
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39580
|
+
__exportStar(require_globalThis(), exports);
|
|
39581
|
+
});
|
|
39582
|
+
|
|
39583
|
+
// node_modules/@opentelemetry/api/build/src/platform/index.js
|
|
39584
|
+
var require_platform = __commonJS((exports) => {
|
|
39585
|
+
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
39586
|
+
if (k2 === undefined)
|
|
39587
|
+
k2 = k;
|
|
39588
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() {
|
|
39589
|
+
return m[k];
|
|
39590
|
+
} });
|
|
39591
|
+
} : function(o, m, k, k2) {
|
|
39592
|
+
if (k2 === undefined)
|
|
39593
|
+
k2 = k;
|
|
39594
|
+
o[k2] = m[k];
|
|
39595
|
+
});
|
|
39596
|
+
var __exportStar = exports && exports.__exportStar || function(m, exports2) {
|
|
39597
|
+
for (var p in m)
|
|
39598
|
+
if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p))
|
|
39599
|
+
__createBinding(exports2, m, p);
|
|
39600
|
+
};
|
|
39601
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39602
|
+
__exportStar(require_node(), exports);
|
|
39603
|
+
});
|
|
39604
|
+
|
|
39032
39605
|
// node_modules/@opentelemetry/api/build/src/version.js
|
|
39033
39606
|
var require_version = __commonJS((exports) => {
|
|
39034
39607
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39035
39608
|
exports.VERSION = undefined;
|
|
39036
|
-
exports.VERSION = "1.9.
|
|
39609
|
+
exports.VERSION = "1.9.0";
|
|
39037
39610
|
});
|
|
39038
39611
|
|
|
39039
39612
|
// node_modules/@opentelemetry/api/build/src/internal/semver.js
|
|
@@ -39111,11 +39684,12 @@ var require_semver = __commonJS((exports) => {
|
|
|
39111
39684
|
var require_global_utils = __commonJS((exports) => {
|
|
39112
39685
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39113
39686
|
exports.unregisterGlobal = exports.getGlobal = exports.registerGlobal = undefined;
|
|
39687
|
+
var platform_1 = require_platform();
|
|
39114
39688
|
var version_1 = require_version();
|
|
39115
39689
|
var semver_1 = require_semver();
|
|
39116
39690
|
var major = version_1.VERSION.split(".")[0];
|
|
39117
39691
|
var GLOBAL_OPENTELEMETRY_API_KEY = Symbol.for(`opentelemetry.js.api.${major}`);
|
|
39118
|
-
var _global =
|
|
39692
|
+
var _global = platform_1._globalThis;
|
|
39119
39693
|
function registerGlobal(type, instance, diag, allowOverride = false) {
|
|
39120
39694
|
var _a16;
|
|
39121
39695
|
const api2 = _global[GLOBAL_OPENTELEMETRY_API_KEY] = (_a16 = _global[GLOBAL_OPENTELEMETRY_API_KEY]) !== null && _a16 !== undefined ? _a16 : {
|
|
@@ -39187,7 +39761,8 @@ var require_ComponentLogger = __commonJS((exports) => {
|
|
|
39187
39761
|
if (!logger) {
|
|
39188
39762
|
return;
|
|
39189
39763
|
}
|
|
39190
|
-
|
|
39764
|
+
args.unshift(namespace);
|
|
39765
|
+
return logger[funcName](...args);
|
|
39191
39766
|
}
|
|
39192
39767
|
});
|
|
39193
39768
|
|
|
@@ -39248,12 +39823,6 @@ var require_diag = __commonJS((exports) => {
|
|
|
39248
39823
|
var API_NAME = "diag";
|
|
39249
39824
|
|
|
39250
39825
|
class DiagAPI {
|
|
39251
|
-
static instance() {
|
|
39252
|
-
if (!this._instance) {
|
|
39253
|
-
this._instance = new DiagAPI;
|
|
39254
|
-
}
|
|
39255
|
-
return this._instance;
|
|
39256
|
-
}
|
|
39257
39826
|
constructor() {
|
|
39258
39827
|
function _logProxy(funcName) {
|
|
39259
39828
|
return function(...args) {
|
|
@@ -39298,6 +39867,12 @@ var require_diag = __commonJS((exports) => {
|
|
|
39298
39867
|
self2.warn = _logProxy("warn");
|
|
39299
39868
|
self2.error = _logProxy("error");
|
|
39300
39869
|
}
|
|
39870
|
+
static instance() {
|
|
39871
|
+
if (!this._instance) {
|
|
39872
|
+
this._instance = new DiagAPI;
|
|
39873
|
+
}
|
|
39874
|
+
return this._instance;
|
|
39875
|
+
}
|
|
39301
39876
|
}
|
|
39302
39877
|
exports.DiagAPI = DiagAPI;
|
|
39303
39878
|
});
|
|
@@ -39319,7 +39894,7 @@ var require_baggage_impl = __commonJS((exports) => {
|
|
|
39319
39894
|
return Object.assign({}, entry);
|
|
39320
39895
|
}
|
|
39321
39896
|
getAllEntries() {
|
|
39322
|
-
return Array.from(this._entries.entries());
|
|
39897
|
+
return Array.from(this._entries.entries()).map(([k, v]) => [k, v]);
|
|
39323
39898
|
}
|
|
39324
39899
|
setEntry(key, entry) {
|
|
39325
39900
|
const newBaggage = new BaggageImpl(this._entries);
|
|
@@ -39411,7 +39986,7 @@ var require_context = __commonJS((exports) => {
|
|
|
39411
39986
|
// node_modules/@opentelemetry/api/build/src/diag/consoleLogger.js
|
|
39412
39987
|
var require_consoleLogger = __commonJS((exports) => {
|
|
39413
39988
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39414
|
-
exports.DiagConsoleLogger =
|
|
39989
|
+
exports.DiagConsoleLogger = undefined;
|
|
39415
39990
|
var consoleMap = [
|
|
39416
39991
|
{ n: "error", c: "error" },
|
|
39417
39992
|
{ n: "warn", c: "warn" },
|
|
@@ -39419,39 +39994,19 @@ var require_consoleLogger = __commonJS((exports) => {
|
|
|
39419
39994
|
{ n: "debug", c: "debug" },
|
|
39420
39995
|
{ n: "verbose", c: "trace" }
|
|
39421
39996
|
];
|
|
39422
|
-
exports._originalConsoleMethods = {};
|
|
39423
|
-
if (typeof console !== "undefined") {
|
|
39424
|
-
const keys = [
|
|
39425
|
-
"error",
|
|
39426
|
-
"warn",
|
|
39427
|
-
"info",
|
|
39428
|
-
"debug",
|
|
39429
|
-
"trace",
|
|
39430
|
-
"log"
|
|
39431
|
-
];
|
|
39432
|
-
for (const key of keys) {
|
|
39433
|
-
if (typeof console[key] === "function") {
|
|
39434
|
-
exports._originalConsoleMethods[key] = console[key];
|
|
39435
|
-
}
|
|
39436
|
-
}
|
|
39437
|
-
}
|
|
39438
39997
|
|
|
39439
39998
|
class DiagConsoleLogger {
|
|
39440
39999
|
constructor() {
|
|
39441
40000
|
function _consoleFunc(funcName) {
|
|
39442
40001
|
return function(...args) {
|
|
39443
|
-
|
|
39444
|
-
|
|
39445
|
-
theFunc = exports._originalConsoleMethods["log"];
|
|
39446
|
-
}
|
|
39447
|
-
if (typeof theFunc !== "function" && console) {
|
|
39448
|
-
theFunc = console[funcName];
|
|
40002
|
+
if (console) {
|
|
40003
|
+
let theFunc = console[funcName];
|
|
39449
40004
|
if (typeof theFunc !== "function") {
|
|
39450
40005
|
theFunc = console.log;
|
|
39451
40006
|
}
|
|
39452
|
-
|
|
39453
|
-
|
|
39454
|
-
|
|
40007
|
+
if (typeof theFunc === "function") {
|
|
40008
|
+
return theFunc.apply(console, args);
|
|
40009
|
+
}
|
|
39455
40010
|
}
|
|
39456
40011
|
};
|
|
39457
40012
|
}
|
|
@@ -39689,8 +40244,8 @@ var require_NonRecordingSpan = __commonJS((exports) => {
|
|
|
39689
40244
|
var invalid_span_constants_1 = require_invalid_span_constants();
|
|
39690
40245
|
|
|
39691
40246
|
class NonRecordingSpan {
|
|
39692
|
-
constructor(
|
|
39693
|
-
this._spanContext =
|
|
40247
|
+
constructor(_spanContext = invalid_span_constants_1.INVALID_SPAN_CONTEXT) {
|
|
40248
|
+
this._spanContext = _spanContext;
|
|
39694
40249
|
}
|
|
39695
40250
|
spanContext() {
|
|
39696
40251
|
return this._spanContext;
|
|
@@ -39766,126 +40321,14 @@ var require_spancontext_utils = __commonJS((exports) => {
|
|
|
39766
40321
|
exports.wrapSpanContext = exports.isSpanContextValid = exports.isValidSpanId = exports.isValidTraceId = undefined;
|
|
39767
40322
|
var invalid_span_constants_1 = require_invalid_span_constants();
|
|
39768
40323
|
var NonRecordingSpan_1 = require_NonRecordingSpan();
|
|
39769
|
-
var
|
|
39770
|
-
|
|
39771
|
-
0,
|
|
39772
|
-
0,
|
|
39773
|
-
0,
|
|
39774
|
-
0,
|
|
39775
|
-
0,
|
|
39776
|
-
0,
|
|
39777
|
-
0,
|
|
39778
|
-
0,
|
|
39779
|
-
0,
|
|
39780
|
-
0,
|
|
39781
|
-
0,
|
|
39782
|
-
0,
|
|
39783
|
-
0,
|
|
39784
|
-
0,
|
|
39785
|
-
0,
|
|
39786
|
-
0,
|
|
39787
|
-
0,
|
|
39788
|
-
0,
|
|
39789
|
-
0,
|
|
39790
|
-
0,
|
|
39791
|
-
0,
|
|
39792
|
-
0,
|
|
39793
|
-
0,
|
|
39794
|
-
0,
|
|
39795
|
-
0,
|
|
39796
|
-
0,
|
|
39797
|
-
0,
|
|
39798
|
-
0,
|
|
39799
|
-
0,
|
|
39800
|
-
0,
|
|
39801
|
-
0,
|
|
39802
|
-
0,
|
|
39803
|
-
0,
|
|
39804
|
-
0,
|
|
39805
|
-
0,
|
|
39806
|
-
0,
|
|
39807
|
-
0,
|
|
39808
|
-
0,
|
|
39809
|
-
0,
|
|
39810
|
-
0,
|
|
39811
|
-
0,
|
|
39812
|
-
0,
|
|
39813
|
-
0,
|
|
39814
|
-
0,
|
|
39815
|
-
0,
|
|
39816
|
-
0,
|
|
39817
|
-
0,
|
|
39818
|
-
1,
|
|
39819
|
-
1,
|
|
39820
|
-
1,
|
|
39821
|
-
1,
|
|
39822
|
-
1,
|
|
39823
|
-
1,
|
|
39824
|
-
1,
|
|
39825
|
-
1,
|
|
39826
|
-
1,
|
|
39827
|
-
1,
|
|
39828
|
-
0,
|
|
39829
|
-
0,
|
|
39830
|
-
0,
|
|
39831
|
-
0,
|
|
39832
|
-
0,
|
|
39833
|
-
0,
|
|
39834
|
-
0,
|
|
39835
|
-
1,
|
|
39836
|
-
1,
|
|
39837
|
-
1,
|
|
39838
|
-
1,
|
|
39839
|
-
1,
|
|
39840
|
-
1,
|
|
39841
|
-
0,
|
|
39842
|
-
0,
|
|
39843
|
-
0,
|
|
39844
|
-
0,
|
|
39845
|
-
0,
|
|
39846
|
-
0,
|
|
39847
|
-
0,
|
|
39848
|
-
0,
|
|
39849
|
-
0,
|
|
39850
|
-
0,
|
|
39851
|
-
0,
|
|
39852
|
-
0,
|
|
39853
|
-
0,
|
|
39854
|
-
0,
|
|
39855
|
-
0,
|
|
39856
|
-
0,
|
|
39857
|
-
0,
|
|
39858
|
-
0,
|
|
39859
|
-
0,
|
|
39860
|
-
0,
|
|
39861
|
-
0,
|
|
39862
|
-
0,
|
|
39863
|
-
0,
|
|
39864
|
-
0,
|
|
39865
|
-
0,
|
|
39866
|
-
0,
|
|
39867
|
-
1,
|
|
39868
|
-
1,
|
|
39869
|
-
1,
|
|
39870
|
-
1,
|
|
39871
|
-
1,
|
|
39872
|
-
1
|
|
39873
|
-
]);
|
|
39874
|
-
function isValidHex(id, length) {
|
|
39875
|
-
if (typeof id !== "string" || id.length !== length)
|
|
39876
|
-
return false;
|
|
39877
|
-
let r = 0;
|
|
39878
|
-
for (let i = 0;i < id.length; i += 4) {
|
|
39879
|
-
r += (isHex[id.charCodeAt(i)] | 0) + (isHex[id.charCodeAt(i + 1)] | 0) + (isHex[id.charCodeAt(i + 2)] | 0) + (isHex[id.charCodeAt(i + 3)] | 0);
|
|
39880
|
-
}
|
|
39881
|
-
return r === length;
|
|
39882
|
-
}
|
|
40324
|
+
var VALID_TRACEID_REGEX = /^([0-9a-f]{32})$/i;
|
|
40325
|
+
var VALID_SPANID_REGEX = /^[0-9a-f]{16}$/i;
|
|
39883
40326
|
function isValidTraceId(traceId) {
|
|
39884
|
-
return
|
|
40327
|
+
return VALID_TRACEID_REGEX.test(traceId) && traceId !== invalid_span_constants_1.INVALID_TRACEID;
|
|
39885
40328
|
}
|
|
39886
40329
|
exports.isValidTraceId = isValidTraceId;
|
|
39887
40330
|
function isValidSpanId(spanId) {
|
|
39888
|
-
return
|
|
40331
|
+
return VALID_SPANID_REGEX.test(spanId) && spanId !== invalid_span_constants_1.INVALID_SPANID;
|
|
39889
40332
|
}
|
|
39890
40333
|
exports.isValidSpanId = isValidSpanId;
|
|
39891
40334
|
function isSpanContextValid(spanContext) {
|
|
@@ -39945,7 +40388,7 @@ var require_NoopTracer = __commonJS((exports) => {
|
|
|
39945
40388
|
}
|
|
39946
40389
|
exports.NoopTracer = NoopTracer;
|
|
39947
40390
|
function isSpanContext(spanContext) {
|
|
39948
|
-
return
|
|
40391
|
+
return typeof spanContext === "object" && typeof spanContext["spanId"] === "string" && typeof spanContext["traceId"] === "string" && typeof spanContext["traceFlags"] === "number";
|
|
39949
40392
|
}
|
|
39950
40393
|
});
|
|
39951
40394
|
|
|
@@ -39957,8 +40400,8 @@ var require_ProxyTracer = __commonJS((exports) => {
|
|
|
39957
40400
|
var NOOP_TRACER = new NoopTracer_1.NoopTracer;
|
|
39958
40401
|
|
|
39959
40402
|
class ProxyTracer {
|
|
39960
|
-
constructor(
|
|
39961
|
-
this._provider =
|
|
40403
|
+
constructor(_provider, name15, version2, options) {
|
|
40404
|
+
this._provider = _provider;
|
|
39962
40405
|
this.name = name15;
|
|
39963
40406
|
this.version = version2;
|
|
39964
40407
|
this.options = options;
|
|
@@ -40118,7 +40561,7 @@ var require_tracestate_impl = __commonJS((exports) => {
|
|
|
40118
40561
|
return this._internalState.get(key);
|
|
40119
40562
|
}
|
|
40120
40563
|
serialize() {
|
|
40121
|
-
return
|
|
40564
|
+
return this._keys().reduce((agg, key) => {
|
|
40122
40565
|
agg.push(key + LIST_MEMBER_KEY_VALUE_SPLITTER + this.get(key));
|
|
40123
40566
|
return agg;
|
|
40124
40567
|
}, []).join(LIST_MEMBERS_SEPARATOR);
|
|
@@ -40126,7 +40569,7 @@ var require_tracestate_impl = __commonJS((exports) => {
|
|
|
40126
40569
|
_parse(rawTraceState) {
|
|
40127
40570
|
if (rawTraceState.length > MAX_TRACE_STATE_LEN)
|
|
40128
40571
|
return;
|
|
40129
|
-
this._internalState = rawTraceState.split(LIST_MEMBERS_SEPARATOR).
|
|
40572
|
+
this._internalState = rawTraceState.split(LIST_MEMBERS_SEPARATOR).reverse().reduce((agg, part) => {
|
|
40130
40573
|
const listMember = part.trim();
|
|
40131
40574
|
const i = listMember.indexOf(LIST_MEMBER_KEY_VALUE_SPLITTER);
|
|
40132
40575
|
if (i !== -1) {
|
|
@@ -41226,10 +41669,7 @@ function convertToLanguageModelMessage({
|
|
|
41226
41669
|
type: "tool-result",
|
|
41227
41670
|
toolCallId: part.toolCallId,
|
|
41228
41671
|
toolName: part.toolName,
|
|
41229
|
-
output: mapToolResultOutput(
|
|
41230
|
-
output: part.output,
|
|
41231
|
-
downloadedAssets
|
|
41232
|
-
}),
|
|
41672
|
+
output: mapToolResultOutput(part.output),
|
|
41233
41673
|
providerOptions
|
|
41234
41674
|
};
|
|
41235
41675
|
}
|
|
@@ -41248,10 +41688,7 @@ function convertToLanguageModelMessage({
|
|
|
41248
41688
|
type: "tool-result",
|
|
41249
41689
|
toolCallId: part.toolCallId,
|
|
41250
41690
|
toolName: part.toolName,
|
|
41251
|
-
output: mapToolResultOutput(
|
|
41252
|
-
output: part.output,
|
|
41253
|
-
downloadedAssets
|
|
41254
|
-
}),
|
|
41691
|
+
output: mapToolResultOutput(part.output),
|
|
41255
41692
|
providerOptions: part.providerOptions
|
|
41256
41693
|
};
|
|
41257
41694
|
}
|
|
@@ -41275,44 +41712,15 @@ function convertToLanguageModelMessage({
|
|
|
41275
41712
|
}
|
|
41276
41713
|
}
|
|
41277
41714
|
async function downloadAssets(messages, download2, supportedUrls) {
|
|
41278
|
-
|
|
41279
|
-
|
|
41280
|
-
|
|
41281
|
-
|
|
41282
|
-
|
|
41283
|
-
|
|
41284
|
-
|
|
41285
|
-
|
|
41286
|
-
mediaType: (_a21 = part.mediaType) != null ? _a21 : part.type === "image" ? "image/*" : undefined
|
|
41287
|
-
});
|
|
41288
|
-
}
|
|
41289
|
-
}
|
|
41290
|
-
}
|
|
41291
|
-
if (message.role === "tool" || message.role === "assistant") {
|
|
41292
|
-
if (!Array.isArray(message.content)) {
|
|
41293
|
-
continue;
|
|
41294
|
-
}
|
|
41295
|
-
for (const part of message.content) {
|
|
41296
|
-
if (part.type !== "tool-result") {
|
|
41297
|
-
continue;
|
|
41298
|
-
}
|
|
41299
|
-
if (part.output.type !== "content") {
|
|
41300
|
-
continue;
|
|
41301
|
-
}
|
|
41302
|
-
for (const contentPart of part.output.value) {
|
|
41303
|
-
if (contentPart.type === "image-url" || contentPart.type === "file-url") {
|
|
41304
|
-
downloadableFiles.push({
|
|
41305
|
-
data: new URL(contentPart.url),
|
|
41306
|
-
mediaType: contentPart.type === "image-url" ? "image/*" : undefined
|
|
41307
|
-
});
|
|
41308
|
-
}
|
|
41309
|
-
}
|
|
41310
|
-
}
|
|
41715
|
+
const plannedDownloads = messages.filter((message) => message.role === "user").map((message) => message.content).filter((content) => Array.isArray(content)).flat().filter((part) => part.type === "image" || part.type === "file").map((part) => {
|
|
41716
|
+
var _a21;
|
|
41717
|
+
const mediaType = (_a21 = part.mediaType) != null ? _a21 : part.type === "image" ? "image/*" : undefined;
|
|
41718
|
+
let data = part.type === "image" ? part.image : part.data;
|
|
41719
|
+
if (typeof data === "string") {
|
|
41720
|
+
try {
|
|
41721
|
+
data = new URL(data);
|
|
41722
|
+
} catch (ignored) {}
|
|
41311
41723
|
}
|
|
41312
|
-
}
|
|
41313
|
-
const plannedDownloads = downloadableFiles.map((part) => {
|
|
41314
|
-
const mediaType = part.mediaType;
|
|
41315
|
-
const { data } = convertToLanguageModelV3DataContent(part.data);
|
|
41316
41724
|
return { mediaType, data };
|
|
41317
41725
|
}).filter((part) => part.data instanceof URL).map((part) => ({
|
|
41318
41726
|
url: part.data,
|
|
@@ -41386,41 +41794,13 @@ function convertPartToLanguageModelPart(part, downloadedAssets) {
|
|
|
41386
41794
|
}
|
|
41387
41795
|
}
|
|
41388
41796
|
}
|
|
41389
|
-
function mapToolResultOutput({
|
|
41390
|
-
output,
|
|
41391
|
-
downloadedAssets
|
|
41392
|
-
}) {
|
|
41797
|
+
function mapToolResultOutput(output) {
|
|
41393
41798
|
if (output.type !== "content") {
|
|
41394
41799
|
return output;
|
|
41395
41800
|
}
|
|
41396
41801
|
return {
|
|
41397
41802
|
type: "content",
|
|
41398
41803
|
value: output.value.map((item) => {
|
|
41399
|
-
var _a21, _b16;
|
|
41400
|
-
if (item.type === "image-url") {
|
|
41401
|
-
const downloadedFile = downloadedAssets[new URL(item.url).toString()];
|
|
41402
|
-
if (downloadedFile) {
|
|
41403
|
-
return {
|
|
41404
|
-
type: "image-data",
|
|
41405
|
-
data: convertDataContentToBase64String(downloadedFile.data),
|
|
41406
|
-
mediaType: (_a21 = downloadedFile.mediaType) != null ? _a21 : "image/*",
|
|
41407
|
-
providerOptions: item.providerOptions
|
|
41408
|
-
};
|
|
41409
|
-
}
|
|
41410
|
-
return item;
|
|
41411
|
-
}
|
|
41412
|
-
if (item.type === "file-url") {
|
|
41413
|
-
const downloadedFile = downloadedAssets[new URL(item.url).toString()];
|
|
41414
|
-
if (downloadedFile) {
|
|
41415
|
-
return {
|
|
41416
|
-
type: "file-data",
|
|
41417
|
-
data: convertDataContentToBase64String(downloadedFile.data),
|
|
41418
|
-
mediaType: (_b16 = downloadedFile.mediaType) != null ? _b16 : "application/octet-stream",
|
|
41419
|
-
providerOptions: item.providerOptions
|
|
41420
|
-
};
|
|
41421
|
-
}
|
|
41422
|
-
return item;
|
|
41423
|
-
}
|
|
41424
41804
|
if (item.type !== "media") {
|
|
41425
41805
|
return item;
|
|
41426
41806
|
}
|
|
@@ -41973,7 +42353,7 @@ function getRetryDelayInMs({
|
|
|
41973
42353
|
error: error40,
|
|
41974
42354
|
exponentialBackoffDelay
|
|
41975
42355
|
}) {
|
|
41976
|
-
const headers =
|
|
42356
|
+
const headers = error40.responseHeaders;
|
|
41977
42357
|
if (!headers)
|
|
41978
42358
|
return exponentialBackoffDelay;
|
|
41979
42359
|
let ms;
|
|
@@ -42023,7 +42403,7 @@ async function _retryWithExponentialBackoff(f, {
|
|
|
42023
42403
|
errors: newErrors
|
|
42024
42404
|
});
|
|
42025
42405
|
}
|
|
42026
|
-
if (error40 instanceof Error &&
|
|
42406
|
+
if (error40 instanceof Error && APICallError.isInstance(error40) && error40.isRetryable === true && tryNumber <= maxRetries) {
|
|
42027
42407
|
await delay(getRetryDelayInMs({
|
|
42028
42408
|
error: error40,
|
|
42029
42409
|
exponentialBackoffDelay: delayInMs
|
|
@@ -42241,8 +42621,7 @@ async function executeToolCall({
|
|
|
42241
42621
|
input,
|
|
42242
42622
|
error: error40,
|
|
42243
42623
|
dynamic: tool2.type === "dynamic",
|
|
42244
|
-
...toolCall.providerMetadata != null ? { providerMetadata: toolCall.providerMetadata } : {}
|
|
42245
|
-
...toolCall.toolMetadata != null ? { toolMetadata: toolCall.toolMetadata } : {}
|
|
42624
|
+
...toolCall.providerMetadata != null ? { providerMetadata: toolCall.providerMetadata } : {}
|
|
42246
42625
|
};
|
|
42247
42626
|
}
|
|
42248
42627
|
const durationMs = now2() - startTime;
|
|
@@ -42272,8 +42651,7 @@ async function executeToolCall({
|
|
|
42272
42651
|
input,
|
|
42273
42652
|
output,
|
|
42274
42653
|
dynamic: tool2.type === "dynamic",
|
|
42275
|
-
...toolCall.providerMetadata != null ? { providerMetadata: toolCall.providerMetadata } : {}
|
|
42276
|
-
...toolCall.toolMetadata != null ? { toolMetadata: toolCall.toolMetadata } : {}
|
|
42654
|
+
...toolCall.providerMetadata != null ? { providerMetadata: toolCall.providerMetadata } : {}
|
|
42277
42655
|
};
|
|
42278
42656
|
}
|
|
42279
42657
|
});
|
|
@@ -42638,6 +43016,15 @@ async function parsePartialJson(jsonText) {
|
|
|
42638
43016
|
}
|
|
42639
43017
|
return { value: undefined, state: "failed-parse" };
|
|
42640
43018
|
}
|
|
43019
|
+
function mergeToolProviderMetadata(toolMetadata, callMetadata) {
|
|
43020
|
+
if (toolMetadata == null) {
|
|
43021
|
+
return callMetadata;
|
|
43022
|
+
}
|
|
43023
|
+
if (callMetadata == null) {
|
|
43024
|
+
return toolMetadata;
|
|
43025
|
+
}
|
|
43026
|
+
return { ...toolMetadata, ...callMetadata };
|
|
43027
|
+
}
|
|
42641
43028
|
async function parseToolCall({
|
|
42642
43029
|
toolCall,
|
|
42643
43030
|
tools,
|
|
@@ -42645,6 +43032,7 @@ async function parseToolCall({
|
|
|
42645
43032
|
system,
|
|
42646
43033
|
messages
|
|
42647
43034
|
}) {
|
|
43035
|
+
var _a21, _b16;
|
|
42648
43036
|
try {
|
|
42649
43037
|
if (tools == null) {
|
|
42650
43038
|
if (toolCall.providerExecuted && toolCall.dynamic) {
|
|
@@ -42685,7 +43073,6 @@ async function parseToolCall({
|
|
|
42685
43073
|
} catch (error40) {
|
|
42686
43074
|
const parsedInput = await safeParseJSON({ text: toolCall.input });
|
|
42687
43075
|
const input = parsedInput.success ? parsedInput.value : toolCall.input;
|
|
42688
|
-
const tool2 = tools == null ? undefined : tools[toolCall.toolName];
|
|
42689
43076
|
return {
|
|
42690
43077
|
type: "tool-call",
|
|
42691
43078
|
toolCallId: toolCall.toolCallId,
|
|
@@ -42694,10 +43081,9 @@ async function parseToolCall({
|
|
|
42694
43081
|
dynamic: true,
|
|
42695
43082
|
invalid: true,
|
|
42696
43083
|
error: error40,
|
|
42697
|
-
title:
|
|
43084
|
+
title: (_a21 = tools == null ? undefined : tools[toolCall.toolName]) == null ? undefined : _a21.title,
|
|
42698
43085
|
providerExecuted: toolCall.providerExecuted,
|
|
42699
|
-
providerMetadata: toolCall.providerMetadata,
|
|
42700
|
-
...(tool2 == null ? undefined : tool2.metadata) != null ? { toolMetadata: tool2.metadata } : {}
|
|
43086
|
+
providerMetadata: mergeToolProviderMetadata((_b16 = tools == null ? undefined : tools[toolCall.toolName]) == null ? undefined : _b16.providerMetadata, toolCall.providerMetadata)
|
|
42701
43087
|
};
|
|
42702
43088
|
}
|
|
42703
43089
|
}
|
|
@@ -42744,14 +43130,14 @@ async function doParseToolCall({
|
|
|
42744
43130
|
cause: parseResult.error
|
|
42745
43131
|
});
|
|
42746
43132
|
}
|
|
43133
|
+
const mergedProviderMetadata = mergeToolProviderMetadata(tool2.providerMetadata, toolCall.providerMetadata);
|
|
42747
43134
|
return tool2.type === "dynamic" ? {
|
|
42748
43135
|
type: "tool-call",
|
|
42749
43136
|
toolCallId: toolCall.toolCallId,
|
|
42750
43137
|
toolName: toolCall.toolName,
|
|
42751
43138
|
input: parseResult.value,
|
|
42752
43139
|
providerExecuted: toolCall.providerExecuted,
|
|
42753
|
-
providerMetadata:
|
|
42754
|
-
...tool2.metadata != null ? { toolMetadata: tool2.metadata } : {},
|
|
43140
|
+
providerMetadata: mergedProviderMetadata,
|
|
42755
43141
|
dynamic: true,
|
|
42756
43142
|
title: tool2.title
|
|
42757
43143
|
} : {
|
|
@@ -42760,8 +43146,7 @@ async function doParseToolCall({
|
|
|
42760
43146
|
toolName,
|
|
42761
43147
|
input: parseResult.value,
|
|
42762
43148
|
providerExecuted: toolCall.providerExecuted,
|
|
42763
|
-
providerMetadata:
|
|
42764
|
-
...tool2.metadata != null ? { toolMetadata: tool2.metadata } : {},
|
|
43149
|
+
providerMetadata: mergedProviderMetadata,
|
|
42765
43150
|
title: tool2.title
|
|
42766
43151
|
};
|
|
42767
43152
|
}
|
|
@@ -43593,8 +43978,7 @@ function asContent({
|
|
|
43593
43978
|
error: part.result,
|
|
43594
43979
|
providerExecuted: true,
|
|
43595
43980
|
dynamic: part.dynamic,
|
|
43596
|
-
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
43597
|
-
...(tool2 == null ? undefined : tool2.metadata) != null ? { toolMetadata: tool2.metadata } : {}
|
|
43981
|
+
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
43598
43982
|
});
|
|
43599
43983
|
} else {
|
|
43600
43984
|
contentParts.push({
|
|
@@ -43605,8 +43989,7 @@ function asContent({
|
|
|
43605
43989
|
output: part.result,
|
|
43606
43990
|
providerExecuted: true,
|
|
43607
43991
|
dynamic: part.dynamic,
|
|
43608
|
-
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
43609
|
-
...(tool2 == null ? undefined : tool2.metadata) != null ? { toolMetadata: tool2.metadata } : {}
|
|
43992
|
+
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
43610
43993
|
});
|
|
43611
43994
|
}
|
|
43612
43995
|
break;
|
|
@@ -43620,8 +44003,7 @@ function asContent({
|
|
|
43620
44003
|
error: part.result,
|
|
43621
44004
|
providerExecuted: true,
|
|
43622
44005
|
dynamic: toolCall.dynamic,
|
|
43623
|
-
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
43624
|
-
...toolCall.toolMetadata != null ? { toolMetadata: toolCall.toolMetadata } : {}
|
|
44006
|
+
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
43625
44007
|
});
|
|
43626
44008
|
} else {
|
|
43627
44009
|
contentParts.push({
|
|
@@ -43632,8 +44014,7 @@ function asContent({
|
|
|
43632
44014
|
output: part.result,
|
|
43633
44015
|
providerExecuted: true,
|
|
43634
44016
|
dynamic: toolCall.dynamic,
|
|
43635
|
-
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
43636
|
-
...toolCall.toolMetadata != null ? { toolMetadata: toolCall.toolMetadata } : {}
|
|
44017
|
+
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
43637
44018
|
});
|
|
43638
44019
|
}
|
|
43639
44020
|
break;
|
|
@@ -43847,9 +44228,6 @@ function processUIMessageStream({
|
|
|
43847
44228
|
if (options.title !== undefined) {
|
|
43848
44229
|
anyPart.title = options.title;
|
|
43849
44230
|
}
|
|
43850
|
-
if (options.toolMetadata !== undefined) {
|
|
43851
|
-
anyPart.toolMetadata = options.toolMetadata;
|
|
43852
|
-
}
|
|
43853
44231
|
anyPart.providerExecuted = (_a222 = anyOptions.providerExecuted) != null ? _a222 : part.providerExecuted;
|
|
43854
44232
|
const providerMetadata = anyOptions.providerMetadata;
|
|
43855
44233
|
if (providerMetadata != null) {
|
|
@@ -43866,7 +44244,6 @@ function processUIMessageStream({
|
|
|
43866
44244
|
toolCallId: options.toolCallId,
|
|
43867
44245
|
state: options.state,
|
|
43868
44246
|
title: options.title,
|
|
43869
|
-
...options.toolMetadata !== undefined ? { toolMetadata: options.toolMetadata } : {},
|
|
43870
44247
|
input: anyOptions.input,
|
|
43871
44248
|
output: anyOptions.output,
|
|
43872
44249
|
rawInput: anyOptions.rawInput,
|
|
@@ -43894,9 +44271,6 @@ function processUIMessageStream({
|
|
|
43894
44271
|
if (options.title !== undefined) {
|
|
43895
44272
|
anyPart.title = options.title;
|
|
43896
44273
|
}
|
|
43897
|
-
if (options.toolMetadata !== undefined) {
|
|
43898
|
-
anyPart.toolMetadata = options.toolMetadata;
|
|
43899
|
-
}
|
|
43900
44274
|
anyPart.providerExecuted = (_b23 = anyOptions.providerExecuted) != null ? _b23 : part.providerExecuted;
|
|
43901
44275
|
const providerMetadata = anyOptions.providerMetadata;
|
|
43902
44276
|
if (providerMetadata != null) {
|
|
@@ -43919,7 +44293,6 @@ function processUIMessageStream({
|
|
|
43919
44293
|
preliminary: anyOptions.preliminary,
|
|
43920
44294
|
providerExecuted: anyOptions.providerExecuted,
|
|
43921
44295
|
title: options.title,
|
|
43922
|
-
...options.toolMetadata !== undefined ? { toolMetadata: options.toolMetadata } : {},
|
|
43923
44296
|
...anyOptions.providerMetadata != null && (options.state === "output-available" || options.state === "output-error") ? { resultProviderMetadata: anyOptions.providerMetadata } : {},
|
|
43924
44297
|
...anyOptions.providerMetadata != null && !(options.state === "output-available" || options.state === "output-error") ? { callProviderMetadata: anyOptions.providerMetadata } : {}
|
|
43925
44298
|
});
|
|
@@ -44064,8 +44437,7 @@ function processUIMessageStream({
|
|
|
44064
44437
|
toolName: chunk.toolName,
|
|
44065
44438
|
index: toolInvocations.length,
|
|
44066
44439
|
dynamic: chunk.dynamic,
|
|
44067
|
-
title: chunk.title
|
|
44068
|
-
toolMetadata: chunk.toolMetadata
|
|
44440
|
+
title: chunk.title
|
|
44069
44441
|
};
|
|
44070
44442
|
if (chunk.dynamic) {
|
|
44071
44443
|
updateDynamicToolPart({
|
|
@@ -44075,7 +44447,6 @@ function processUIMessageStream({
|
|
|
44075
44447
|
input: undefined,
|
|
44076
44448
|
providerExecuted: chunk.providerExecuted,
|
|
44077
44449
|
title: chunk.title,
|
|
44078
|
-
toolMetadata: chunk.toolMetadata,
|
|
44079
44450
|
providerMetadata: chunk.providerMetadata
|
|
44080
44451
|
});
|
|
44081
44452
|
} else {
|
|
@@ -44086,7 +44457,6 @@ function processUIMessageStream({
|
|
|
44086
44457
|
input: undefined,
|
|
44087
44458
|
providerExecuted: chunk.providerExecuted,
|
|
44088
44459
|
title: chunk.title,
|
|
44089
|
-
toolMetadata: chunk.toolMetadata,
|
|
44090
44460
|
providerMetadata: chunk.providerMetadata
|
|
44091
44461
|
});
|
|
44092
44462
|
}
|
|
@@ -44110,8 +44480,7 @@ function processUIMessageStream({
|
|
|
44110
44480
|
toolName: partialToolCall.toolName,
|
|
44111
44481
|
state: "input-streaming",
|
|
44112
44482
|
input: partialArgs,
|
|
44113
|
-
title: partialToolCall.title
|
|
44114
|
-
toolMetadata: partialToolCall.toolMetadata
|
|
44483
|
+
title: partialToolCall.title
|
|
44115
44484
|
});
|
|
44116
44485
|
} else {
|
|
44117
44486
|
updateToolPart({
|
|
@@ -44119,8 +44488,7 @@ function processUIMessageStream({
|
|
|
44119
44488
|
toolName: partialToolCall.toolName,
|
|
44120
44489
|
state: "input-streaming",
|
|
44121
44490
|
input: partialArgs,
|
|
44122
|
-
title: partialToolCall.title
|
|
44123
|
-
toolMetadata: partialToolCall.toolMetadata
|
|
44491
|
+
title: partialToolCall.title
|
|
44124
44492
|
});
|
|
44125
44493
|
}
|
|
44126
44494
|
write();
|
|
@@ -44135,8 +44503,7 @@ function processUIMessageStream({
|
|
|
44135
44503
|
input: chunk.input,
|
|
44136
44504
|
providerExecuted: chunk.providerExecuted,
|
|
44137
44505
|
providerMetadata: chunk.providerMetadata,
|
|
44138
|
-
title: chunk.title
|
|
44139
|
-
toolMetadata: chunk.toolMetadata
|
|
44506
|
+
title: chunk.title
|
|
44140
44507
|
});
|
|
44141
44508
|
} else {
|
|
44142
44509
|
updateToolPart({
|
|
@@ -44146,8 +44513,7 @@ function processUIMessageStream({
|
|
|
44146
44513
|
input: chunk.input,
|
|
44147
44514
|
providerExecuted: chunk.providerExecuted,
|
|
44148
44515
|
providerMetadata: chunk.providerMetadata,
|
|
44149
|
-
title: chunk.title
|
|
44150
|
-
toolMetadata: chunk.toolMetadata
|
|
44516
|
+
title: chunk.title
|
|
44151
44517
|
});
|
|
44152
44518
|
}
|
|
44153
44519
|
write();
|
|
@@ -44169,8 +44535,7 @@ function processUIMessageStream({
|
|
|
44169
44535
|
input: chunk.input,
|
|
44170
44536
|
errorText: chunk.errorText,
|
|
44171
44537
|
providerExecuted: chunk.providerExecuted,
|
|
44172
|
-
providerMetadata: chunk.providerMetadata
|
|
44173
|
-
toolMetadata: chunk.toolMetadata
|
|
44538
|
+
providerMetadata: chunk.providerMetadata
|
|
44174
44539
|
});
|
|
44175
44540
|
} else {
|
|
44176
44541
|
updateToolPart({
|
|
@@ -44181,8 +44546,7 @@ function processUIMessageStream({
|
|
|
44181
44546
|
rawInput: chunk.input,
|
|
44182
44547
|
errorText: chunk.errorText,
|
|
44183
44548
|
providerExecuted: chunk.providerExecuted,
|
|
44184
|
-
providerMetadata: chunk.providerMetadata
|
|
44185
|
-
toolMetadata: chunk.toolMetadata
|
|
44549
|
+
providerMetadata: chunk.providerMetadata
|
|
44186
44550
|
});
|
|
44187
44551
|
}
|
|
44188
44552
|
write();
|
|
@@ -44213,8 +44577,7 @@ function processUIMessageStream({
|
|
|
44213
44577
|
preliminary: chunk.preliminary,
|
|
44214
44578
|
providerExecuted: chunk.providerExecuted,
|
|
44215
44579
|
providerMetadata: chunk.providerMetadata,
|
|
44216
|
-
title: toolInvocation.title
|
|
44217
|
-
toolMetadata: toolInvocation.toolMetadata
|
|
44580
|
+
title: toolInvocation.title
|
|
44218
44581
|
});
|
|
44219
44582
|
} else {
|
|
44220
44583
|
updateToolPart({
|
|
@@ -44226,8 +44589,7 @@ function processUIMessageStream({
|
|
|
44226
44589
|
providerExecuted: chunk.providerExecuted,
|
|
44227
44590
|
preliminary: chunk.preliminary,
|
|
44228
44591
|
providerMetadata: chunk.providerMetadata,
|
|
44229
|
-
title: toolInvocation.title
|
|
44230
|
-
toolMetadata: toolInvocation.toolMetadata
|
|
44592
|
+
title: toolInvocation.title
|
|
44231
44593
|
});
|
|
44232
44594
|
}
|
|
44233
44595
|
write();
|
|
@@ -44244,8 +44606,7 @@ function processUIMessageStream({
|
|
|
44244
44606
|
errorText: chunk.errorText,
|
|
44245
44607
|
providerExecuted: chunk.providerExecuted,
|
|
44246
44608
|
providerMetadata: chunk.providerMetadata,
|
|
44247
|
-
title: toolInvocation.title
|
|
44248
|
-
toolMetadata: toolInvocation.toolMetadata
|
|
44609
|
+
title: toolInvocation.title
|
|
44249
44610
|
});
|
|
44250
44611
|
} else {
|
|
44251
44612
|
updateToolPart({
|
|
@@ -44257,8 +44618,7 @@ function processUIMessageStream({
|
|
|
44257
44618
|
errorText: chunk.errorText,
|
|
44258
44619
|
providerExecuted: chunk.providerExecuted,
|
|
44259
44620
|
providerMetadata: chunk.providerMetadata,
|
|
44260
|
-
title: toolInvocation.title
|
|
44261
|
-
toolMetadata: toolInvocation.toolMetadata
|
|
44621
|
+
title: toolInvocation.title
|
|
44262
44622
|
});
|
|
44263
44623
|
}
|
|
44264
44624
|
write();
|
|
@@ -44716,8 +45076,7 @@ function runToolsTransformation({
|
|
|
44716
45076
|
input: toolCall.input,
|
|
44717
45077
|
error: getErrorMessage2(toolCall.error),
|
|
44718
45078
|
dynamic: true,
|
|
44719
|
-
title: toolCall.title
|
|
44720
|
-
...toolCall.toolMetadata != null ? { toolMetadata: toolCall.toolMetadata } : {}
|
|
45079
|
+
title: toolCall.title
|
|
44721
45080
|
});
|
|
44722
45081
|
break;
|
|
44723
45082
|
}
|
|
@@ -44785,7 +45144,6 @@ function runToolsTransformation({
|
|
|
44785
45144
|
}
|
|
44786
45145
|
case "tool-result": {
|
|
44787
45146
|
const toolName = chunk.toolName;
|
|
44788
|
-
const toolCall = toolCallsByToolCallId.get(chunk.toolCallId);
|
|
44789
45147
|
if (chunk.isError) {
|
|
44790
45148
|
toolResultsStreamController.enqueue({
|
|
44791
45149
|
type: "tool-error",
|
|
@@ -44795,8 +45153,7 @@ function runToolsTransformation({
|
|
|
44795
45153
|
providerExecuted: true,
|
|
44796
45154
|
error: chunk.result,
|
|
44797
45155
|
dynamic: chunk.dynamic,
|
|
44798
|
-
...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {}
|
|
44799
|
-
...(toolCall == null ? undefined : toolCall.toolMetadata) != null ? { toolMetadata: toolCall.toolMetadata } : {}
|
|
45156
|
+
...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {}
|
|
44800
45157
|
});
|
|
44801
45158
|
} else {
|
|
44802
45159
|
controller.enqueue({
|
|
@@ -44807,8 +45164,7 @@ function runToolsTransformation({
|
|
|
44807
45164
|
output: chunk.result,
|
|
44808
45165
|
providerExecuted: true,
|
|
44809
45166
|
dynamic: chunk.dynamic,
|
|
44810
|
-
...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {}
|
|
44811
|
-
...(toolCall == null ? undefined : toolCall.toolMetadata) != null ? { toolMetadata: toolCall.toolMetadata } : {}
|
|
45167
|
+
...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {}
|
|
44812
45168
|
});
|
|
44813
45169
|
}
|
|
44814
45170
|
break;
|
|
@@ -45591,7 +45947,7 @@ async function embed({
|
|
|
45591
45947
|
}),
|
|
45592
45948
|
tracer,
|
|
45593
45949
|
fn: async (doEmbedSpan) => {
|
|
45594
|
-
var _a21
|
|
45950
|
+
var _a21;
|
|
45595
45951
|
const modelResponse = await model.doEmbed({
|
|
45596
45952
|
values: [value],
|
|
45597
45953
|
abortSignal,
|
|
@@ -45612,7 +45968,7 @@ async function embed({
|
|
|
45612
45968
|
return {
|
|
45613
45969
|
embedding: embedding2,
|
|
45614
45970
|
usage: usage2,
|
|
45615
|
-
warnings:
|
|
45971
|
+
warnings: modelResponse.warnings,
|
|
45616
45972
|
providerMetadata: modelResponse.providerMetadata,
|
|
45617
45973
|
response: modelResponse.response
|
|
45618
45974
|
};
|
|
@@ -45708,7 +46064,7 @@ async function embedMany({
|
|
|
45708
46064
|
}),
|
|
45709
46065
|
tracer,
|
|
45710
46066
|
fn: async (doEmbedSpan) => {
|
|
45711
|
-
var _a222
|
|
46067
|
+
var _a222;
|
|
45712
46068
|
const modelResponse = await model.doEmbed({
|
|
45713
46069
|
values,
|
|
45714
46070
|
abortSignal,
|
|
@@ -45729,7 +46085,7 @@ async function embedMany({
|
|
|
45729
46085
|
return {
|
|
45730
46086
|
embeddings: embeddings3,
|
|
45731
46087
|
usage: usage2,
|
|
45732
|
-
warnings:
|
|
46088
|
+
warnings: modelResponse.warnings,
|
|
45733
46089
|
providerMetadata: modelResponse.providerMetadata,
|
|
45734
46090
|
response: modelResponse.response
|
|
45735
46091
|
};
|
|
@@ -45786,7 +46142,7 @@ async function embedMany({
|
|
|
45786
46142
|
}),
|
|
45787
46143
|
tracer,
|
|
45788
46144
|
fn: async (doEmbedSpan) => {
|
|
45789
|
-
var _a222
|
|
46145
|
+
var _a222;
|
|
45790
46146
|
const modelResponse = await model.doEmbed({
|
|
45791
46147
|
values: chunk,
|
|
45792
46148
|
abortSignal,
|
|
@@ -45807,7 +46163,7 @@ async function embedMany({
|
|
|
45807
46163
|
return {
|
|
45808
46164
|
embeddings: embeddings2,
|
|
45809
46165
|
usage,
|
|
45810
|
-
warnings:
|
|
46166
|
+
warnings: modelResponse.warnings,
|
|
45811
46167
|
providerMetadata: modelResponse.providerMetadata,
|
|
45812
46168
|
response: modelResponse.response
|
|
45813
46169
|
};
|
|
@@ -47921,7 +48277,7 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
|
|
|
47921
48277
|
const bytes = typeof data === "string" ? convertBase64ToUint8Array(data) : data;
|
|
47922
48278
|
const id3Size = (bytes[6] & 127) << 21 | (bytes[7] & 127) << 14 | (bytes[8] & 127) << 7 | bytes[9] & 127;
|
|
47923
48279
|
return bytes.slice(id3Size + 10);
|
|
47924
|
-
}, VERSION3 = "6.0.
|
|
48280
|
+
}, VERSION3 = "6.0.175", download = async ({
|
|
47925
48281
|
url: url2,
|
|
47926
48282
|
maxBytes,
|
|
47927
48283
|
abortSignal
|
|
@@ -48429,7 +48785,7 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
|
|
|
48429
48785
|
}
|
|
48430
48786
|
return this._output;
|
|
48431
48787
|
}
|
|
48432
|
-
}, JsonToSseTransformStream, UI_MESSAGE_STREAM_HEADERS,
|
|
48788
|
+
}, JsonToSseTransformStream, UI_MESSAGE_STREAM_HEADERS, uiMessageChunkSchema, isToolOrDynamicToolUIPart, getToolOrDynamicToolName, originalGenerateId2, DefaultStreamTextResult = class {
|
|
48433
48789
|
constructor({
|
|
48434
48790
|
model,
|
|
48435
48791
|
telemetry,
|
|
@@ -49677,7 +50033,6 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
|
|
|
49677
50033
|
toolName: part.toolName,
|
|
49678
50034
|
...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
|
|
49679
50035
|
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
|
|
49680
|
-
...part.toolMetadata != null ? { toolMetadata: part.toolMetadata } : {},
|
|
49681
50036
|
...dynamic != null ? { dynamic } : {},
|
|
49682
50037
|
...part.title != null ? { title: part.title } : {}
|
|
49683
50038
|
});
|
|
@@ -49701,7 +50056,6 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
|
|
|
49701
50056
|
input: part.input,
|
|
49702
50057
|
...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
|
|
49703
50058
|
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
|
|
49704
|
-
...part.toolMetadata != null ? { toolMetadata: part.toolMetadata } : {},
|
|
49705
50059
|
...dynamic != null ? { dynamic } : {},
|
|
49706
50060
|
errorText: onError(part.error),
|
|
49707
50061
|
...part.title != null ? { title: part.title } : {}
|
|
@@ -49714,7 +50068,6 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
|
|
|
49714
50068
|
input: part.input,
|
|
49715
50069
|
...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
|
|
49716
50070
|
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
|
|
49717
|
-
...part.toolMetadata != null ? { toolMetadata: part.toolMetadata } : {},
|
|
49718
50071
|
...dynamic != null ? { dynamic } : {},
|
|
49719
50072
|
...part.title != null ? { title: part.title } : {}
|
|
49720
50073
|
});
|
|
@@ -49737,7 +50090,6 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
|
|
|
49737
50090
|
output: part.output,
|
|
49738
50091
|
...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
|
|
49739
50092
|
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
|
|
49740
|
-
...part.toolMetadata != null ? { toolMetadata: part.toolMetadata } : {},
|
|
49741
50093
|
...part.preliminary != null ? { preliminary: part.preliminary } : {},
|
|
49742
50094
|
...dynamic != null ? { dynamic } : {}
|
|
49743
50095
|
});
|
|
@@ -49751,7 +50103,6 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
|
|
|
49751
50103
|
errorText: part.providerExecuted ? typeof part.error === "string" ? part.error : JSON.stringify(part.error) : onError(part.error),
|
|
49752
50104
|
...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
|
|
49753
50105
|
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
|
|
49754
|
-
...part.toolMetadata != null ? { toolMetadata: part.toolMetadata } : {},
|
|
49755
50106
|
...dynamic != null ? { dynamic } : {}
|
|
49756
50107
|
});
|
|
49757
50108
|
break;
|
|
@@ -49925,21 +50276,10 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
|
|
|
49925
50276
|
...options
|
|
49926
50277
|
};
|
|
49927
50278
|
const preparedCallArgs = (_d = await ((_c = (_b16 = this.settings).prepareCall) == null ? undefined : _c.call(_b16, baseCallArgs))) != null ? _d : baseCallArgs;
|
|
49928
|
-
const {
|
|
49929
|
-
instructions,
|
|
49930
|
-
allowSystemInMessages,
|
|
49931
|
-
messages,
|
|
49932
|
-
prompt,
|
|
49933
|
-
...callArgs
|
|
49934
|
-
} = preparedCallArgs;
|
|
50279
|
+
const { instructions, messages, prompt, ...callArgs } = preparedCallArgs;
|
|
49935
50280
|
return {
|
|
49936
50281
|
...callArgs,
|
|
49937
|
-
...{
|
|
49938
|
-
system: instructions,
|
|
49939
|
-
allowSystemInMessages,
|
|
49940
|
-
messages,
|
|
49941
|
-
prompt
|
|
49942
|
-
}
|
|
50282
|
+
...{ system: instructions, messages, prompt }
|
|
49943
50283
|
};
|
|
49944
50284
|
}
|
|
49945
50285
|
mergeOnStepFinishCallbacks(methodCallback) {
|
|
@@ -49980,7 +50320,7 @@ var import_api2, import_api3, __defProp3, __export3 = (target, all) => {
|
|
|
49980
50320
|
onStepFinish: this.mergeOnStepFinishCallbacks(onStepFinish)
|
|
49981
50321
|
});
|
|
49982
50322
|
}
|
|
49983
|
-
},
|
|
50323
|
+
}, uiMessagesSchema, DefaultEmbedResult = class {
|
|
49984
50324
|
constructor(options) {
|
|
49985
50325
|
this.value = options.value;
|
|
49986
50326
|
this.embedding = options.embedding;
|
|
@@ -51488,7 +51828,6 @@ var init_dist6 = __esm(() => {
|
|
|
51488
51828
|
init_dist5();
|
|
51489
51829
|
init_dist2();
|
|
51490
51830
|
init_dist2();
|
|
51491
|
-
init_dist5();
|
|
51492
51831
|
init_dist4();
|
|
51493
51832
|
init_dist4();
|
|
51494
51833
|
init_dist4();
|
|
@@ -52348,7 +52687,6 @@ var init_dist6 = __esm(() => {
|
|
|
52348
52687
|
"x-vercel-ai-ui-message-stream": "v1",
|
|
52349
52688
|
"x-accel-buffering": "no"
|
|
52350
52689
|
};
|
|
52351
|
-
toolMetadataSchema = exports_external3.record(exports_external3.string(), jsonValueSchema.optional());
|
|
52352
52690
|
uiMessageChunkSchema = lazySchema(() => zodSchema(exports_external3.union([
|
|
52353
52691
|
exports_external3.strictObject({
|
|
52354
52692
|
type: exports_external3.literal("text-start"),
|
|
@@ -52376,7 +52714,6 @@ var init_dist6 = __esm(() => {
|
|
|
52376
52714
|
toolName: exports_external3.string(),
|
|
52377
52715
|
providerExecuted: exports_external3.boolean().optional(),
|
|
52378
52716
|
providerMetadata: providerMetadataSchema.optional(),
|
|
52379
|
-
toolMetadata: toolMetadataSchema.optional(),
|
|
52380
52717
|
dynamic: exports_external3.boolean().optional(),
|
|
52381
52718
|
title: exports_external3.string().optional()
|
|
52382
52719
|
}),
|
|
@@ -52392,7 +52729,6 @@ var init_dist6 = __esm(() => {
|
|
|
52392
52729
|
input: exports_external3.unknown(),
|
|
52393
52730
|
providerExecuted: exports_external3.boolean().optional(),
|
|
52394
52731
|
providerMetadata: providerMetadataSchema.optional(),
|
|
52395
|
-
toolMetadata: toolMetadataSchema.optional(),
|
|
52396
52732
|
dynamic: exports_external3.boolean().optional(),
|
|
52397
52733
|
title: exports_external3.string().optional()
|
|
52398
52734
|
}),
|
|
@@ -52403,7 +52739,6 @@ var init_dist6 = __esm(() => {
|
|
|
52403
52739
|
input: exports_external3.unknown(),
|
|
52404
52740
|
providerExecuted: exports_external3.boolean().optional(),
|
|
52405
52741
|
providerMetadata: providerMetadataSchema.optional(),
|
|
52406
|
-
toolMetadata: toolMetadataSchema.optional(),
|
|
52407
52742
|
dynamic: exports_external3.boolean().optional(),
|
|
52408
52743
|
errorText: exports_external3.string(),
|
|
52409
52744
|
title: exports_external3.string().optional()
|
|
@@ -52419,7 +52754,6 @@ var init_dist6 = __esm(() => {
|
|
|
52419
52754
|
output: exports_external3.unknown(),
|
|
52420
52755
|
providerExecuted: exports_external3.boolean().optional(),
|
|
52421
52756
|
providerMetadata: providerMetadataSchema.optional(),
|
|
52422
|
-
toolMetadata: toolMetadataSchema.optional(),
|
|
52423
52757
|
dynamic: exports_external3.boolean().optional(),
|
|
52424
52758
|
preliminary: exports_external3.boolean().optional()
|
|
52425
52759
|
}),
|
|
@@ -52429,7 +52763,6 @@ var init_dist6 = __esm(() => {
|
|
|
52429
52763
|
errorText: exports_external3.string(),
|
|
52430
52764
|
providerExecuted: exports_external3.boolean().optional(),
|
|
52431
52765
|
providerMetadata: providerMetadataSchema.optional(),
|
|
52432
|
-
toolMetadata: toolMetadataSchema.optional(),
|
|
52433
52766
|
dynamic: exports_external3.boolean().optional()
|
|
52434
52767
|
}),
|
|
52435
52768
|
exports_external3.strictObject({
|
|
@@ -52517,7 +52850,6 @@ var init_dist6 = __esm(() => {
|
|
|
52517
52850
|
prefix: "aitxt",
|
|
52518
52851
|
size: 24
|
|
52519
52852
|
});
|
|
52520
|
-
toolMetadataSchema2 = exports_external3.record(exports_external3.string(), jsonValueSchema.optional());
|
|
52521
52853
|
uiMessagesSchema = lazySchema(() => zodSchema(exports_external3.array(exports_external3.object({
|
|
52522
52854
|
id: exports_external3.string(),
|
|
52523
52855
|
role: exports_external3.enum(["system", "user", "assistant"]),
|
|
@@ -52569,7 +52901,6 @@ var init_dist6 = __esm(() => {
|
|
|
52569
52901
|
type: exports_external3.literal("dynamic-tool"),
|
|
52570
52902
|
toolName: exports_external3.string(),
|
|
52571
52903
|
toolCallId: exports_external3.string(),
|
|
52572
|
-
toolMetadata: toolMetadataSchema2.optional(),
|
|
52573
52904
|
state: exports_external3.literal("input-streaming"),
|
|
52574
52905
|
input: exports_external3.unknown().optional(),
|
|
52575
52906
|
providerExecuted: exports_external3.boolean().optional(),
|
|
@@ -52582,7 +52913,6 @@ var init_dist6 = __esm(() => {
|
|
|
52582
52913
|
type: exports_external3.literal("dynamic-tool"),
|
|
52583
52914
|
toolName: exports_external3.string(),
|
|
52584
52915
|
toolCallId: exports_external3.string(),
|
|
52585
|
-
toolMetadata: toolMetadataSchema2.optional(),
|
|
52586
52916
|
state: exports_external3.literal("input-available"),
|
|
52587
52917
|
input: exports_external3.unknown(),
|
|
52588
52918
|
providerExecuted: exports_external3.boolean().optional(),
|
|
@@ -52595,7 +52925,6 @@ var init_dist6 = __esm(() => {
|
|
|
52595
52925
|
type: exports_external3.literal("dynamic-tool"),
|
|
52596
52926
|
toolName: exports_external3.string(),
|
|
52597
52927
|
toolCallId: exports_external3.string(),
|
|
52598
|
-
toolMetadata: toolMetadataSchema2.optional(),
|
|
52599
52928
|
state: exports_external3.literal("approval-requested"),
|
|
52600
52929
|
input: exports_external3.unknown(),
|
|
52601
52930
|
providerExecuted: exports_external3.boolean().optional(),
|
|
@@ -52612,7 +52941,6 @@ var init_dist6 = __esm(() => {
|
|
|
52612
52941
|
type: exports_external3.literal("dynamic-tool"),
|
|
52613
52942
|
toolName: exports_external3.string(),
|
|
52614
52943
|
toolCallId: exports_external3.string(),
|
|
52615
|
-
toolMetadata: toolMetadataSchema2.optional(),
|
|
52616
52944
|
state: exports_external3.literal("approval-responded"),
|
|
52617
52945
|
input: exports_external3.unknown(),
|
|
52618
52946
|
providerExecuted: exports_external3.boolean().optional(),
|
|
@@ -52629,7 +52957,6 @@ var init_dist6 = __esm(() => {
|
|
|
52629
52957
|
type: exports_external3.literal("dynamic-tool"),
|
|
52630
52958
|
toolName: exports_external3.string(),
|
|
52631
52959
|
toolCallId: exports_external3.string(),
|
|
52632
|
-
toolMetadata: toolMetadataSchema2.optional(),
|
|
52633
52960
|
state: exports_external3.literal("output-available"),
|
|
52634
52961
|
input: exports_external3.unknown(),
|
|
52635
52962
|
providerExecuted: exports_external3.boolean().optional(),
|
|
@@ -52648,9 +52975,8 @@ var init_dist6 = __esm(() => {
|
|
|
52648
52975
|
type: exports_external3.literal("dynamic-tool"),
|
|
52649
52976
|
toolName: exports_external3.string(),
|
|
52650
52977
|
toolCallId: exports_external3.string(),
|
|
52651
|
-
toolMetadata: toolMetadataSchema2.optional(),
|
|
52652
52978
|
state: exports_external3.literal("output-error"),
|
|
52653
|
-
input: exports_external3.unknown()
|
|
52979
|
+
input: exports_external3.unknown(),
|
|
52654
52980
|
rawInput: exports_external3.unknown().optional(),
|
|
52655
52981
|
providerExecuted: exports_external3.boolean().optional(),
|
|
52656
52982
|
output: exports_external3.never().optional(),
|
|
@@ -52667,7 +52993,6 @@ var init_dist6 = __esm(() => {
|
|
|
52667
52993
|
type: exports_external3.literal("dynamic-tool"),
|
|
52668
52994
|
toolName: exports_external3.string(),
|
|
52669
52995
|
toolCallId: exports_external3.string(),
|
|
52670
|
-
toolMetadata: toolMetadataSchema2.optional(),
|
|
52671
52996
|
state: exports_external3.literal("output-denied"),
|
|
52672
52997
|
input: exports_external3.unknown(),
|
|
52673
52998
|
providerExecuted: exports_external3.boolean().optional(),
|
|
@@ -52683,7 +53008,6 @@ var init_dist6 = __esm(() => {
|
|
|
52683
53008
|
exports_external3.object({
|
|
52684
53009
|
type: exports_external3.string().startsWith("tool-"),
|
|
52685
53010
|
toolCallId: exports_external3.string(),
|
|
52686
|
-
toolMetadata: toolMetadataSchema2.optional(),
|
|
52687
53011
|
state: exports_external3.literal("input-streaming"),
|
|
52688
53012
|
providerExecuted: exports_external3.boolean().optional(),
|
|
52689
53013
|
callProviderMetadata: providerMetadataSchema.optional(),
|
|
@@ -52695,7 +53019,6 @@ var init_dist6 = __esm(() => {
|
|
|
52695
53019
|
exports_external3.object({
|
|
52696
53020
|
type: exports_external3.string().startsWith("tool-"),
|
|
52697
53021
|
toolCallId: exports_external3.string(),
|
|
52698
|
-
toolMetadata: toolMetadataSchema2.optional(),
|
|
52699
53022
|
state: exports_external3.literal("input-available"),
|
|
52700
53023
|
providerExecuted: exports_external3.boolean().optional(),
|
|
52701
53024
|
input: exports_external3.unknown(),
|
|
@@ -52707,7 +53030,6 @@ var init_dist6 = __esm(() => {
|
|
|
52707
53030
|
exports_external3.object({
|
|
52708
53031
|
type: exports_external3.string().startsWith("tool-"),
|
|
52709
53032
|
toolCallId: exports_external3.string(),
|
|
52710
|
-
toolMetadata: toolMetadataSchema2.optional(),
|
|
52711
53033
|
state: exports_external3.literal("approval-requested"),
|
|
52712
53034
|
input: exports_external3.unknown(),
|
|
52713
53035
|
providerExecuted: exports_external3.boolean().optional(),
|
|
@@ -52723,7 +53045,6 @@ var init_dist6 = __esm(() => {
|
|
|
52723
53045
|
exports_external3.object({
|
|
52724
53046
|
type: exports_external3.string().startsWith("tool-"),
|
|
52725
53047
|
toolCallId: exports_external3.string(),
|
|
52726
|
-
toolMetadata: toolMetadataSchema2.optional(),
|
|
52727
53048
|
state: exports_external3.literal("approval-responded"),
|
|
52728
53049
|
input: exports_external3.unknown(),
|
|
52729
53050
|
providerExecuted: exports_external3.boolean().optional(),
|
|
@@ -52739,7 +53060,6 @@ var init_dist6 = __esm(() => {
|
|
|
52739
53060
|
exports_external3.object({
|
|
52740
53061
|
type: exports_external3.string().startsWith("tool-"),
|
|
52741
53062
|
toolCallId: exports_external3.string(),
|
|
52742
|
-
toolMetadata: toolMetadataSchema2.optional(),
|
|
52743
53063
|
state: exports_external3.literal("output-available"),
|
|
52744
53064
|
providerExecuted: exports_external3.boolean().optional(),
|
|
52745
53065
|
input: exports_external3.unknown(),
|
|
@@ -52757,10 +53077,9 @@ var init_dist6 = __esm(() => {
|
|
|
52757
53077
|
exports_external3.object({
|
|
52758
53078
|
type: exports_external3.string().startsWith("tool-"),
|
|
52759
53079
|
toolCallId: exports_external3.string(),
|
|
52760
|
-
toolMetadata: toolMetadataSchema2.optional(),
|
|
52761
53080
|
state: exports_external3.literal("output-error"),
|
|
52762
53081
|
providerExecuted: exports_external3.boolean().optional(),
|
|
52763
|
-
input: exports_external3.unknown()
|
|
53082
|
+
input: exports_external3.unknown(),
|
|
52764
53083
|
rawInput: exports_external3.unknown().optional(),
|
|
52765
53084
|
output: exports_external3.never().optional(),
|
|
52766
53085
|
errorText: exports_external3.string(),
|
|
@@ -52775,7 +53094,6 @@ var init_dist6 = __esm(() => {
|
|
|
52775
53094
|
exports_external3.object({
|
|
52776
53095
|
type: exports_external3.string().startsWith("tool-"),
|
|
52777
53096
|
toolCallId: exports_external3.string(),
|
|
52778
|
-
toolMetadata: toolMetadataSchema2.optional(),
|
|
52779
53097
|
state: exports_external3.literal("output-denied"),
|
|
52780
53098
|
providerExecuted: exports_external3.boolean().optional(),
|
|
52781
53099
|
input: exports_external3.unknown(),
|
|
@@ -53265,54 +53583,52 @@ import { promises as fsPromises } from "fs";
|
|
|
53265
53583
|
import { createHash, createPrivateKey, createPublicKey, sign } from "crypto";
|
|
53266
53584
|
import { promises as fs2 } from "fs";
|
|
53267
53585
|
import { homedir as homedir22 } from "os";
|
|
53268
|
-
import { dirname as dirname3, join as
|
|
53586
|
+
import { dirname as dirname3, join as join52 } from "path";
|
|
53269
53587
|
import { exec } from "child_process";
|
|
53270
53588
|
import { promisify } from "util";
|
|
53271
|
-
import { readFileSync as
|
|
53589
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
53272
53590
|
import { webcrypto as crypto2 } from "crypto";
|
|
53273
|
-
import { existsSync as
|
|
53274
|
-
import { join as
|
|
53591
|
+
import { existsSync as existsSync42, writeFileSync as writeFileSync32, readFileSync as readFileSync22, mkdirSync as mkdirSync32 } from "fs";
|
|
53592
|
+
import { join as join42 } from "path";
|
|
53275
53593
|
import { Database as Database4 } from "bun:sqlite";
|
|
53276
53594
|
import { existsSync as existsSync11, mkdirSync as mkdirSync9 } from "fs";
|
|
53277
|
-
import { dirname as dirname4, join as
|
|
53278
|
-
import { existsSync as existsSync22, writeFileSync as
|
|
53595
|
+
import { dirname as dirname4, join as join15, resolve as resolve2 } from "path";
|
|
53596
|
+
import { existsSync as existsSync22, writeFileSync as writeFileSync4 } from "fs";
|
|
53279
53597
|
import { join as join22 } from "path";
|
|
53280
|
-
import { execFileSync } from "child_process";
|
|
53281
|
-
import {
|
|
53282
|
-
import { join as join32 } from "path";
|
|
53283
|
-
import { hostname as hostname3 } from "os";
|
|
53284
|
-
import { existsSync as existsSync42, readFileSync as readFileSync22, writeFileSync as writeFileSync32, mkdirSync as mkdirSync22 } from "fs";
|
|
53598
|
+
import { execSync as execSync2, execFileSync } from "child_process";
|
|
53599
|
+
import { existsSync as existsSync32, readFileSync as readFileSync4, writeFileSync as writeFileSync22, mkdirSync as mkdirSync22 } from "fs";
|
|
53285
53600
|
import { homedir as homedir11 } from "os";
|
|
53286
|
-
import { join as
|
|
53601
|
+
import { join as join32, dirname as dirname22 } from "path";
|
|
53602
|
+
import { hostname as hostname3 } from "os";
|
|
53287
53603
|
import { Buffer as Buffer2 } from "buffer";
|
|
53288
53604
|
import * as zlib from "zlib";
|
|
53289
53605
|
import { Readable } from "stream";
|
|
53290
53606
|
import { Writable } from "stream";
|
|
53291
53607
|
import { createHash as createHash2 } from "crypto";
|
|
53292
|
-
import { mkdirSync as mkdirSync4, statSync, writeFileSync as
|
|
53293
|
-
import { dirname as dirname42, join as
|
|
53608
|
+
import { mkdirSync as mkdirSync4, statSync, writeFileSync as writeFileSync42 } from "fs";
|
|
53609
|
+
import { dirname as dirname42, join as join62, relative as relative2 } from "path";
|
|
53294
53610
|
import { readdir, readFile as readFile2 } from "fs/promises";
|
|
53295
|
-
import { existsSync as
|
|
53296
|
-
import { basename, join as
|
|
53611
|
+
import { existsSync as existsSync62, readdirSync as readdirSync3, readFileSync as readFileSync42, statSync as statSync2 } from "fs";
|
|
53612
|
+
import { basename, join as join72, resolve as resolve22 } from "path";
|
|
53297
53613
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
53298
|
-
import { existsSync as
|
|
53299
|
-
import { dirname as dirname5, join as
|
|
53614
|
+
import { existsSync as existsSync72, readFileSync as readFileSync5, writeFileSync as writeFileSync5, mkdirSync as mkdirSync52 } from "fs";
|
|
53615
|
+
import { dirname as dirname5, join as join82 } from "path";
|
|
53300
53616
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
53301
|
-
import { existsSync as existsSync112 } from "fs";
|
|
53302
|
-
import { join as join122 } from "path";
|
|
53303
|
-
import { execFileSync as execFileSync3 } from "child_process";
|
|
53304
|
-
import { existsSync as existsSync92 } from "fs";
|
|
53305
|
-
import { homedir as homedir32, hostname as hostname22, platform as platform2, type } from "os";
|
|
53306
|
-
import { join as join102 } from "path";
|
|
53307
53617
|
import { existsSync as existsSync102 } from "fs";
|
|
53308
|
-
import { execSync as execSync2 } from "child_process";
|
|
53309
53618
|
import { join as join112 } from "path";
|
|
53619
|
+
import { execFileSync as execFileSync3 } from "child_process";
|
|
53620
|
+
import { existsSync as existsSync82 } from "fs";
|
|
53621
|
+
import { homedir as homedir32, hostname as hostname22, platform as platform2, type } from "os";
|
|
53622
|
+
import { join as join92 } from "path";
|
|
53623
|
+
import { existsSync as existsSync92 } from "fs";
|
|
53310
53624
|
import { execSync as execSync22 } from "child_process";
|
|
53311
|
-
import {
|
|
53625
|
+
import { join as join102 } from "path";
|
|
53626
|
+
import { execSync as execSync3 } from "child_process";
|
|
53627
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
53312
53628
|
import { mkdirSync as mkdirSync62 } from "fs";
|
|
53313
|
-
import { dirname as dirname6, join as
|
|
53629
|
+
import { dirname as dirname6, join as join122 } from "path";
|
|
53314
53630
|
import { fileURLToPath } from "url";
|
|
53315
|
-
import { existsSync as
|
|
53631
|
+
import { existsSync as existsSync112 } from "fs";
|
|
53316
53632
|
function __accessProp3(key) {
|
|
53317
53633
|
return this[key];
|
|
53318
53634
|
}
|
|
@@ -53451,7 +53767,7 @@ function getDbPath2() {
|
|
|
53451
53767
|
return process.env["PROJECTS_DB_PATH"];
|
|
53452
53768
|
}
|
|
53453
53769
|
const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
|
|
53454
|
-
return
|
|
53770
|
+
return join15(home, ".hasna", "projects", "projects.db");
|
|
53455
53771
|
}
|
|
53456
53772
|
function ensureDir2(filePath) {
|
|
53457
53773
|
if (filePath === ":memory:")
|
|
@@ -53489,25 +53805,14 @@ function uuid5() {
|
|
|
53489
53805
|
function isGitRepo(path) {
|
|
53490
53806
|
return existsSync22(join22(path, ".git"));
|
|
53491
53807
|
}
|
|
53492
|
-
function getCurrentBranch(path) {
|
|
53493
|
-
return execFileSync("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
|
|
53494
|
-
cwd: path,
|
|
53495
|
-
stdio: "pipe",
|
|
53496
|
-
encoding: "utf-8",
|
|
53497
|
-
env: process.env
|
|
53498
|
-
}).trim();
|
|
53499
|
-
}
|
|
53500
|
-
function bootstrapPathsToStage(path) {
|
|
53501
|
-
return BOOTSTRAP_PATHS.filter((entry) => existsSync22(join22(path, entry)));
|
|
53502
|
-
}
|
|
53503
53808
|
function gitInit(project) {
|
|
53504
53809
|
const { path, name: name21, id, slug } = project;
|
|
53505
53810
|
if (isGitRepo(path))
|
|
53506
53811
|
return;
|
|
53507
|
-
|
|
53812
|
+
execSync2("git init", { cwd: path, stdio: "pipe" });
|
|
53508
53813
|
const gitignorePath = join22(path, ".gitignore");
|
|
53509
53814
|
if (!existsSync22(gitignorePath)) {
|
|
53510
|
-
|
|
53815
|
+
writeFileSync4(gitignorePath, GITIGNORE_TEMPLATE, "utf-8");
|
|
53511
53816
|
}
|
|
53512
53817
|
const projectJson = {
|
|
53513
53818
|
id,
|
|
@@ -53516,18 +53821,26 @@ function gitInit(project) {
|
|
|
53516
53821
|
created_at: project.created_at,
|
|
53517
53822
|
integrations: project.integrations ?? {}
|
|
53518
53823
|
};
|
|
53519
|
-
|
|
53824
|
+
writeFileSync4(join22(path, ".project.json"), JSON.stringify(projectJson, null, 2) + `
|
|
53520
53825
|
`, "utf-8");
|
|
53521
|
-
|
|
53522
|
-
|
|
53523
|
-
return;
|
|
53524
|
-
execFileSync("git", ["add", ...staged], { cwd: path, stdio: "pipe", env: process.env });
|
|
53525
|
-
execFileSync("git", ["commit", "-m", `chore: init project ${name21}`], {
|
|
53826
|
+
execSync2("git add .gitignore .project.json", { cwd: path, stdio: "pipe" });
|
|
53827
|
+
execSync2(`git commit -m "chore: init project ${name21}"`, {
|
|
53526
53828
|
cwd: path,
|
|
53527
53829
|
stdio: "pipe",
|
|
53528
53830
|
env: { ...process.env, GIT_AUTHOR_NAME: "open-projects", GIT_COMMITTER_NAME: "open-projects" }
|
|
53529
53831
|
});
|
|
53530
53832
|
}
|
|
53833
|
+
function getConfig() {
|
|
53834
|
+
if (existsSync32(CONFIG_PATH3)) {
|
|
53835
|
+
try {
|
|
53836
|
+
const user = JSON.parse(readFileSync4(CONFIG_PATH3, "utf-8"));
|
|
53837
|
+
return { ...DEFAULTS, ...user };
|
|
53838
|
+
} catch {
|
|
53839
|
+
return { ...DEFAULTS };
|
|
53840
|
+
}
|
|
53841
|
+
}
|
|
53842
|
+
return { ...DEFAULTS };
|
|
53843
|
+
}
|
|
53531
53844
|
function rowToWorkdir(row) {
|
|
53532
53845
|
return {
|
|
53533
53846
|
...row,
|
|
@@ -53571,176 +53884,6 @@ function removeWorkdir(projectId, path, db2) {
|
|
|
53571
53884
|
const d = db2 || getDatabase2();
|
|
53572
53885
|
d.run("DELETE FROM project_workdirs WHERE project_id = ? AND path = ?", [projectId, path]);
|
|
53573
53886
|
}
|
|
53574
|
-
function markWorkdirGenerated(projectId, path, db2) {
|
|
53575
|
-
const d = db2 || getDatabase2();
|
|
53576
|
-
d.run("UPDATE project_workdirs SET claude_md_generated = 1, agents_md_generated = 1 WHERE project_id = ? AND path = ?", [projectId, path]);
|
|
53577
|
-
}
|
|
53578
|
-
function buildWorkdirList(workdirs, currentPath) {
|
|
53579
|
-
return workdirs.map((w) => {
|
|
53580
|
-
const isCurrent = w.path === currentPath;
|
|
53581
|
-
const primary = w.is_primary ? " (primary)" : "";
|
|
53582
|
-
const current = isCurrent ? " \u2190 you are here" : "";
|
|
53583
|
-
return `- \`${w.path}\` [${w.label}]${primary}${current} *(machine: ${w.machine_id})*`;
|
|
53584
|
-
}).join(`
|
|
53585
|
-
`);
|
|
53586
|
-
}
|
|
53587
|
-
function claudeMdContent(project, workdir, allWorkdirs) {
|
|
53588
|
-
const otherDirs = allWorkdirs.filter((w) => w.path !== workdir.path);
|
|
53589
|
-
const otherSection = otherDirs.length ? `
|
|
53590
|
-
## Other Working Directories
|
|
53591
|
-
${buildWorkdirList(otherDirs, workdir.path)}
|
|
53592
|
-
` : "";
|
|
53593
|
-
const integrations = Object.keys(project.integrations).length ? `
|
|
53594
|
-
## Integrations
|
|
53595
|
-
${Object.entries(project.integrations).filter(([, v]) => v).map(([k, v]) => `- **${k}:** \`${v}\``).join(`
|
|
53596
|
-
`)}
|
|
53597
|
-
` : "";
|
|
53598
|
-
const tags = project.tags.length ? `
|
|
53599
|
-
**Tags:** ${project.tags.join(", ")}` : "";
|
|
53600
|
-
return `# Project: ${project.name}
|
|
53601
|
-
|
|
53602
|
-
> ${project.description ?? `Working directory for project **${project.name}**`}
|
|
53603
|
-
${tags}
|
|
53604
|
-
|
|
53605
|
-
## Working Directory
|
|
53606
|
-
|
|
53607
|
-
You are working in the **${workdir.label}** directory for this project:
|
|
53608
|
-
|
|
53609
|
-
\`\`\`
|
|
53610
|
-
${workdir.path}
|
|
53611
|
-
\`\`\`
|
|
53612
|
-
|
|
53613
|
-
**Write all code to this directory.** Do not write to other project directories unless explicitly instructed.
|
|
53614
|
-
|
|
53615
|
-
## Project Metadata
|
|
53616
|
-
|
|
53617
|
-
| Field | Value |
|
|
53618
|
-
|-------|-------|
|
|
53619
|
-
| ID | \`${project.id}\` |
|
|
53620
|
-
| Slug | \`${project.slug}\` |
|
|
53621
|
-
| Label | \`${workdir.label}\` |
|
|
53622
|
-
| Machine | \`${workdir.machine_id}\` |
|
|
53623
|
-
| Status | ${project.status} |
|
|
53624
|
-
${project.git_remote ? `| Git Remote | ${project.git_remote} |` : ""}
|
|
53625
|
-
${project.s3_bucket ? `| S3 Bucket | \`${project.s3_bucket}\` |` : ""}
|
|
53626
|
-
${integrations}${otherSection}
|
|
53627
|
-
## All Working Directories
|
|
53628
|
-
|
|
53629
|
-
${buildWorkdirList(allWorkdirs, workdir.path)}
|
|
53630
|
-
|
|
53631
|
-
## Instructions for AI Agents
|
|
53632
|
-
|
|
53633
|
-
1. **Write code in \`${workdir.path}\`** \u2014 this is your working directory for this session.
|
|
53634
|
-
2. Use \`projects sync ${project.slug}\` to push changes to S3.
|
|
53635
|
-
3. Use \`projects git ${project.slug} <args>\` to run git commands.
|
|
53636
|
-
4. If you need to switch to a different workdir, call \`projects_open\` with the project ID.
|
|
53637
|
-
|
|
53638
|
-
---
|
|
53639
|
-
*Generated by open-projects. Regenerate: \`projects workdir generate ${project.slug}\`*
|
|
53640
|
-
`.trimStart();
|
|
53641
|
-
}
|
|
53642
|
-
function agentsMdContent(project, workdir, allWorkdirs) {
|
|
53643
|
-
const otherDirs = allWorkdirs.filter((w) => w.path !== workdir.path);
|
|
53644
|
-
return `---
|
|
53645
|
-
project_id: ${project.id}
|
|
53646
|
-
project_slug: ${project.slug}
|
|
53647
|
-
project_name: ${project.name}
|
|
53648
|
-
working_directory: ${workdir.path}
|
|
53649
|
-
label: ${workdir.label}
|
|
53650
|
-
machine_id: ${workdir.machine_id}
|
|
53651
|
-
is_primary: ${workdir.is_primary}
|
|
53652
|
-
---
|
|
53653
|
-
|
|
53654
|
-
# ${project.name} \u2014 Agent Instructions
|
|
53655
|
-
|
|
53656
|
-
## Scope
|
|
53657
|
-
|
|
53658
|
-
This agent session is scoped to the **${workdir.label}** working directory:
|
|
53659
|
-
|
|
53660
|
-
\`\`\`
|
|
53661
|
-
${workdir.path}
|
|
53662
|
-
\`\`\`
|
|
53663
|
-
|
|
53664
|
-
**Only write files inside this directory** unless the user explicitly asks you to work elsewhere.
|
|
53665
|
-
${otherDirs.length ? `
|
|
53666
|
-
## Other workdirs for this project
|
|
53667
|
-
|
|
53668
|
-
${otherDirs.map((w) => `- \`${w.path}\` [${w.label}] on ${w.machine_id}`).join(`
|
|
53669
|
-
`)}
|
|
53670
|
-
` : ""}
|
|
53671
|
-
## Quick Reference
|
|
53672
|
-
|
|
53673
|
-
\`\`\`bash
|
|
53674
|
-
# Open this project
|
|
53675
|
-
cd ${workdir.path}
|
|
53676
|
-
|
|
53677
|
-
# Sync to S3
|
|
53678
|
-
projects sync ${project.slug}
|
|
53679
|
-
|
|
53680
|
-
# Git operations
|
|
53681
|
-
projects git ${project.slug} status
|
|
53682
|
-
projects git ${project.slug} log --oneline -10
|
|
53683
|
-
\`\`\`
|
|
53684
|
-
${Object.keys(project.integrations).length ? `
|
|
53685
|
-
## Service IDs
|
|
53686
|
-
|
|
53687
|
-
${Object.entries(project.integrations).filter(([, v]) => v).map(([k, v]) => `- **${k}:** \`${v}\``).join(`
|
|
53688
|
-
`)}
|
|
53689
|
-
` : ""}
|
|
53690
|
-
---
|
|
53691
|
-
*Generated by open-projects ${new Date().toISOString().slice(0, 10)}*
|
|
53692
|
-
`.trimStart();
|
|
53693
|
-
}
|
|
53694
|
-
function generateForWorkdir(project, workdir, allWorkdirs, options = {}) {
|
|
53695
|
-
const claudeMd = claudeMdContent(project, workdir, allWorkdirs);
|
|
53696
|
-
const agentsMd = agentsMdContent(project, workdir, allWorkdirs);
|
|
53697
|
-
const claudePath = join32(workdir.path, "CLAUDE.md");
|
|
53698
|
-
const agentsPath = join32(workdir.path, "AGENTS.md");
|
|
53699
|
-
let written = false;
|
|
53700
|
-
if (!options.dryRun && existsSync32(workdir.path)) {
|
|
53701
|
-
if (existsSync32(claudePath) && !options.force) {
|
|
53702
|
-
const existing = readFileSync5(claudePath, "utf-8");
|
|
53703
|
-
if (existing.includes("Generated by open-projects")) {
|
|
53704
|
-
writeFileSync22(claudePath, claudeMd, "utf-8");
|
|
53705
|
-
} else {
|
|
53706
|
-
const separator = `
|
|
53707
|
-
|
|
53708
|
-
---
|
|
53709
|
-
|
|
53710
|
-
<!-- open-projects -->
|
|
53711
|
-
`;
|
|
53712
|
-
const marker21 = "<!-- open-projects -->";
|
|
53713
|
-
if (existing.includes(marker21)) {
|
|
53714
|
-
const before = existing.slice(0, existing.indexOf(marker21) - separator.length + 1);
|
|
53715
|
-
writeFileSync22(claudePath, before + separator + claudeMd, "utf-8");
|
|
53716
|
-
} else {
|
|
53717
|
-
writeFileSync22(claudePath, existing.trimEnd() + separator + claudeMd, "utf-8");
|
|
53718
|
-
}
|
|
53719
|
-
}
|
|
53720
|
-
} else {
|
|
53721
|
-
writeFileSync22(claudePath, claudeMd, "utf-8");
|
|
53722
|
-
}
|
|
53723
|
-
writeFileSync22(agentsPath, agentsMd, "utf-8");
|
|
53724
|
-
markWorkdirGenerated(project.id, workdir.path, options.db);
|
|
53725
|
-
written = true;
|
|
53726
|
-
}
|
|
53727
|
-
return { path: workdir.path, claude_md: claudeMd, agents_md: agentsMd, written };
|
|
53728
|
-
}
|
|
53729
|
-
function generateAllWorkdirs(project, options = {}) {
|
|
53730
|
-
const workdirs = listWorkdirs(project.id, options.db);
|
|
53731
|
-
return workdirs.map((w) => generateForWorkdir(project, w, workdirs, options));
|
|
53732
|
-
}
|
|
53733
|
-
function getConfig() {
|
|
53734
|
-
if (existsSync42(CONFIG_PATH3)) {
|
|
53735
|
-
try {
|
|
53736
|
-
const user = JSON.parse(readFileSync22(CONFIG_PATH3, "utf-8"));
|
|
53737
|
-
return { ...DEFAULTS, ...user };
|
|
53738
|
-
} catch {
|
|
53739
|
-
return { ...DEFAULTS };
|
|
53740
|
-
}
|
|
53741
|
-
}
|
|
53742
|
-
return { ...DEFAULTS };
|
|
53743
|
-
}
|
|
53744
53887
|
function generateProjectId() {
|
|
53745
53888
|
return `prj_${nanoid3()}`;
|
|
53746
53889
|
}
|
|
@@ -53748,10 +53891,12 @@ function slugify2(name21) {
|
|
|
53748
53891
|
return name21.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
53749
53892
|
}
|
|
53750
53893
|
function scaffoldProject(path) {
|
|
53894
|
+
if (existsSync42(path))
|
|
53895
|
+
return;
|
|
53751
53896
|
mkdirSync32(path, { recursive: true });
|
|
53752
53897
|
const config2 = getConfig();
|
|
53753
53898
|
for (const dir of config2.scaffold_dirs || ["data", "scripts", "assets", "docs"]) {
|
|
53754
|
-
mkdirSync32(
|
|
53899
|
+
mkdirSync32(join42(path, dir), { recursive: true });
|
|
53755
53900
|
}
|
|
53756
53901
|
}
|
|
53757
53902
|
function ensureUniqueSlug(base, db2, excludeId) {
|
|
@@ -53802,9 +53947,6 @@ function createProject2(input, db2) {
|
|
|
53802
53947
|
try {
|
|
53803
53948
|
addWorkdir({ project_id: id, path: input.path, label: "main", is_primary: true }, d);
|
|
53804
53949
|
} catch {}
|
|
53805
|
-
try {
|
|
53806
|
-
generateAllWorkdirs(project, { db: d });
|
|
53807
|
-
} catch {}
|
|
53808
53950
|
const shouldGitInit = input.git_init !== false;
|
|
53809
53951
|
if (shouldGitInit) {
|
|
53810
53952
|
try {
|
|
@@ -53910,10 +54052,10 @@ function setIntegrations(id, integrations, db2) {
|
|
|
53910
54052
|
id
|
|
53911
54053
|
]);
|
|
53912
54054
|
try {
|
|
53913
|
-
const jsonPath =
|
|
53914
|
-
if (
|
|
53915
|
-
const existing = JSON.parse(
|
|
53916
|
-
|
|
54055
|
+
const jsonPath = join42(project.path, ".project.json");
|
|
54056
|
+
if (existsSync42(jsonPath)) {
|
|
54057
|
+
const existing = JSON.parse(readFileSync22(jsonPath, "utf-8"));
|
|
54058
|
+
writeFileSync32(jsonPath, JSON.stringify({ ...existing, integrations: merged }, null, 2) + `
|
|
53917
54059
|
`, "utf-8");
|
|
53918
54060
|
}
|
|
53919
54061
|
} catch {}
|
|
@@ -54987,7 +55129,7 @@ async function collectLocalFiles(rootPath) {
|
|
|
54987
55129
|
async function walk(dir) {
|
|
54988
55130
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
54989
55131
|
for (const entry of entries) {
|
|
54990
|
-
const fullPath =
|
|
55132
|
+
const fullPath = join62(dir, entry.name);
|
|
54991
55133
|
if (entry.isDirectory()) {
|
|
54992
55134
|
await walk(fullPath);
|
|
54993
55135
|
} else if (entry.isFile()) {
|
|
@@ -55059,7 +55201,7 @@ async function syncProject(project, options = {}) {
|
|
|
55059
55201
|
continue;
|
|
55060
55202
|
}
|
|
55061
55203
|
try {
|
|
55062
|
-
const data = await readFile2(
|
|
55204
|
+
const data = await readFile2(join62(project.path, relPath));
|
|
55063
55205
|
await client.send(new PutObjectCommand({
|
|
55064
55206
|
Bucket: bucket,
|
|
55065
55207
|
Key: s3Key,
|
|
@@ -55097,9 +55239,9 @@ async function syncProject(project, options = {}) {
|
|
|
55097
55239
|
chunks.push(chunk);
|
|
55098
55240
|
}
|
|
55099
55241
|
const data = Buffer.concat(chunks);
|
|
55100
|
-
const localPath =
|
|
55242
|
+
const localPath = join62(project.path, relPath);
|
|
55101
55243
|
mkdirSync4(dirname42(localPath), { recursive: true });
|
|
55102
|
-
|
|
55244
|
+
writeFileSync42(localPath, data);
|
|
55103
55245
|
log(`pull: ${relPath} (${data.length}B)`);
|
|
55104
55246
|
result.pulled++;
|
|
55105
55247
|
result.bytes += data.length;
|
|
@@ -55120,18 +55262,18 @@ async function syncProject(project, options = {}) {
|
|
|
55120
55262
|
return result;
|
|
55121
55263
|
}
|
|
55122
55264
|
function inferProjectName(projectPath) {
|
|
55123
|
-
const pkgPath =
|
|
55124
|
-
if (
|
|
55265
|
+
const pkgPath = join72(projectPath, "package.json");
|
|
55266
|
+
if (existsSync62(pkgPath)) {
|
|
55125
55267
|
try {
|
|
55126
|
-
const pkg = JSON.parse(
|
|
55268
|
+
const pkg = JSON.parse(readFileSync42(pkgPath, "utf-8"));
|
|
55127
55269
|
if (pkg.name)
|
|
55128
55270
|
return pkg.name.replace(/^@[^/]+\//, "");
|
|
55129
55271
|
} catch {}
|
|
55130
55272
|
}
|
|
55131
|
-
const projPath =
|
|
55132
|
-
if (
|
|
55273
|
+
const projPath = join72(projectPath, ".project.json");
|
|
55274
|
+
if (existsSync62(projPath)) {
|
|
55133
55275
|
try {
|
|
55134
|
-
const p2 = JSON.parse(
|
|
55276
|
+
const p2 = JSON.parse(readFileSync42(projPath, "utf-8"));
|
|
55135
55277
|
if (p2.name)
|
|
55136
55278
|
return p2.name;
|
|
55137
55279
|
} catch {}
|
|
@@ -55139,11 +55281,11 @@ function inferProjectName(projectPath) {
|
|
|
55139
55281
|
return basename(projectPath);
|
|
55140
55282
|
}
|
|
55141
55283
|
function inferGitRemote(projectPath) {
|
|
55142
|
-
const gitConfigPath =
|
|
55143
|
-
if (!
|
|
55284
|
+
const gitConfigPath = join72(projectPath, ".git", "config");
|
|
55285
|
+
if (!existsSync62(gitConfigPath))
|
|
55144
55286
|
return;
|
|
55145
55287
|
try {
|
|
55146
|
-
const config2 =
|
|
55288
|
+
const config2 = readFileSync42(gitConfigPath, "utf-8");
|
|
55147
55289
|
const match = config2.match(/\[remote "origin"\][\s\S]*?url\s*=\s*(.+)/);
|
|
55148
55290
|
return match?.[1]?.trim();
|
|
55149
55291
|
} catch {
|
|
@@ -55153,7 +55295,7 @@ function inferGitRemote(projectPath) {
|
|
|
55153
55295
|
async function importProject(projectPath, options = {}) {
|
|
55154
55296
|
const absPath = resolve22(projectPath);
|
|
55155
55297
|
const log = options.onProgress ?? (() => {});
|
|
55156
|
-
if (!
|
|
55298
|
+
if (!existsSync62(absPath)) {
|
|
55157
55299
|
return { error: `Path does not exist: ${absPath}` };
|
|
55158
55300
|
}
|
|
55159
55301
|
const stat = statSync2(absPath);
|
|
@@ -55188,7 +55330,7 @@ async function importBulk(dirPath, options = {}) {
|
|
|
55188
55330
|
const absDir = resolve22(dirPath);
|
|
55189
55331
|
const result = { imported: [], skipped: [], errors: [] };
|
|
55190
55332
|
const log = options.onProgress ?? (() => {});
|
|
55191
|
-
if (!
|
|
55333
|
+
if (!existsSync62(absDir)) {
|
|
55192
55334
|
result.errors.push({ path: absDir, error: "Directory does not exist" });
|
|
55193
55335
|
return result;
|
|
55194
55336
|
}
|
|
@@ -55196,7 +55338,7 @@ async function importBulk(dirPath, options = {}) {
|
|
|
55196
55338
|
const dirs = entries.filter((e2) => e2.isDirectory() && !e2.name.startsWith("."));
|
|
55197
55339
|
log(`Found ${dirs.length} subdirectories in ${absDir}`);
|
|
55198
55340
|
for (const entry of dirs) {
|
|
55199
|
-
const subPath =
|
|
55341
|
+
const subPath = join72(absDir, entry.name);
|
|
55200
55342
|
const res = await importProject(subPath, options);
|
|
55201
55343
|
if (res.project) {
|
|
55202
55344
|
result.imported.push(res.project);
|
|
@@ -55231,8 +55373,7 @@ function publishProject(name21, path, options = {}) {
|
|
|
55231
55373
|
} else {
|
|
55232
55374
|
execFileSync2("git", ["remote", "add", "origin", remote], { cwd: path, stdio: "pipe", env: process.env });
|
|
55233
55375
|
}
|
|
55234
|
-
|
|
55235
|
-
execFileSync2("git", ["push", "-u", "origin", branch, "--quiet"], { cwd: path, stdio: "pipe", env: process.env });
|
|
55376
|
+
execFileSync2("git", ["push", "-u", "origin", "main", "--quiet"], { cwd: path, stdio: "pipe", env: process.env });
|
|
55236
55377
|
pushed = true;
|
|
55237
55378
|
} catch {}
|
|
55238
55379
|
}
|
|
@@ -55258,14 +55399,14 @@ function getGitHubUrl(path) {
|
|
|
55258
55399
|
}
|
|
55259
55400
|
}
|
|
55260
55401
|
function getScheduleConfig() {
|
|
55261
|
-
if (!
|
|
55402
|
+
if (!existsSync72(CONFIG_PATH22)) {
|
|
55262
55403
|
return { enabled: false, interval: "daily", direction: "both" };
|
|
55263
55404
|
}
|
|
55264
|
-
return JSON.parse(
|
|
55405
|
+
return JSON.parse(readFileSync5(CONFIG_PATH22, "utf-8"));
|
|
55265
55406
|
}
|
|
55266
55407
|
function saveScheduleConfig(config2) {
|
|
55267
55408
|
mkdirSync52(dirname5(CONFIG_PATH22), { recursive: true });
|
|
55268
|
-
|
|
55409
|
+
writeFileSync5(CONFIG_PATH22, JSON.stringify(config2, null, 2) + `
|
|
55269
55410
|
`, "utf-8");
|
|
55270
55411
|
}
|
|
55271
55412
|
async function syncAll(direction = "both", onProgress) {
|
|
@@ -55295,7 +55436,7 @@ async function syncAll(direction = "both", onProgress) {
|
|
|
55295
55436
|
function getMachineProfile() {
|
|
55296
55437
|
const host = (process.env["HOSTNAME"] || hostname22()).split(".")[0] || hostname22();
|
|
55297
55438
|
const currentPlatform = platform2();
|
|
55298
|
-
const workspaceRoot = currentPlatform === "darwin" ?
|
|
55439
|
+
const workspaceRoot = currentPlatform === "darwin" ? join92(homedir32(), "Workspace") : join92(homedir32(), "workspace");
|
|
55299
55440
|
return {
|
|
55300
55441
|
hostname: host,
|
|
55301
55442
|
platform: currentPlatform,
|
|
@@ -55322,7 +55463,7 @@ function commandAvailability(command, versionArgs = ["--version"]) {
|
|
|
55322
55463
|
return { command, available: true, path: commandPath, version: version2 };
|
|
55323
55464
|
}
|
|
55324
55465
|
function pathExists(path) {
|
|
55325
|
-
return
|
|
55466
|
+
return existsSync82(path);
|
|
55326
55467
|
}
|
|
55327
55468
|
function classifyMachine(host, currentPlatform) {
|
|
55328
55469
|
if (host === "apple01")
|
|
@@ -55336,10 +55477,10 @@ function classifyMachine(host, currentPlatform) {
|
|
|
55336
55477
|
return "unknown";
|
|
55337
55478
|
}
|
|
55338
55479
|
function gitStatus(path) {
|
|
55339
|
-
if (!
|
|
55480
|
+
if (!existsSync92(join102(path, ".git")))
|
|
55340
55481
|
return "not a repo";
|
|
55341
55482
|
try {
|
|
55342
|
-
const out =
|
|
55483
|
+
const out = execSync22("git status --porcelain", { cwd: path, stdio: "pipe", encoding: "utf-8" }).trim();
|
|
55343
55484
|
if (!out)
|
|
55344
55485
|
return "clean";
|
|
55345
55486
|
const n2 = out.split(`
|
|
@@ -55350,17 +55491,17 @@ function gitStatus(path) {
|
|
|
55350
55491
|
}
|
|
55351
55492
|
}
|
|
55352
55493
|
function dirSize(path) {
|
|
55353
|
-
if (!
|
|
55494
|
+
if (!existsSync92(path))
|
|
55354
55495
|
return 0;
|
|
55355
55496
|
try {
|
|
55356
|
-
const out =
|
|
55497
|
+
const out = execSync22(`du -sb -- "${path}" 2>/dev/null || du -sk -- "${path}" 2>/dev/null`, { stdio: "pipe", encoding: "utf-8" }).trim();
|
|
55357
55498
|
return parseInt(out.split("\t")[0] ?? "0", 10);
|
|
55358
55499
|
} catch {
|
|
55359
55500
|
return 0;
|
|
55360
55501
|
}
|
|
55361
55502
|
}
|
|
55362
55503
|
function getProjectStatus(project) {
|
|
55363
|
-
const pathExists2 =
|
|
55504
|
+
const pathExists2 = existsSync92(project.path);
|
|
55364
55505
|
const workdirs = listWorkdirs(project.id);
|
|
55365
55506
|
const lastSync = getDatabase2().query("SELECT completed_at FROM sync_log WHERE project_id = ? AND status = 'completed' ORDER BY completed_at DESC LIMIT 1").get(project.id)?.completed_at ?? null;
|
|
55366
55507
|
return {
|
|
@@ -55373,21 +55514,18 @@ function getProjectStatus(project) {
|
|
|
55373
55514
|
};
|
|
55374
55515
|
}
|
|
55375
55516
|
function run(cmd) {
|
|
55376
|
-
return
|
|
55517
|
+
return execSync3(cmd, { encoding: "utf-8", stdio: "pipe" }).trim();
|
|
55377
55518
|
}
|
|
55378
55519
|
function getTmuxSessionName(project) {
|
|
55379
|
-
|
|
55520
|
+
const raw = project.slug || project.name;
|
|
55521
|
+
if (project.path?.includes("opensourcedev")) {
|
|
55522
|
+
const normalized = raw.replace(/^proj-/, "");
|
|
55523
|
+
return normalized.startsWith("open-") ? normalized : `open-${normalized}`;
|
|
55524
|
+
}
|
|
55525
|
+
return raw;
|
|
55380
55526
|
}
|
|
55381
55527
|
function listSessions() {
|
|
55382
|
-
|
|
55383
|
-
try {
|
|
55384
|
-
output = run("tmux list-sessions -F '#{session_name}:#{session_group}:#{session_windows}:#{session_attached}'");
|
|
55385
|
-
} catch (err) {
|
|
55386
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
55387
|
-
if (message.includes("no server running"))
|
|
55388
|
-
return [];
|
|
55389
|
-
throw err;
|
|
55390
|
-
}
|
|
55528
|
+
const output = run("tmux list-sessions -F '#{session_name}:#{session_group}:#{session_windows}:#{session_attached}'");
|
|
55391
55529
|
return output.split(`
|
|
55392
55530
|
`).filter(Boolean).map((line) => {
|
|
55393
55531
|
const [name21, group, windows, attached] = line.split(":");
|
|
@@ -55495,7 +55633,7 @@ function getProjectLocations(project) {
|
|
|
55495
55633
|
const currentMachine = getMachineId();
|
|
55496
55634
|
return listWorkdirs(project.id).map((workdir) => ({
|
|
55497
55635
|
...workdir,
|
|
55498
|
-
exists:
|
|
55636
|
+
exists: existsSync102(workdir.path),
|
|
55499
55637
|
currentMachine: workdir.machine_id === currentMachine,
|
|
55500
55638
|
recommended: workdir.is_primary || workdir.path === project.path
|
|
55501
55639
|
}));
|
|
@@ -55532,7 +55670,7 @@ function buildProjectContext(project) {
|
|
|
55532
55670
|
};
|
|
55533
55671
|
}
|
|
55534
55672
|
function getGitContext(path) {
|
|
55535
|
-
if (!
|
|
55673
|
+
if (!existsSync102(join112(path, ".git"))) {
|
|
55536
55674
|
return { isRepo: false, branch: null, dirtyCount: null, remote: null };
|
|
55537
55675
|
}
|
|
55538
55676
|
return {
|
|
@@ -55575,7 +55713,7 @@ function setupMachineReport(options = {}) {
|
|
|
55575
55713
|
const dryRun = options.dryRun !== false;
|
|
55576
55714
|
const checks3 = [];
|
|
55577
55715
|
const dbDir = dirname6(getDbPath2());
|
|
55578
|
-
const cloudConfig =
|
|
55716
|
+
const cloudConfig = join122(process.env["HOME"] || "~", ".hasna", "cloud", "config.json");
|
|
55579
55717
|
checks3.push(pathCheck("PROJECTS_DATA_DIR", "projects data dir", dbDir, options));
|
|
55580
55718
|
checks3.push(pathCheck("WORKSPACE_ROOT", "workspace root", machine.workspaceRoot, options));
|
|
55581
55719
|
checks3.push(commandCheck("bun", ["--version"], "Bun runtime"));
|
|
@@ -55636,8 +55774,8 @@ function commandCheck(command, versionArgs, label, missingStatus = "error") {
|
|
|
55636
55774
|
}
|
|
55637
55775
|
function packageVersion() {
|
|
55638
55776
|
try {
|
|
55639
|
-
const pkgPath =
|
|
55640
|
-
return JSON.parse(
|
|
55777
|
+
const pkgPath = join122(dirname6(fileURLToPath(import.meta.url)), "..", "..", "package.json");
|
|
55778
|
+
return JSON.parse(readFileSync6(pkgPath, "utf-8")).version || "0.0.0";
|
|
55641
55779
|
} catch {
|
|
55642
55780
|
return "0.0.0";
|
|
55643
55781
|
}
|
|
@@ -55651,7 +55789,7 @@ function findStaleIssues(project) {
|
|
|
55651
55789
|
const issues = [];
|
|
55652
55790
|
const currentMachine = getMachineId();
|
|
55653
55791
|
for (const p2 of projects) {
|
|
55654
|
-
if (p2.status === "active" && !
|
|
55792
|
+
if (p2.status === "active" && !existsSync112(p2.path)) {
|
|
55655
55793
|
issues.push({
|
|
55656
55794
|
code: "PROJECT_PATH_MISSING",
|
|
55657
55795
|
severity: "error",
|
|
@@ -55662,7 +55800,7 @@ function findStaleIssues(project) {
|
|
|
55662
55800
|
});
|
|
55663
55801
|
}
|
|
55664
55802
|
for (const workdir of listWorkdirs(p2.id)) {
|
|
55665
|
-
if (workdir.machine_id === currentMachine && !
|
|
55803
|
+
if (workdir.machine_id === currentMachine && !existsSync112(workdir.path)) {
|
|
55666
55804
|
issues.push({
|
|
55667
55805
|
code: "WORKDIR_PATH_MISSING",
|
|
55668
55806
|
severity: "warn",
|
|
@@ -56604,7 +56742,7 @@ Reference: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.ht
|
|
|
56604
56742
|
}
|
|
56605
56743
|
const credentials = await fromWebToken({
|
|
56606
56744
|
...init,
|
|
56607
|
-
webIdentityToken: import_shared_ini_file_loader10.externalDataInterceptor?.getTokenRecord?.()[webIdentityTokenFile] ??
|
|
56745
|
+
webIdentityToken: import_shared_ini_file_loader10.externalDataInterceptor?.getTokenRecord?.()[webIdentityTokenFile] ?? readFileSync3(webIdentityTokenFile, { encoding: "ascii" }),
|
|
56608
56746
|
roleArn,
|
|
56609
56747
|
roleSessionName
|
|
56610
56748
|
})(awsIdentityProperties);
|
|
@@ -56691,7 +56829,7 @@ coverage/
|
|
|
56691
56829
|
# Cache
|
|
56692
56830
|
.cache/
|
|
56693
56831
|
.turbo/
|
|
56694
|
-
`,
|
|
56832
|
+
`, CONFIG_PATH3, DEFAULTS, nanoid3, import_protocol_http, addExpectContinueMiddlewareOptions, getAddExpectContinuePlugin = (options) => ({
|
|
56695
56833
|
applyToStack: (clientStack) => {
|
|
56696
56834
|
clientStack.add(addExpectContinueMiddleware(options), addExpectContinueMiddlewareOptions);
|
|
56697
56835
|
}
|
|
@@ -69770,11 +69908,11 @@ More information can be found at: https://a.co/c895JFp`);
|
|
|
69770
69908
|
var numberSelector = (obj, key, type2) => {
|
|
69771
69909
|
if (!(key in obj))
|
|
69772
69910
|
return;
|
|
69773
|
-
const
|
|
69774
|
-
if (Number.isNaN(
|
|
69911
|
+
const numberValue2 = parseInt(obj[key], 10);
|
|
69912
|
+
if (Number.isNaN(numberValue2)) {
|
|
69775
69913
|
throw new TypeError(`Cannot load ${type2} '${key}'. Expected number, got '${obj[key]}'.`);
|
|
69776
69914
|
}
|
|
69777
|
-
return
|
|
69915
|
+
return numberValue2;
|
|
69778
69916
|
};
|
|
69779
69917
|
exports.SelectorType = undefined;
|
|
69780
69918
|
(function(SelectorType2) {
|
|
@@ -74502,7 +74640,7 @@ More information can be found at: https://a.co/c895JFp`);
|
|
|
74502
74640
|
};
|
|
74503
74641
|
});
|
|
74504
74642
|
require_dist_cjs41 = __commonJS3((exports) => {
|
|
74505
|
-
var __dirname2 = "/
|
|
74643
|
+
var __dirname2 = "/home/hasna/workspace/hasna/opensource/open-projects/node_modules/@aws-sdk/util-user-agent-node/dist-cjs";
|
|
74506
74644
|
var node_os = __require3("os");
|
|
74507
74645
|
var node_process = __require3("process");
|
|
74508
74646
|
var utilConfigProvider = require_dist_cjs28();
|
|
@@ -78172,10 +78310,10 @@ More information can be found at: https://a.co/c895JFp`);
|
|
|
78172
78310
|
await fs2.writeFile(tokenFilePath, JSON.stringify(token, null, 2), "utf8");
|
|
78173
78311
|
}
|
|
78174
78312
|
getTokenFilePath() {
|
|
78175
|
-
const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ??
|
|
78313
|
+
const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ?? join52(homedir22(), ".aws", "login", "cache");
|
|
78176
78314
|
const loginSessionBytes = Buffer.from(this.loginSession, "utf8");
|
|
78177
78315
|
const loginSessionSha256 = createHash("sha256").update(loginSessionBytes).digest("hex");
|
|
78178
|
-
return
|
|
78316
|
+
return join52(directory, `${loginSessionSha256}.json`);
|
|
78179
78317
|
}
|
|
78180
78318
|
derToRawSignature(derSignature) {
|
|
78181
78319
|
let offset = 2;
|
|
@@ -78476,18 +78614,7 @@ More information can be found at: https://a.co/c895JFp`);
|
|
|
78476
78614
|
INSERT OR IGNORE INTO _migrations (id) VALUES (4);
|
|
78477
78615
|
`
|
|
78478
78616
|
];
|
|
78479
|
-
|
|
78480
|
-
".gitignore",
|
|
78481
|
-
".project.json",
|
|
78482
|
-
"CLAUDE.md",
|
|
78483
|
-
"AGENTS.md",
|
|
78484
|
-
"README.md",
|
|
78485
|
-
"docs",
|
|
78486
|
-
"data",
|
|
78487
|
-
"scripts",
|
|
78488
|
-
"assets"
|
|
78489
|
-
];
|
|
78490
|
-
CONFIG_PATH3 = join42(homedir11(), ".hasna", "projects", "config.json");
|
|
78617
|
+
CONFIG_PATH3 = join32(homedir11(), ".hasna", "projects", "config.json");
|
|
78491
78618
|
DEFAULTS = {
|
|
78492
78619
|
default_path: process.cwd(),
|
|
78493
78620
|
default_github_org: "hasnaxyz",
|
|
@@ -84273,7 +84400,7 @@ More information can be found at: https://a.co/c895JFp`);
|
|
|
84273
84400
|
}).s("AmazonS3", "PutObject", {}).n("S3Client", "PutObjectCommand").sc(PutObject$).build() {
|
|
84274
84401
|
};
|
|
84275
84402
|
MAX_FILE_SIZE = 100 * 1024 * 1024;
|
|
84276
|
-
CONFIG_PATH22 =
|
|
84403
|
+
CONFIG_PATH22 = join82(process.env["HOME"] || "~", ".hasna", "projects", "scheduler.json");
|
|
84277
84404
|
SPARK_MACHINES = new Set(["spark01", "spark02"]);
|
|
84278
84405
|
});
|
|
84279
84406
|
|
|
@@ -85264,12 +85391,12 @@ __export(exports_contacts_connector, {
|
|
|
85264
85391
|
});
|
|
85265
85392
|
function getContactsDb() {
|
|
85266
85393
|
const { Database: Database5 } = __require("bun:sqlite");
|
|
85267
|
-
const { existsSync:
|
|
85268
|
-
const { join:
|
|
85394
|
+
const { existsSync: existsSync5 } = __require("fs");
|
|
85395
|
+
const { join: join16 } = __require("path");
|
|
85269
85396
|
const { homedir: homedir7 } = __require("os");
|
|
85270
85397
|
const envPath = process.env["HASNA_CONTACTS_DB_PATH"] ?? process.env["OPEN_CONTACTS_DB"];
|
|
85271
|
-
const dbPath = envPath ??
|
|
85272
|
-
if (!
|
|
85398
|
+
const dbPath = envPath ?? join16(homedir7(), ".hasna", "contacts", "contacts.db");
|
|
85399
|
+
if (!existsSync5(dbPath))
|
|
85273
85400
|
return null;
|
|
85274
85401
|
const db2 = new Database5(dbPath, { readonly: true });
|
|
85275
85402
|
return db2;
|
|
@@ -85389,7 +85516,7 @@ __export(exports_army_runner, {
|
|
|
85389
85516
|
waitForArmyRun: () => waitForArmyRun,
|
|
85390
85517
|
runWithArmy: () => runWithArmy
|
|
85391
85518
|
});
|
|
85392
|
-
import { join as
|
|
85519
|
+
import { join as join16 } from "path";
|
|
85393
85520
|
function chunkArray(arr, n2) {
|
|
85394
85521
|
const chunks = [];
|
|
85395
85522
|
const size = Math.ceil(arr.length / n2);
|
|
@@ -85399,7 +85526,7 @@ function chunkArray(arr, n2) {
|
|
|
85399
85526
|
return chunks;
|
|
85400
85527
|
}
|
|
85401
85528
|
function getCliPath() {
|
|
85402
|
-
const srcPath =
|
|
85529
|
+
const srcPath = join16(import.meta.dir, "../cli/index.tsx");
|
|
85403
85530
|
return srcPath;
|
|
85404
85531
|
}
|
|
85405
85532
|
async function runWithArmy(options) {
|
|
@@ -85602,12 +85729,28 @@ Rules:
|
|
|
85602
85729
|
];
|
|
85603
85730
|
const messages = [{ role: "user", content: contentParts }];
|
|
85604
85731
|
try {
|
|
85605
|
-
|
|
85606
|
-
|
|
85607
|
-
|
|
85608
|
-
|
|
85609
|
-
|
|
85610
|
-
|
|
85732
|
+
let text2;
|
|
85733
|
+
const provider = detectProvider(model);
|
|
85734
|
+
if (provider !== "anthropic") {
|
|
85735
|
+
const compat2 = client;
|
|
85736
|
+
const response = await callOpenAICompatible({
|
|
85737
|
+
baseUrl: compat2.baseUrl,
|
|
85738
|
+
apiKey: compat2.apiKey,
|
|
85739
|
+
model,
|
|
85740
|
+
system: "You are a QA engineer.",
|
|
85741
|
+
messages: [{ role: "user", content: prompt }],
|
|
85742
|
+
tools: [],
|
|
85743
|
+
maxTokens: 2048
|
|
85744
|
+
});
|
|
85745
|
+
text2 = response.content.filter((b2) => b2.type === "text").map((b2) => b2.text).join("");
|
|
85746
|
+
} else {
|
|
85747
|
+
const response = await anthropicClient.messages.create({
|
|
85748
|
+
model,
|
|
85749
|
+
max_tokens: 2048,
|
|
85750
|
+
messages
|
|
85751
|
+
});
|
|
85752
|
+
text2 = response.content.filter((b2) => b2.type === "text").map((b2) => b2.text).join("");
|
|
85753
|
+
}
|
|
85611
85754
|
const match = text2.match(/\[[\s\S]*\]/);
|
|
85612
85755
|
if (!match)
|
|
85613
85756
|
return [];
|
|
@@ -85635,7 +85778,7 @@ async function crawlAndGenerate(options) {
|
|
|
85635
85778
|
} = options;
|
|
85636
85779
|
const config2 = loadConfig();
|
|
85637
85780
|
const model = resolveModel2(options.model ?? config2.defaultModel ?? "thorough");
|
|
85638
|
-
const client =
|
|
85781
|
+
const client = createClientForModel(model, resolveProviderApiKeyForModel(model, options.apiKey, config2.anthropicApiKey));
|
|
85639
85782
|
const rootOrigin = new URL(url2).origin;
|
|
85640
85783
|
const visited = new Set;
|
|
85641
85784
|
const queue = [url2];
|
|
@@ -85715,7 +85858,6 @@ var init_crawl_and_generate = __esm(() => {
|
|
|
85715
85858
|
init_scenarios();
|
|
85716
85859
|
init_ai_client();
|
|
85717
85860
|
init_config2();
|
|
85718
|
-
init_ai_client();
|
|
85719
85861
|
DEFAULT_SKIP_PATTERNS = [
|
|
85720
85862
|
"/logout",
|
|
85721
85863
|
"/sign-out",
|
|
@@ -86171,9 +86313,30 @@ function buildServer() {
|
|
|
86171
86313
|
goalPrompt: exports_external.string().optional().describe("Goal prompt for the AI SDK workflow agent"),
|
|
86172
86314
|
successCriteria: exports_external.array(exports_external.string()).optional().describe("Goal success criteria"),
|
|
86173
86315
|
maxIterations: exports_external.number().int().min(1).max(20).optional().describe("Max goal loop iterations"),
|
|
86174
|
-
executionTarget: exports_external.enum(["local", "connector:e2b"]).optional().describe("Run locally or through the
|
|
86175
|
-
|
|
86176
|
-
|
|
86316
|
+
executionTarget: exports_external.enum(["local", "sandbox", "connector:e2b"]).optional().describe("Run locally or through the sandboxes SDK"),
|
|
86317
|
+
sandboxProvider: exports_external.string().optional().describe("Sandbox provider: e2b, daytona, or modal"),
|
|
86318
|
+
sandboxImage: exports_external.string().optional().describe("Sandbox image/template"),
|
|
86319
|
+
sandboxRemoteDir: exports_external.string().optional().describe("Remote working directory for sandbox runs"),
|
|
86320
|
+
sandboxCleanup: exports_external.enum(["delete", "stop", "keep"]).optional().describe("Sandbox cleanup mode"),
|
|
86321
|
+
e2bTemplate: exports_external.string().optional().describe("Legacy alias for sandboxImage")
|
|
86322
|
+
}, async ({
|
|
86323
|
+
name: name21,
|
|
86324
|
+
description,
|
|
86325
|
+
projectId,
|
|
86326
|
+
scenarioIds,
|
|
86327
|
+
tags,
|
|
86328
|
+
priority,
|
|
86329
|
+
personaIds,
|
|
86330
|
+
goalPrompt,
|
|
86331
|
+
successCriteria,
|
|
86332
|
+
maxIterations,
|
|
86333
|
+
executionTarget,
|
|
86334
|
+
sandboxProvider,
|
|
86335
|
+
sandboxImage,
|
|
86336
|
+
sandboxRemoteDir,
|
|
86337
|
+
sandboxCleanup,
|
|
86338
|
+
e2bTemplate
|
|
86339
|
+
}) => {
|
|
86177
86340
|
try {
|
|
86178
86341
|
return json3(createTestingWorkflow({
|
|
86179
86342
|
name: name21,
|
|
@@ -86184,8 +86347,10 @@ function buildServer() {
|
|
|
86184
86347
|
goal: goalPrompt ? { prompt: goalPrompt, successCriteria, maxIterations } : null,
|
|
86185
86348
|
execution: {
|
|
86186
86349
|
target: executionTarget ?? "local",
|
|
86187
|
-
|
|
86188
|
-
|
|
86350
|
+
provider: sandboxProvider ?? (executionTarget === "connector:e2b" ? "e2b" : undefined),
|
|
86351
|
+
sandboxImage: sandboxImage ?? e2bTemplate,
|
|
86352
|
+
sandboxRemoteDir,
|
|
86353
|
+
sandboxCleanup
|
|
86189
86354
|
}
|
|
86190
86355
|
}));
|
|
86191
86356
|
} catch (error40) {
|
|
@@ -86949,12 +87114,12 @@ function buildServer() {
|
|
|
86949
87114
|
}
|
|
86950
87115
|
if (!resolvedUrl)
|
|
86951
87116
|
return errorResponse(new Error("No URL provided and no default environment set. Pass url or env."));
|
|
86952
|
-
const { execSync:
|
|
87117
|
+
const { execSync: execSync4 } = await import("child_process");
|
|
86953
87118
|
let diffOutput = "";
|
|
86954
87119
|
try {
|
|
86955
87120
|
const ref = baseRef ?? "HEAD";
|
|
86956
|
-
const stagedOut =
|
|
86957
|
-
const unstagedOut =
|
|
87121
|
+
const stagedOut = execSync4(`git diff --cached --name-only`, { cwd: process.cwd(), encoding: "utf-8" }).trim();
|
|
87122
|
+
const unstagedOut = execSync4(`git diff --name-only ${ref}`, { cwd: process.cwd(), encoding: "utf-8" }).trim();
|
|
86958
87123
|
diffOutput = [stagedOut, unstagedOut].filter(Boolean).join(`
|
|
86959
87124
|
`);
|
|
86960
87125
|
} catch {
|
|
@@ -87091,8 +87256,8 @@ function buildServer() {
|
|
|
87091
87256
|
let allFiles = [...filePaths];
|
|
87092
87257
|
if (includeAutoDetect) {
|
|
87093
87258
|
try {
|
|
87094
|
-
const { execSync:
|
|
87095
|
-
const diffOutput =
|
|
87259
|
+
const { execSync: execSync4 } = await import("child_process");
|
|
87260
|
+
const diffOutput = execSync4("git diff --name-only HEAD", { encoding: "utf-8", cwd: process.cwd() }).trim();
|
|
87096
87261
|
const gitFiles = diffOutput.split(`
|
|
87097
87262
|
`).filter(Boolean);
|
|
87098
87263
|
allFiles = [...new Set([...allFiles, ...gitFiles])];
|
|
@@ -87637,7 +87802,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
87637
87802
|
// src/mcp/http.ts
|
|
87638
87803
|
import { createServer } from "http";
|
|
87639
87804
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
87640
|
-
var DEFAULT_MCP_HTTP_PORT =
|
|
87805
|
+
var DEFAULT_MCP_HTTP_PORT = 8840;
|
|
87641
87806
|
var DEFAULT_HOST = "127.0.0.1";
|
|
87642
87807
|
function resolveMcpHttpPort(explicitPort) {
|
|
87643
87808
|
if (explicitPort !== undefined && !Number.isNaN(explicitPort))
|
|
@@ -87659,8 +87824,8 @@ function parseCliPort(args) {
|
|
|
87659
87824
|
}
|
|
87660
87825
|
return;
|
|
87661
87826
|
}
|
|
87662
|
-
function
|
|
87663
|
-
return args.includes("--
|
|
87827
|
+
function isHttpMode(args) {
|
|
87828
|
+
return args.includes("--http") || process.env.MCP_HTTP === "1";
|
|
87664
87829
|
}
|
|
87665
87830
|
async function readJsonBody(req) {
|
|
87666
87831
|
const chunks = [];
|
|
@@ -87748,14 +87913,14 @@ process.on("uncaughtException", (err) => {
|
|
|
87748
87913
|
});
|
|
87749
87914
|
async function main() {
|
|
87750
87915
|
const args = process.argv.slice(2);
|
|
87751
|
-
if (
|
|
87752
|
-
|
|
87753
|
-
const server = buildServer2();
|
|
87754
|
-
const transport = new StdioServerTransport;
|
|
87755
|
-
await server.connect(transport);
|
|
87916
|
+
if (isHttpMode(args)) {
|
|
87917
|
+
await startMcpHttpServer({ name: "testers", port: parseCliPort(args) });
|
|
87756
87918
|
return;
|
|
87757
87919
|
}
|
|
87758
|
-
|
|
87920
|
+
const { buildServer: buildServer2 } = await Promise.resolve().then(() => (init_server(), exports_server));
|
|
87921
|
+
const server = buildServer2();
|
|
87922
|
+
const transport = new StdioServerTransport;
|
|
87923
|
+
await server.connect(transport);
|
|
87759
87924
|
}
|
|
87760
87925
|
main().catch((error40) => {
|
|
87761
87926
|
console.error("Failed to start testers:", error40);
|