struere 0.11.2 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/struere.js +221 -61
- package/dist/cli/commands/logs.d.ts.map +1 -1
- package/dist/cli/commands/triggers.d.ts.map +1 -1
- package/dist/cli/index.js +221 -61
- package/dist/cli/utils/credentials.d.ts +1 -0
- package/dist/cli/utils/credentials.d.ts.map +1 -1
- package/dist/cli/utils/logs.d.ts +5 -0
- package/dist/cli/utils/logs.d.ts.map +1 -1
- package/dist/cli/utils/triggers.d.ts +3 -0
- package/dist/cli/utils/triggers.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/bin/struere.js
CHANGED
|
@@ -33,12 +33,7 @@ function loadCredentials() {
|
|
|
33
33
|
}
|
|
34
34
|
try {
|
|
35
35
|
const data = readFileSync(CREDENTIALS_FILE, "utf-8");
|
|
36
|
-
|
|
37
|
-
if (new Date(credentials.expiresAt) < new Date) {
|
|
38
|
-
clearCredentials();
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
return credentials;
|
|
36
|
+
return JSON.parse(data);
|
|
42
37
|
} catch {
|
|
43
38
|
return null;
|
|
44
39
|
}
|
|
@@ -936,7 +931,7 @@ function getTsConfig() {
|
|
|
936
931
|
rootDir: ".",
|
|
937
932
|
types: ["bun-types"],
|
|
938
933
|
paths: {
|
|
939
|
-
struere: ["./.struere
|
|
934
|
+
struere: ["./.struere"]
|
|
940
935
|
}
|
|
941
936
|
},
|
|
942
937
|
include: ["**/*.ts"],
|
|
@@ -5364,10 +5359,13 @@ function getToken2() {
|
|
|
5364
5359
|
return apiKey || credentials?.token || null;
|
|
5365
5360
|
}
|
|
5366
5361
|
async function convexQuery2(path, args) {
|
|
5367
|
-
|
|
5368
|
-
if (!token)
|
|
5369
|
-
|
|
5370
|
-
|
|
5362
|
+
let token = getToken2();
|
|
5363
|
+
if (!token) {
|
|
5364
|
+
token = await refreshToken();
|
|
5365
|
+
if (!token)
|
|
5366
|
+
return { error: "Not authenticated. Run `struere login`." };
|
|
5367
|
+
}
|
|
5368
|
+
let response = await fetch(`${CONVEX_URL}/api/query`, {
|
|
5371
5369
|
method: "POST",
|
|
5372
5370
|
headers: {
|
|
5373
5371
|
"Content-Type": "application/json",
|
|
@@ -5375,6 +5373,19 @@ async function convexQuery2(path, args) {
|
|
|
5375
5373
|
},
|
|
5376
5374
|
body: JSON.stringify({ path, args })
|
|
5377
5375
|
});
|
|
5376
|
+
if (response.status === 401 || response.status === 403) {
|
|
5377
|
+
const refreshed = await refreshToken();
|
|
5378
|
+
if (refreshed) {
|
|
5379
|
+
response = await fetch(`${CONVEX_URL}/api/query`, {
|
|
5380
|
+
method: "POST",
|
|
5381
|
+
headers: {
|
|
5382
|
+
"Content-Type": "application/json",
|
|
5383
|
+
Authorization: `Bearer ${refreshed}`
|
|
5384
|
+
},
|
|
5385
|
+
body: JSON.stringify({ path, args })
|
|
5386
|
+
});
|
|
5387
|
+
}
|
|
5388
|
+
}
|
|
5378
5389
|
const text = await response.text();
|
|
5379
5390
|
let json;
|
|
5380
5391
|
try {
|
|
@@ -5383,22 +5394,45 @@ async function convexQuery2(path, args) {
|
|
|
5383
5394
|
return { error: text || `HTTP ${response.status}` };
|
|
5384
5395
|
}
|
|
5385
5396
|
if (!response.ok) {
|
|
5386
|
-
const
|
|
5387
|
-
|
|
5397
|
+
const errorData = json.errorData;
|
|
5398
|
+
const msg = errorData?.message || json.message || json.errorMessage || text;
|
|
5399
|
+
const msgStr = String(msg);
|
|
5400
|
+
if (msgStr.includes("OIDC") || msgStr.includes("token")) {
|
|
5401
|
+
return { error: "Session expired. Run `struere logout && struere login`." };
|
|
5402
|
+
}
|
|
5403
|
+
return { error: msgStr };
|
|
5388
5404
|
}
|
|
5389
5405
|
if (json.status === "success")
|
|
5390
5406
|
return { data: json.value };
|
|
5391
|
-
if (json.status === "error")
|
|
5392
|
-
|
|
5407
|
+
if (json.status === "error") {
|
|
5408
|
+
const errMsg = String(json.errorMessage || "Unknown error");
|
|
5409
|
+
if (errMsg.includes("OIDC") || errMsg.includes("token")) {
|
|
5410
|
+
return { error: "Session expired. Run `struere logout && struere login`." };
|
|
5411
|
+
}
|
|
5412
|
+
return { error: errMsg };
|
|
5413
|
+
}
|
|
5393
5414
|
return { error: `Unexpected response: ${text}` };
|
|
5394
5415
|
}
|
|
5395
5416
|
async function queryThreads(options) {
|
|
5396
|
-
|
|
5417
|
+
const result = await convexQuery2("threads:listWithPreviews", {
|
|
5397
5418
|
environment: options.environment,
|
|
5398
5419
|
...options.agentId && { agentId: options.agentId },
|
|
5399
5420
|
...options.channel && { channel: options.channel },
|
|
5400
5421
|
...options.limit && { limit: options.limit }
|
|
5401
5422
|
});
|
|
5423
|
+
if (result.error || !result.data)
|
|
5424
|
+
return result;
|
|
5425
|
+
if (options.phone) {
|
|
5426
|
+
const threads = result.data;
|
|
5427
|
+
const filtered = threads.filter((t) => {
|
|
5428
|
+
const externalId = t.externalId ?? "";
|
|
5429
|
+
const params = t.channelParams;
|
|
5430
|
+
const phone = params?.phoneNumber ?? "";
|
|
5431
|
+
return externalId.includes(options.phone) || phone.includes(options.phone);
|
|
5432
|
+
});
|
|
5433
|
+
return { data: filtered };
|
|
5434
|
+
}
|
|
5435
|
+
return result;
|
|
5402
5436
|
}
|
|
5403
5437
|
async function queryThreadDetail(threadId, messageLimit) {
|
|
5404
5438
|
return convexQuery2("threads:getWithMessages", {
|
|
@@ -5409,6 +5443,31 @@ async function queryThreadDetail(threadId, messageLimit) {
|
|
|
5409
5443
|
async function queryThreadExecutions(threadId) {
|
|
5410
5444
|
return convexQuery2("executions:getByThread", { threadId });
|
|
5411
5445
|
}
|
|
5446
|
+
async function resolveThreadId(shortId, environment) {
|
|
5447
|
+
if (shortId.includes("|") || shortId.length > 20) {
|
|
5448
|
+
return { data: shortId };
|
|
5449
|
+
}
|
|
5450
|
+
const result = await queryThreads({ environment: environment ?? "development", limit: 100 });
|
|
5451
|
+
if (result.error || !result.data)
|
|
5452
|
+
return { error: result.error ?? "Could not fetch threads" };
|
|
5453
|
+
const threads = result.data;
|
|
5454
|
+
const match = threads.find((t) => t._id.endsWith(shortId));
|
|
5455
|
+
if (!match) {
|
|
5456
|
+
for (const env of ["production", "development", "eval"]) {
|
|
5457
|
+
if (env === (environment ?? "development"))
|
|
5458
|
+
continue;
|
|
5459
|
+
const envResult = await queryThreads({ environment: env, limit: 100 });
|
|
5460
|
+
if (envResult.data) {
|
|
5461
|
+
const envThreads = envResult.data;
|
|
5462
|
+
const envMatch = envThreads.find((t) => t._id.endsWith(shortId));
|
|
5463
|
+
if (envMatch)
|
|
5464
|
+
return { data: envMatch._id };
|
|
5465
|
+
}
|
|
5466
|
+
}
|
|
5467
|
+
return { error: `No thread found matching "${shortId}"` };
|
|
5468
|
+
}
|
|
5469
|
+
return { data: match._id };
|
|
5470
|
+
}
|
|
5412
5471
|
async function resolveAgentSlug(slug, organizationId) {
|
|
5413
5472
|
const result = await convexQuery2("agents:getBySlug", { slug, ...organizationId && { organizationId } });
|
|
5414
5473
|
if (result.error)
|
|
@@ -5477,7 +5536,7 @@ function formatTimestamp(ts) {
|
|
|
5477
5536
|
return d.toTimeString().slice(0, 8);
|
|
5478
5537
|
}
|
|
5479
5538
|
var logsCommand = new Command14("logs").description("View and debug agent conversations");
|
|
5480
|
-
logsCommand.command("list", { isDefault: true }).description("List recent conversations").option("--env <environment>", "Environment (development|production|eval)", "development").option("--agent <slug>", "Filter by agent slug").option("--channel <channel>", "Filter by channel (api|whatsapp|widget|dashboard)").option("--limit <n>", "Maximum results", "20").option("--json", "Output raw JSON").action(async (opts) => {
|
|
5539
|
+
logsCommand.command("list", { isDefault: true }).description("List recent conversations").option("--env <environment>", "Environment (development|production|eval)", "development").option("--agent <slug>", "Filter by agent slug").option("--channel <channel>", "Filter by channel (api|whatsapp|widget|dashboard)").option("--phone <number>", "Filter by phone number").option("--limit <n>", "Maximum results", "20").option("--json", "Output raw JSON").action(async (opts) => {
|
|
5481
5540
|
await ensureAuth2();
|
|
5482
5541
|
const spinner = ora12();
|
|
5483
5542
|
const orgId = getOrgId2();
|
|
@@ -5498,6 +5557,7 @@ logsCommand.command("list", { isDefault: true }).description("List recent conver
|
|
|
5498
5557
|
environment: opts.env,
|
|
5499
5558
|
agentId,
|
|
5500
5559
|
channel: opts.channel,
|
|
5560
|
+
phone: opts.phone,
|
|
5501
5561
|
limit: parseInt(opts.limit, 10)
|
|
5502
5562
|
});
|
|
5503
5563
|
if (error || !data) {
|
|
@@ -5506,11 +5566,12 @@ logsCommand.command("list", { isDefault: true }).description("List recent conver
|
|
|
5506
5566
|
process.exit(1);
|
|
5507
5567
|
}
|
|
5508
5568
|
const threads = data;
|
|
5509
|
-
spinner.succeed(`Found ${threads.length} conversations`);
|
|
5510
5569
|
if (opts.json) {
|
|
5570
|
+
spinner.stop();
|
|
5511
5571
|
console.log(JSON.stringify(threads, null, 2));
|
|
5512
5572
|
return;
|
|
5513
5573
|
}
|
|
5574
|
+
spinner.succeed(`Found ${threads.length} conversations`);
|
|
5514
5575
|
console.log();
|
|
5515
5576
|
renderTable([
|
|
5516
5577
|
{ key: "id", label: "ID", width: 14 },
|
|
@@ -5532,37 +5593,86 @@ logsCommand.command("list", { isDefault: true }).description("List recent conver
|
|
|
5532
5593
|
}));
|
|
5533
5594
|
console.log();
|
|
5534
5595
|
});
|
|
5535
|
-
logsCommand.command("view <thread-id>").description("View conversation messages").option("--exec", "Include execution details").option("--json", "Output raw JSON").option("--limit <n>", "Message limit", "100").action(async (
|
|
5596
|
+
logsCommand.command("view <thread-id>").description("View conversation messages").option("--env <environment>", "Environment hint for resolving short IDs").option("--exec", "Include execution details").option("--verbose", "Show full tool call arguments and results").option("--tail", "Show most recent messages (use with --limit)").option("--json", "Output raw JSON").option("--limit <n>", "Message limit", "100").action(async (rawThreadId, opts) => {
|
|
5536
5597
|
await ensureAuth2();
|
|
5537
5598
|
const spinner = ora12();
|
|
5599
|
+
spinner.start("Resolving thread");
|
|
5600
|
+
const resolved = await resolveThreadId(rawThreadId, opts.env);
|
|
5601
|
+
if (resolved.error || !resolved.data) {
|
|
5602
|
+
spinner.fail("Thread not found");
|
|
5603
|
+
console.log(chalk16.red("Error:"), resolved.error || `No thread matched "${rawThreadId}"`);
|
|
5604
|
+
process.exit(1);
|
|
5605
|
+
}
|
|
5606
|
+
const threadId = resolved.data;
|
|
5607
|
+
spinner.stop();
|
|
5538
5608
|
spinner.start("Fetching conversation");
|
|
5539
|
-
const
|
|
5609
|
+
const fetchLimit = opts.tail ? 1000 : parseInt(opts.limit, 10);
|
|
5610
|
+
const { data, error } = await queryThreadDetail(threadId, fetchLimit);
|
|
5540
5611
|
if (error || !data) {
|
|
5541
5612
|
spinner.fail("Failed to fetch conversation");
|
|
5542
5613
|
console.log(chalk16.red("Error:"), error || "Thread not found");
|
|
5543
5614
|
process.exit(1);
|
|
5544
5615
|
}
|
|
5545
|
-
spinner.
|
|
5616
|
+
spinner.stop();
|
|
5546
5617
|
const result = data;
|
|
5618
|
+
let executions = [];
|
|
5619
|
+
if (opts.exec) {
|
|
5620
|
+
const execResult = await queryThreadExecutions(threadId);
|
|
5621
|
+
if (execResult.data) {
|
|
5622
|
+
executions = execResult.data;
|
|
5623
|
+
}
|
|
5624
|
+
}
|
|
5547
5625
|
if (opts.json) {
|
|
5548
|
-
console.log(JSON.stringify(result, null, 2));
|
|
5626
|
+
console.log(JSON.stringify(opts.exec ? { ...result, executions } : result, null, 2));
|
|
5549
5627
|
return;
|
|
5550
5628
|
}
|
|
5629
|
+
const truncLen = opts.verbose ? 1e4 : 500;
|
|
5551
5630
|
console.log();
|
|
5552
5631
|
console.log(chalk16.bold(`Thread: ${result._id}`));
|
|
5553
5632
|
console.log(chalk16.gray(` Environment: ${result.environment ?? "unknown"} Channel: ${result.channel ?? "api"}`));
|
|
5554
|
-
console.log(chalk16.gray("\u2500".repeat(
|
|
5555
|
-
|
|
5633
|
+
console.log(chalk16.gray("\u2500".repeat(80)));
|
|
5634
|
+
let messages = result.messages ?? [];
|
|
5635
|
+
if (opts.tail) {
|
|
5636
|
+
const limit = parseInt(opts.limit, 10);
|
|
5637
|
+
if (messages.length > limit) {
|
|
5638
|
+
messages = messages.slice(-limit);
|
|
5639
|
+
console.log(chalk16.dim(` ... ${messages.length} earlier messages hidden (showing last ${limit})`));
|
|
5640
|
+
}
|
|
5641
|
+
}
|
|
5642
|
+
const execByTime = new Map;
|
|
5643
|
+
for (const exec of executions) {
|
|
5644
|
+
const ts = exec.createdAt ?? exec._creationTime ?? 0;
|
|
5645
|
+
execByTime.set(ts, exec);
|
|
5646
|
+
}
|
|
5556
5647
|
for (let i = 0;i < messages.length; i++) {
|
|
5557
5648
|
const msg = messages[i];
|
|
5558
5649
|
const ts = formatTimestamp(msg.createdAt ?? msg._creationTime ?? Date.now());
|
|
5650
|
+
const msgTs = msg.createdAt ?? msg._creationTime ?? 0;
|
|
5559
5651
|
const role = msg.role;
|
|
5560
5652
|
const content = msg.content ?? "";
|
|
5561
5653
|
const toolCalls = msg.toolCalls;
|
|
5654
|
+
const attachments = msg.attachments;
|
|
5655
|
+
const channelData = msg.channelData;
|
|
5562
5656
|
if (role === "user") {
|
|
5563
5657
|
console.log();
|
|
5564
5658
|
console.log(` ${chalk16.gray(`[${ts}]`)} ${chalk16.cyan("User")}`);
|
|
5565
5659
|
console.log(` ${content}`);
|
|
5660
|
+
if (attachments?.length) {
|
|
5661
|
+
for (const att of attachments) {
|
|
5662
|
+
console.log(` ${chalk16.magenta(`\uD83D\uDCCE ${att.type}`)} ${att.fileName ?? ""} ${chalk16.dim(att.mimeType ?? "")}`);
|
|
5663
|
+
console.log(` ${chalk16.dim(` url: ${att.url?.slice(0, 120)}`)}`);
|
|
5664
|
+
if (att.attachmentId)
|
|
5665
|
+
console.log(` ${chalk16.dim(` attachmentId: ${att.attachmentId}`)}`);
|
|
5666
|
+
}
|
|
5667
|
+
}
|
|
5668
|
+
if (channelData && typeof channelData === "object") {
|
|
5669
|
+
const cdType = channelData.type;
|
|
5670
|
+
const mediaStorageId = channelData.mediaStorageId;
|
|
5671
|
+
const mediaDirectUrl = channelData.mediaDirectUrl;
|
|
5672
|
+
if (cdType && cdType !== "text") {
|
|
5673
|
+
console.log(` ${chalk16.dim(` channel: ${cdType}${mediaStorageId ? ` storageId:${mediaStorageId}` : ""}${mediaDirectUrl ? ` directUrl:${String(mediaDirectUrl).slice(0, 80)}` : ""}`)}`);
|
|
5674
|
+
}
|
|
5675
|
+
}
|
|
5566
5676
|
} else if (role === "assistant" && toolCalls?.length) {
|
|
5567
5677
|
console.log();
|
|
5568
5678
|
console.log(` ${chalk16.gray(`[${ts}]`)} ${chalk16.green("Agent")}`);
|
|
@@ -5570,57 +5680,44 @@ logsCommand.command("view <thread-id>").description("View conversation messages"
|
|
|
5570
5680
|
console.log(` ${content}`);
|
|
5571
5681
|
for (const call of toolCalls) {
|
|
5572
5682
|
console.log(` ${chalk16.yellow("Tool: " + call.name)}`);
|
|
5573
|
-
console.log(` ${chalk16.dim("\u2192 " + JSON.stringify(call.arguments).slice(0,
|
|
5683
|
+
console.log(` ${chalk16.dim("\u2192 " + JSON.stringify(call.arguments).slice(0, truncLen))}`);
|
|
5574
5684
|
}
|
|
5575
5685
|
} else if (role === "assistant") {
|
|
5576
5686
|
console.log();
|
|
5577
5687
|
console.log(` ${chalk16.gray(`[${ts}]`)} ${chalk16.green("Agent")}`);
|
|
5578
5688
|
console.log(` ${content}`);
|
|
5579
5689
|
} else if (role === "tool") {
|
|
5580
|
-
console.log(` ${chalk16.dim("\u2190 " + content.slice(0,
|
|
5690
|
+
console.log(` ${chalk16.dim("\u2190 " + content.slice(0, truncLen))}`);
|
|
5581
5691
|
} else if (role === "system") {
|
|
5582
5692
|
console.log();
|
|
5583
5693
|
console.log(` ${chalk16.dim("[System] " + content.slice(0, 100))}`);
|
|
5584
5694
|
}
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
}
|
|
5595
|
-
spinner.succeed("Executions loaded");
|
|
5596
|
-
const executions = execResult.data;
|
|
5597
|
-
console.log();
|
|
5598
|
-
console.log(chalk16.bold("Executions"));
|
|
5599
|
-
console.log(chalk16.gray("\u2500".repeat(60)));
|
|
5600
|
-
for (const exec of executions) {
|
|
5601
|
-
const status = exec.status;
|
|
5602
|
-
const statusColor = status === "success" ? chalk16.green : status === "error" ? chalk16.red : chalk16.yellow;
|
|
5603
|
-
const toolCallDetails = exec.toolCallDetails;
|
|
5604
|
-
console.log();
|
|
5605
|
-
console.log(` ${chalk16.gray("Status:")} ${statusColor(status)}`);
|
|
5606
|
-
if (exec.model)
|
|
5607
|
-
console.log(` ${chalk16.gray("Model:")} ${exec.model}`);
|
|
5608
|
-
if (exec.inputTokens || exec.outputTokens)
|
|
5609
|
-
console.log(` ${chalk16.gray("Tokens:")} ${exec.inputTokens ?? 0} in / ${exec.outputTokens ?? 0} out`);
|
|
5610
|
-
if (exec.durationMs)
|
|
5611
|
-
console.log(` ${chalk16.gray("Duration:")} ${exec.durationMs}ms`);
|
|
5612
|
-
if (toolCallDetails?.length) {
|
|
5613
|
-
console.log(` ${chalk16.gray("Tools:")} ${toolCallDetails.length} calls`);
|
|
5614
|
-
for (const tc of toolCallDetails) {
|
|
5615
|
-
console.log(` ${tc.name} (${tc.durationMs}ms) -> ${tc.status}`);
|
|
5695
|
+
if (opts.exec && role === "assistant" && toolCalls?.length) {
|
|
5696
|
+
let closestExec;
|
|
5697
|
+
let closestDiff = Infinity;
|
|
5698
|
+
for (const exec of executions) {
|
|
5699
|
+
const execTs = exec.createdAt ?? exec._creationTime ?? 0;
|
|
5700
|
+
const diff = Math.abs(execTs - msgTs);
|
|
5701
|
+
if (diff < closestDiff) {
|
|
5702
|
+
closestDiff = diff;
|
|
5703
|
+
closestExec = exec;
|
|
5616
5704
|
}
|
|
5617
5705
|
}
|
|
5618
|
-
if (
|
|
5619
|
-
|
|
5706
|
+
if (closestExec && closestDiff < 30000) {
|
|
5707
|
+
const status = closestExec.status;
|
|
5708
|
+
const statusColor = status === "success" ? chalk16.green : status === "error" ? chalk16.red : chalk16.yellow;
|
|
5709
|
+
const model = closestExec.model;
|
|
5710
|
+
const duration = closestExec.durationMs;
|
|
5711
|
+
const inputTokens = closestExec.inputTokens;
|
|
5712
|
+
const outputTokens = closestExec.outputTokens;
|
|
5713
|
+
console.log(` ${chalk16.dim(` exec: ${statusColor(status)} ${model ?? ""} ${inputTokens ?? 0}in/${outputTokens ?? 0}out ${duration ?? 0}ms`)}`);
|
|
5714
|
+
if (closestExec.errorMessage) {
|
|
5715
|
+
console.log(` ${chalk16.red(` error: ${closestExec.errorMessage}`)}`);
|
|
5716
|
+
}
|
|
5620
5717
|
}
|
|
5621
5718
|
}
|
|
5622
|
-
console.log();
|
|
5623
5719
|
}
|
|
5720
|
+
console.log();
|
|
5624
5721
|
});
|
|
5625
5722
|
|
|
5626
5723
|
// src/cli/commands/eval.ts
|
|
@@ -6978,6 +7075,34 @@ async function listTriggerExecutions(options) {
|
|
|
6978
7075
|
async function getTriggerExecutionDetail(eventId) {
|
|
6979
7076
|
return convexQuery6("triggers:getExecutionDetail", { eventId });
|
|
6980
7077
|
}
|
|
7078
|
+
async function convexAction3(path, args) {
|
|
7079
|
+
const token = getToken6();
|
|
7080
|
+
const response = await fetch(`${CONVEX_URL}/api/action`, {
|
|
7081
|
+
method: "POST",
|
|
7082
|
+
headers: {
|
|
7083
|
+
"Content-Type": "application/json",
|
|
7084
|
+
Authorization: `Bearer ${token}`
|
|
7085
|
+
},
|
|
7086
|
+
body: JSON.stringify({ path, args })
|
|
7087
|
+
});
|
|
7088
|
+
const text = await response.text();
|
|
7089
|
+
let json;
|
|
7090
|
+
try {
|
|
7091
|
+
json = JSON.parse(text);
|
|
7092
|
+
} catch {
|
|
7093
|
+
throw new Error(text || `HTTP ${response.status}`);
|
|
7094
|
+
}
|
|
7095
|
+
if (!response.ok) {
|
|
7096
|
+
throw new Error(json.errorData?.message || json.errorMessage || text);
|
|
7097
|
+
}
|
|
7098
|
+
if (json.status === "error") {
|
|
7099
|
+
throw new Error(json.errorMessage || "Unknown error from Convex");
|
|
7100
|
+
}
|
|
7101
|
+
return json.value;
|
|
7102
|
+
}
|
|
7103
|
+
async function retryImmediateExecution(eventId, environment) {
|
|
7104
|
+
return convexAction3("triggers:retryImmediateExecution", { eventId, environment });
|
|
7105
|
+
}
|
|
6981
7106
|
|
|
6982
7107
|
// src/cli/commands/triggers.ts
|
|
6983
7108
|
async function ensureAuth5() {
|
|
@@ -7623,6 +7748,41 @@ triggersCommand.command("disable <slug>").description("Disable a trigger").optio
|
|
|
7623
7748
|
process.exit(1);
|
|
7624
7749
|
}
|
|
7625
7750
|
});
|
|
7751
|
+
triggersCommand.command("retry-event <event-id>").description("Retry a failed immediate trigger execution").option("--env <environment>", "Environment (development|production|eval)", "development").option("--json", "Output raw JSON").option("--confirm", "Skip production confirmation").action(async (eventId, opts) => {
|
|
7752
|
+
await ensureAuth5();
|
|
7753
|
+
const spinner = ora14();
|
|
7754
|
+
const environment = opts.env;
|
|
7755
|
+
if (environment === "production" && !opts.confirm && isInteractive()) {
|
|
7756
|
+
const readline = await import("readline");
|
|
7757
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
7758
|
+
await new Promise((resolve) => {
|
|
7759
|
+
rl.question(chalk20.yellow(`WARNING: Retrying execution in PRODUCTION environment.
|
|
7760
|
+
Press Enter to continue or Ctrl+C to cancel: `), resolve);
|
|
7761
|
+
});
|
|
7762
|
+
rl.close();
|
|
7763
|
+
}
|
|
7764
|
+
try {
|
|
7765
|
+
spinner.start("Retrying failed execution...");
|
|
7766
|
+
const result = await retryImmediateExecution(eventId, environment);
|
|
7767
|
+
if (result.success) {
|
|
7768
|
+
spinner.succeed(chalk20.green(`Execution retried successfully`));
|
|
7769
|
+
} else {
|
|
7770
|
+
spinner.fail(chalk20.red(`Execution retry failed again`));
|
|
7771
|
+
}
|
|
7772
|
+
if (opts.json) {
|
|
7773
|
+
console.log(JSON.stringify(result));
|
|
7774
|
+
}
|
|
7775
|
+
} catch (err) {
|
|
7776
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
7777
|
+
spinner.fail("Failed to retry execution");
|
|
7778
|
+
if (opts.json) {
|
|
7779
|
+
console.log(JSON.stringify({ success: false, error: message }));
|
|
7780
|
+
} else {
|
|
7781
|
+
console.log(chalk20.red("Error:"), message);
|
|
7782
|
+
}
|
|
7783
|
+
process.exit(1);
|
|
7784
|
+
}
|
|
7785
|
+
});
|
|
7626
7786
|
|
|
7627
7787
|
// src/cli/commands/compile-prompt.ts
|
|
7628
7788
|
import { Command as Command19 } from "commander";
|
|
@@ -8182,7 +8342,7 @@ var chatCommand = new Command21("chat").description("Chat with an agent").argume
|
|
|
8182
8342
|
// package.json
|
|
8183
8343
|
var package_default = {
|
|
8184
8344
|
name: "struere",
|
|
8185
|
-
version: "0.
|
|
8345
|
+
version: "0.12.0",
|
|
8186
8346
|
description: "Build, test, and deploy AI agents",
|
|
8187
8347
|
keywords: [
|
|
8188
8348
|
"ai",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA8EnC,eAAO,MAAM,WAAW,SAC4B,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"triggers.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/triggers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"triggers.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/triggers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA2KnC,eAAO,MAAM,eAAe,SACyB,CAAA"}
|
package/dist/cli/index.js
CHANGED
|
@@ -33,12 +33,7 @@ function loadCredentials() {
|
|
|
33
33
|
}
|
|
34
34
|
try {
|
|
35
35
|
const data = readFileSync(CREDENTIALS_FILE, "utf-8");
|
|
36
|
-
|
|
37
|
-
if (new Date(credentials.expiresAt) < new Date) {
|
|
38
|
-
clearCredentials();
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
return credentials;
|
|
36
|
+
return JSON.parse(data);
|
|
42
37
|
} catch {
|
|
43
38
|
return null;
|
|
44
39
|
}
|
|
@@ -936,7 +931,7 @@ function getTsConfig() {
|
|
|
936
931
|
rootDir: ".",
|
|
937
932
|
types: ["bun-types"],
|
|
938
933
|
paths: {
|
|
939
|
-
struere: ["./.struere
|
|
934
|
+
struere: ["./.struere"]
|
|
940
935
|
}
|
|
941
936
|
},
|
|
942
937
|
include: ["**/*.ts"],
|
|
@@ -5364,10 +5359,13 @@ function getToken2() {
|
|
|
5364
5359
|
return apiKey || credentials?.token || null;
|
|
5365
5360
|
}
|
|
5366
5361
|
async function convexQuery2(path, args) {
|
|
5367
|
-
|
|
5368
|
-
if (!token)
|
|
5369
|
-
|
|
5370
|
-
|
|
5362
|
+
let token = getToken2();
|
|
5363
|
+
if (!token) {
|
|
5364
|
+
token = await refreshToken();
|
|
5365
|
+
if (!token)
|
|
5366
|
+
return { error: "Not authenticated. Run `struere login`." };
|
|
5367
|
+
}
|
|
5368
|
+
let response = await fetch(`${CONVEX_URL}/api/query`, {
|
|
5371
5369
|
method: "POST",
|
|
5372
5370
|
headers: {
|
|
5373
5371
|
"Content-Type": "application/json",
|
|
@@ -5375,6 +5373,19 @@ async function convexQuery2(path, args) {
|
|
|
5375
5373
|
},
|
|
5376
5374
|
body: JSON.stringify({ path, args })
|
|
5377
5375
|
});
|
|
5376
|
+
if (response.status === 401 || response.status === 403) {
|
|
5377
|
+
const refreshed = await refreshToken();
|
|
5378
|
+
if (refreshed) {
|
|
5379
|
+
response = await fetch(`${CONVEX_URL}/api/query`, {
|
|
5380
|
+
method: "POST",
|
|
5381
|
+
headers: {
|
|
5382
|
+
"Content-Type": "application/json",
|
|
5383
|
+
Authorization: `Bearer ${refreshed}`
|
|
5384
|
+
},
|
|
5385
|
+
body: JSON.stringify({ path, args })
|
|
5386
|
+
});
|
|
5387
|
+
}
|
|
5388
|
+
}
|
|
5378
5389
|
const text = await response.text();
|
|
5379
5390
|
let json;
|
|
5380
5391
|
try {
|
|
@@ -5383,22 +5394,45 @@ async function convexQuery2(path, args) {
|
|
|
5383
5394
|
return { error: text || `HTTP ${response.status}` };
|
|
5384
5395
|
}
|
|
5385
5396
|
if (!response.ok) {
|
|
5386
|
-
const
|
|
5387
|
-
|
|
5397
|
+
const errorData = json.errorData;
|
|
5398
|
+
const msg = errorData?.message || json.message || json.errorMessage || text;
|
|
5399
|
+
const msgStr = String(msg);
|
|
5400
|
+
if (msgStr.includes("OIDC") || msgStr.includes("token")) {
|
|
5401
|
+
return { error: "Session expired. Run `struere logout && struere login`." };
|
|
5402
|
+
}
|
|
5403
|
+
return { error: msgStr };
|
|
5388
5404
|
}
|
|
5389
5405
|
if (json.status === "success")
|
|
5390
5406
|
return { data: json.value };
|
|
5391
|
-
if (json.status === "error")
|
|
5392
|
-
|
|
5407
|
+
if (json.status === "error") {
|
|
5408
|
+
const errMsg = String(json.errorMessage || "Unknown error");
|
|
5409
|
+
if (errMsg.includes("OIDC") || errMsg.includes("token")) {
|
|
5410
|
+
return { error: "Session expired. Run `struere logout && struere login`." };
|
|
5411
|
+
}
|
|
5412
|
+
return { error: errMsg };
|
|
5413
|
+
}
|
|
5393
5414
|
return { error: `Unexpected response: ${text}` };
|
|
5394
5415
|
}
|
|
5395
5416
|
async function queryThreads(options) {
|
|
5396
|
-
|
|
5417
|
+
const result = await convexQuery2("threads:listWithPreviews", {
|
|
5397
5418
|
environment: options.environment,
|
|
5398
5419
|
...options.agentId && { agentId: options.agentId },
|
|
5399
5420
|
...options.channel && { channel: options.channel },
|
|
5400
5421
|
...options.limit && { limit: options.limit }
|
|
5401
5422
|
});
|
|
5423
|
+
if (result.error || !result.data)
|
|
5424
|
+
return result;
|
|
5425
|
+
if (options.phone) {
|
|
5426
|
+
const threads = result.data;
|
|
5427
|
+
const filtered = threads.filter((t) => {
|
|
5428
|
+
const externalId = t.externalId ?? "";
|
|
5429
|
+
const params = t.channelParams;
|
|
5430
|
+
const phone = params?.phoneNumber ?? "";
|
|
5431
|
+
return externalId.includes(options.phone) || phone.includes(options.phone);
|
|
5432
|
+
});
|
|
5433
|
+
return { data: filtered };
|
|
5434
|
+
}
|
|
5435
|
+
return result;
|
|
5402
5436
|
}
|
|
5403
5437
|
async function queryThreadDetail(threadId, messageLimit) {
|
|
5404
5438
|
return convexQuery2("threads:getWithMessages", {
|
|
@@ -5409,6 +5443,31 @@ async function queryThreadDetail(threadId, messageLimit) {
|
|
|
5409
5443
|
async function queryThreadExecutions(threadId) {
|
|
5410
5444
|
return convexQuery2("executions:getByThread", { threadId });
|
|
5411
5445
|
}
|
|
5446
|
+
async function resolveThreadId(shortId, environment) {
|
|
5447
|
+
if (shortId.includes("|") || shortId.length > 20) {
|
|
5448
|
+
return { data: shortId };
|
|
5449
|
+
}
|
|
5450
|
+
const result = await queryThreads({ environment: environment ?? "development", limit: 100 });
|
|
5451
|
+
if (result.error || !result.data)
|
|
5452
|
+
return { error: result.error ?? "Could not fetch threads" };
|
|
5453
|
+
const threads = result.data;
|
|
5454
|
+
const match = threads.find((t) => t._id.endsWith(shortId));
|
|
5455
|
+
if (!match) {
|
|
5456
|
+
for (const env of ["production", "development", "eval"]) {
|
|
5457
|
+
if (env === (environment ?? "development"))
|
|
5458
|
+
continue;
|
|
5459
|
+
const envResult = await queryThreads({ environment: env, limit: 100 });
|
|
5460
|
+
if (envResult.data) {
|
|
5461
|
+
const envThreads = envResult.data;
|
|
5462
|
+
const envMatch = envThreads.find((t) => t._id.endsWith(shortId));
|
|
5463
|
+
if (envMatch)
|
|
5464
|
+
return { data: envMatch._id };
|
|
5465
|
+
}
|
|
5466
|
+
}
|
|
5467
|
+
return { error: `No thread found matching "${shortId}"` };
|
|
5468
|
+
}
|
|
5469
|
+
return { data: match._id };
|
|
5470
|
+
}
|
|
5412
5471
|
async function resolveAgentSlug(slug, organizationId) {
|
|
5413
5472
|
const result = await convexQuery2("agents:getBySlug", { slug, ...organizationId && { organizationId } });
|
|
5414
5473
|
if (result.error)
|
|
@@ -5477,7 +5536,7 @@ function formatTimestamp(ts) {
|
|
|
5477
5536
|
return d.toTimeString().slice(0, 8);
|
|
5478
5537
|
}
|
|
5479
5538
|
var logsCommand = new Command14("logs").description("View and debug agent conversations");
|
|
5480
|
-
logsCommand.command("list", { isDefault: true }).description("List recent conversations").option("--env <environment>", "Environment (development|production|eval)", "development").option("--agent <slug>", "Filter by agent slug").option("--channel <channel>", "Filter by channel (api|whatsapp|widget|dashboard)").option("--limit <n>", "Maximum results", "20").option("--json", "Output raw JSON").action(async (opts) => {
|
|
5539
|
+
logsCommand.command("list", { isDefault: true }).description("List recent conversations").option("--env <environment>", "Environment (development|production|eval)", "development").option("--agent <slug>", "Filter by agent slug").option("--channel <channel>", "Filter by channel (api|whatsapp|widget|dashboard)").option("--phone <number>", "Filter by phone number").option("--limit <n>", "Maximum results", "20").option("--json", "Output raw JSON").action(async (opts) => {
|
|
5481
5540
|
await ensureAuth2();
|
|
5482
5541
|
const spinner = ora12();
|
|
5483
5542
|
const orgId = getOrgId2();
|
|
@@ -5498,6 +5557,7 @@ logsCommand.command("list", { isDefault: true }).description("List recent conver
|
|
|
5498
5557
|
environment: opts.env,
|
|
5499
5558
|
agentId,
|
|
5500
5559
|
channel: opts.channel,
|
|
5560
|
+
phone: opts.phone,
|
|
5501
5561
|
limit: parseInt(opts.limit, 10)
|
|
5502
5562
|
});
|
|
5503
5563
|
if (error || !data) {
|
|
@@ -5506,11 +5566,12 @@ logsCommand.command("list", { isDefault: true }).description("List recent conver
|
|
|
5506
5566
|
process.exit(1);
|
|
5507
5567
|
}
|
|
5508
5568
|
const threads = data;
|
|
5509
|
-
spinner.succeed(`Found ${threads.length} conversations`);
|
|
5510
5569
|
if (opts.json) {
|
|
5570
|
+
spinner.stop();
|
|
5511
5571
|
console.log(JSON.stringify(threads, null, 2));
|
|
5512
5572
|
return;
|
|
5513
5573
|
}
|
|
5574
|
+
spinner.succeed(`Found ${threads.length} conversations`);
|
|
5514
5575
|
console.log();
|
|
5515
5576
|
renderTable([
|
|
5516
5577
|
{ key: "id", label: "ID", width: 14 },
|
|
@@ -5532,37 +5593,86 @@ logsCommand.command("list", { isDefault: true }).description("List recent conver
|
|
|
5532
5593
|
}));
|
|
5533
5594
|
console.log();
|
|
5534
5595
|
});
|
|
5535
|
-
logsCommand.command("view <thread-id>").description("View conversation messages").option("--exec", "Include execution details").option("--json", "Output raw JSON").option("--limit <n>", "Message limit", "100").action(async (
|
|
5596
|
+
logsCommand.command("view <thread-id>").description("View conversation messages").option("--env <environment>", "Environment hint for resolving short IDs").option("--exec", "Include execution details").option("--verbose", "Show full tool call arguments and results").option("--tail", "Show most recent messages (use with --limit)").option("--json", "Output raw JSON").option("--limit <n>", "Message limit", "100").action(async (rawThreadId, opts) => {
|
|
5536
5597
|
await ensureAuth2();
|
|
5537
5598
|
const spinner = ora12();
|
|
5599
|
+
spinner.start("Resolving thread");
|
|
5600
|
+
const resolved = await resolveThreadId(rawThreadId, opts.env);
|
|
5601
|
+
if (resolved.error || !resolved.data) {
|
|
5602
|
+
spinner.fail("Thread not found");
|
|
5603
|
+
console.log(chalk16.red("Error:"), resolved.error || `No thread matched "${rawThreadId}"`);
|
|
5604
|
+
process.exit(1);
|
|
5605
|
+
}
|
|
5606
|
+
const threadId = resolved.data;
|
|
5607
|
+
spinner.stop();
|
|
5538
5608
|
spinner.start("Fetching conversation");
|
|
5539
|
-
const
|
|
5609
|
+
const fetchLimit = opts.tail ? 1000 : parseInt(opts.limit, 10);
|
|
5610
|
+
const { data, error } = await queryThreadDetail(threadId, fetchLimit);
|
|
5540
5611
|
if (error || !data) {
|
|
5541
5612
|
spinner.fail("Failed to fetch conversation");
|
|
5542
5613
|
console.log(chalk16.red("Error:"), error || "Thread not found");
|
|
5543
5614
|
process.exit(1);
|
|
5544
5615
|
}
|
|
5545
|
-
spinner.
|
|
5616
|
+
spinner.stop();
|
|
5546
5617
|
const result = data;
|
|
5618
|
+
let executions = [];
|
|
5619
|
+
if (opts.exec) {
|
|
5620
|
+
const execResult = await queryThreadExecutions(threadId);
|
|
5621
|
+
if (execResult.data) {
|
|
5622
|
+
executions = execResult.data;
|
|
5623
|
+
}
|
|
5624
|
+
}
|
|
5547
5625
|
if (opts.json) {
|
|
5548
|
-
console.log(JSON.stringify(result, null, 2));
|
|
5626
|
+
console.log(JSON.stringify(opts.exec ? { ...result, executions } : result, null, 2));
|
|
5549
5627
|
return;
|
|
5550
5628
|
}
|
|
5629
|
+
const truncLen = opts.verbose ? 1e4 : 500;
|
|
5551
5630
|
console.log();
|
|
5552
5631
|
console.log(chalk16.bold(`Thread: ${result._id}`));
|
|
5553
5632
|
console.log(chalk16.gray(` Environment: ${result.environment ?? "unknown"} Channel: ${result.channel ?? "api"}`));
|
|
5554
|
-
console.log(chalk16.gray("\u2500".repeat(
|
|
5555
|
-
|
|
5633
|
+
console.log(chalk16.gray("\u2500".repeat(80)));
|
|
5634
|
+
let messages = result.messages ?? [];
|
|
5635
|
+
if (opts.tail) {
|
|
5636
|
+
const limit = parseInt(opts.limit, 10);
|
|
5637
|
+
if (messages.length > limit) {
|
|
5638
|
+
messages = messages.slice(-limit);
|
|
5639
|
+
console.log(chalk16.dim(` ... ${messages.length} earlier messages hidden (showing last ${limit})`));
|
|
5640
|
+
}
|
|
5641
|
+
}
|
|
5642
|
+
const execByTime = new Map;
|
|
5643
|
+
for (const exec of executions) {
|
|
5644
|
+
const ts = exec.createdAt ?? exec._creationTime ?? 0;
|
|
5645
|
+
execByTime.set(ts, exec);
|
|
5646
|
+
}
|
|
5556
5647
|
for (let i = 0;i < messages.length; i++) {
|
|
5557
5648
|
const msg = messages[i];
|
|
5558
5649
|
const ts = formatTimestamp(msg.createdAt ?? msg._creationTime ?? Date.now());
|
|
5650
|
+
const msgTs = msg.createdAt ?? msg._creationTime ?? 0;
|
|
5559
5651
|
const role = msg.role;
|
|
5560
5652
|
const content = msg.content ?? "";
|
|
5561
5653
|
const toolCalls = msg.toolCalls;
|
|
5654
|
+
const attachments = msg.attachments;
|
|
5655
|
+
const channelData = msg.channelData;
|
|
5562
5656
|
if (role === "user") {
|
|
5563
5657
|
console.log();
|
|
5564
5658
|
console.log(` ${chalk16.gray(`[${ts}]`)} ${chalk16.cyan("User")}`);
|
|
5565
5659
|
console.log(` ${content}`);
|
|
5660
|
+
if (attachments?.length) {
|
|
5661
|
+
for (const att of attachments) {
|
|
5662
|
+
console.log(` ${chalk16.magenta(`\uD83D\uDCCE ${att.type}`)} ${att.fileName ?? ""} ${chalk16.dim(att.mimeType ?? "")}`);
|
|
5663
|
+
console.log(` ${chalk16.dim(` url: ${att.url?.slice(0, 120)}`)}`);
|
|
5664
|
+
if (att.attachmentId)
|
|
5665
|
+
console.log(` ${chalk16.dim(` attachmentId: ${att.attachmentId}`)}`);
|
|
5666
|
+
}
|
|
5667
|
+
}
|
|
5668
|
+
if (channelData && typeof channelData === "object") {
|
|
5669
|
+
const cdType = channelData.type;
|
|
5670
|
+
const mediaStorageId = channelData.mediaStorageId;
|
|
5671
|
+
const mediaDirectUrl = channelData.mediaDirectUrl;
|
|
5672
|
+
if (cdType && cdType !== "text") {
|
|
5673
|
+
console.log(` ${chalk16.dim(` channel: ${cdType}${mediaStorageId ? ` storageId:${mediaStorageId}` : ""}${mediaDirectUrl ? ` directUrl:${String(mediaDirectUrl).slice(0, 80)}` : ""}`)}`);
|
|
5674
|
+
}
|
|
5675
|
+
}
|
|
5566
5676
|
} else if (role === "assistant" && toolCalls?.length) {
|
|
5567
5677
|
console.log();
|
|
5568
5678
|
console.log(` ${chalk16.gray(`[${ts}]`)} ${chalk16.green("Agent")}`);
|
|
@@ -5570,57 +5680,44 @@ logsCommand.command("view <thread-id>").description("View conversation messages"
|
|
|
5570
5680
|
console.log(` ${content}`);
|
|
5571
5681
|
for (const call of toolCalls) {
|
|
5572
5682
|
console.log(` ${chalk16.yellow("Tool: " + call.name)}`);
|
|
5573
|
-
console.log(` ${chalk16.dim("\u2192 " + JSON.stringify(call.arguments).slice(0,
|
|
5683
|
+
console.log(` ${chalk16.dim("\u2192 " + JSON.stringify(call.arguments).slice(0, truncLen))}`);
|
|
5574
5684
|
}
|
|
5575
5685
|
} else if (role === "assistant") {
|
|
5576
5686
|
console.log();
|
|
5577
5687
|
console.log(` ${chalk16.gray(`[${ts}]`)} ${chalk16.green("Agent")}`);
|
|
5578
5688
|
console.log(` ${content}`);
|
|
5579
5689
|
} else if (role === "tool") {
|
|
5580
|
-
console.log(` ${chalk16.dim("\u2190 " + content.slice(0,
|
|
5690
|
+
console.log(` ${chalk16.dim("\u2190 " + content.slice(0, truncLen))}`);
|
|
5581
5691
|
} else if (role === "system") {
|
|
5582
5692
|
console.log();
|
|
5583
5693
|
console.log(` ${chalk16.dim("[System] " + content.slice(0, 100))}`);
|
|
5584
5694
|
}
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
}
|
|
5595
|
-
spinner.succeed("Executions loaded");
|
|
5596
|
-
const executions = execResult.data;
|
|
5597
|
-
console.log();
|
|
5598
|
-
console.log(chalk16.bold("Executions"));
|
|
5599
|
-
console.log(chalk16.gray("\u2500".repeat(60)));
|
|
5600
|
-
for (const exec of executions) {
|
|
5601
|
-
const status = exec.status;
|
|
5602
|
-
const statusColor = status === "success" ? chalk16.green : status === "error" ? chalk16.red : chalk16.yellow;
|
|
5603
|
-
const toolCallDetails = exec.toolCallDetails;
|
|
5604
|
-
console.log();
|
|
5605
|
-
console.log(` ${chalk16.gray("Status:")} ${statusColor(status)}`);
|
|
5606
|
-
if (exec.model)
|
|
5607
|
-
console.log(` ${chalk16.gray("Model:")} ${exec.model}`);
|
|
5608
|
-
if (exec.inputTokens || exec.outputTokens)
|
|
5609
|
-
console.log(` ${chalk16.gray("Tokens:")} ${exec.inputTokens ?? 0} in / ${exec.outputTokens ?? 0} out`);
|
|
5610
|
-
if (exec.durationMs)
|
|
5611
|
-
console.log(` ${chalk16.gray("Duration:")} ${exec.durationMs}ms`);
|
|
5612
|
-
if (toolCallDetails?.length) {
|
|
5613
|
-
console.log(` ${chalk16.gray("Tools:")} ${toolCallDetails.length} calls`);
|
|
5614
|
-
for (const tc of toolCallDetails) {
|
|
5615
|
-
console.log(` ${tc.name} (${tc.durationMs}ms) -> ${tc.status}`);
|
|
5695
|
+
if (opts.exec && role === "assistant" && toolCalls?.length) {
|
|
5696
|
+
let closestExec;
|
|
5697
|
+
let closestDiff = Infinity;
|
|
5698
|
+
for (const exec of executions) {
|
|
5699
|
+
const execTs = exec.createdAt ?? exec._creationTime ?? 0;
|
|
5700
|
+
const diff = Math.abs(execTs - msgTs);
|
|
5701
|
+
if (diff < closestDiff) {
|
|
5702
|
+
closestDiff = diff;
|
|
5703
|
+
closestExec = exec;
|
|
5616
5704
|
}
|
|
5617
5705
|
}
|
|
5618
|
-
if (
|
|
5619
|
-
|
|
5706
|
+
if (closestExec && closestDiff < 30000) {
|
|
5707
|
+
const status = closestExec.status;
|
|
5708
|
+
const statusColor = status === "success" ? chalk16.green : status === "error" ? chalk16.red : chalk16.yellow;
|
|
5709
|
+
const model = closestExec.model;
|
|
5710
|
+
const duration = closestExec.durationMs;
|
|
5711
|
+
const inputTokens = closestExec.inputTokens;
|
|
5712
|
+
const outputTokens = closestExec.outputTokens;
|
|
5713
|
+
console.log(` ${chalk16.dim(` exec: ${statusColor(status)} ${model ?? ""} ${inputTokens ?? 0}in/${outputTokens ?? 0}out ${duration ?? 0}ms`)}`);
|
|
5714
|
+
if (closestExec.errorMessage) {
|
|
5715
|
+
console.log(` ${chalk16.red(` error: ${closestExec.errorMessage}`)}`);
|
|
5716
|
+
}
|
|
5620
5717
|
}
|
|
5621
5718
|
}
|
|
5622
|
-
console.log();
|
|
5623
5719
|
}
|
|
5720
|
+
console.log();
|
|
5624
5721
|
});
|
|
5625
5722
|
|
|
5626
5723
|
// src/cli/commands/eval.ts
|
|
@@ -6978,6 +7075,34 @@ async function listTriggerExecutions(options) {
|
|
|
6978
7075
|
async function getTriggerExecutionDetail(eventId) {
|
|
6979
7076
|
return convexQuery6("triggers:getExecutionDetail", { eventId });
|
|
6980
7077
|
}
|
|
7078
|
+
async function convexAction3(path, args) {
|
|
7079
|
+
const token = getToken6();
|
|
7080
|
+
const response = await fetch(`${CONVEX_URL}/api/action`, {
|
|
7081
|
+
method: "POST",
|
|
7082
|
+
headers: {
|
|
7083
|
+
"Content-Type": "application/json",
|
|
7084
|
+
Authorization: `Bearer ${token}`
|
|
7085
|
+
},
|
|
7086
|
+
body: JSON.stringify({ path, args })
|
|
7087
|
+
});
|
|
7088
|
+
const text = await response.text();
|
|
7089
|
+
let json;
|
|
7090
|
+
try {
|
|
7091
|
+
json = JSON.parse(text);
|
|
7092
|
+
} catch {
|
|
7093
|
+
throw new Error(text || `HTTP ${response.status}`);
|
|
7094
|
+
}
|
|
7095
|
+
if (!response.ok) {
|
|
7096
|
+
throw new Error(json.errorData?.message || json.errorMessage || text);
|
|
7097
|
+
}
|
|
7098
|
+
if (json.status === "error") {
|
|
7099
|
+
throw new Error(json.errorMessage || "Unknown error from Convex");
|
|
7100
|
+
}
|
|
7101
|
+
return json.value;
|
|
7102
|
+
}
|
|
7103
|
+
async function retryImmediateExecution(eventId, environment) {
|
|
7104
|
+
return convexAction3("triggers:retryImmediateExecution", { eventId, environment });
|
|
7105
|
+
}
|
|
6981
7106
|
|
|
6982
7107
|
// src/cli/commands/triggers.ts
|
|
6983
7108
|
async function ensureAuth5() {
|
|
@@ -7623,6 +7748,41 @@ triggersCommand.command("disable <slug>").description("Disable a trigger").optio
|
|
|
7623
7748
|
process.exit(1);
|
|
7624
7749
|
}
|
|
7625
7750
|
});
|
|
7751
|
+
triggersCommand.command("retry-event <event-id>").description("Retry a failed immediate trigger execution").option("--env <environment>", "Environment (development|production|eval)", "development").option("--json", "Output raw JSON").option("--confirm", "Skip production confirmation").action(async (eventId, opts) => {
|
|
7752
|
+
await ensureAuth5();
|
|
7753
|
+
const spinner = ora14();
|
|
7754
|
+
const environment = opts.env;
|
|
7755
|
+
if (environment === "production" && !opts.confirm && isInteractive()) {
|
|
7756
|
+
const readline = await import("readline");
|
|
7757
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
7758
|
+
await new Promise((resolve) => {
|
|
7759
|
+
rl.question(chalk20.yellow(`WARNING: Retrying execution in PRODUCTION environment.
|
|
7760
|
+
Press Enter to continue or Ctrl+C to cancel: `), resolve);
|
|
7761
|
+
});
|
|
7762
|
+
rl.close();
|
|
7763
|
+
}
|
|
7764
|
+
try {
|
|
7765
|
+
spinner.start("Retrying failed execution...");
|
|
7766
|
+
const result = await retryImmediateExecution(eventId, environment);
|
|
7767
|
+
if (result.success) {
|
|
7768
|
+
spinner.succeed(chalk20.green(`Execution retried successfully`));
|
|
7769
|
+
} else {
|
|
7770
|
+
spinner.fail(chalk20.red(`Execution retry failed again`));
|
|
7771
|
+
}
|
|
7772
|
+
if (opts.json) {
|
|
7773
|
+
console.log(JSON.stringify(result));
|
|
7774
|
+
}
|
|
7775
|
+
} catch (err) {
|
|
7776
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
7777
|
+
spinner.fail("Failed to retry execution");
|
|
7778
|
+
if (opts.json) {
|
|
7779
|
+
console.log(JSON.stringify({ success: false, error: message }));
|
|
7780
|
+
} else {
|
|
7781
|
+
console.log(chalk20.red("Error:"), message);
|
|
7782
|
+
}
|
|
7783
|
+
process.exit(1);
|
|
7784
|
+
}
|
|
7785
|
+
});
|
|
7626
7786
|
|
|
7627
7787
|
// src/cli/commands/compile-prompt.ts
|
|
7628
7788
|
import { Command as Command19 } from "commander";
|
|
@@ -8182,7 +8342,7 @@ var chatCommand = new Command21("chat").description("Chat with an agent").argume
|
|
|
8182
8342
|
// package.json
|
|
8183
8343
|
var package_default = {
|
|
8184
8344
|
name: "struere",
|
|
8185
|
-
version: "0.
|
|
8345
|
+
version: "0.12.0",
|
|
8186
8346
|
description: "Build, test, and deploy AI agents",
|
|
8187
8347
|
keywords: [
|
|
8188
8348
|
"ai",
|
|
@@ -17,6 +17,7 @@ export interface Credentials {
|
|
|
17
17
|
}
|
|
18
18
|
export declare function saveCredentials(credentials: Credentials): void;
|
|
19
19
|
export declare function loadCredentials(): Credentials | null;
|
|
20
|
+
export declare function isTokenExpired(): boolean;
|
|
20
21
|
export declare function clearCredentials(): void;
|
|
21
22
|
export declare function getApiKey(): string | null;
|
|
22
23
|
//# sourceMappingURL=credentials.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/credentials.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAA;QACV,KAAK,EAAE,MAAM,CAAA;QACb,IAAI,EAAE,MAAM,CAAA;QACZ,cAAc,CAAC,EAAE,MAAM,CAAA;KACxB,CAAA;IACD,YAAY,CAAC,EAAE;QACb,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;IACD,SAAS,EAAE,MAAM,CAAA;CAClB;AAWD,wBAAgB,eAAe,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,CAG9D;AAED,wBAAgB,eAAe,IAAI,WAAW,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/credentials.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAA;QACV,KAAK,EAAE,MAAM,CAAA;QACb,IAAI,EAAE,MAAM,CAAA;QACZ,cAAc,CAAC,EAAE,MAAM,CAAA;KACxB,CAAA;IACD,YAAY,CAAC,EAAE;QACb,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;IACD,SAAS,EAAE,MAAM,CAAA;CAClB;AAWD,wBAAgB,eAAe,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,CAG9D;AAED,wBAAgB,eAAe,IAAI,WAAW,GAAG,IAAI,CAWpD;AAED,wBAAgB,cAAc,IAAI,OAAO,CAIxC;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAIvC;AAED,wBAAgB,SAAS,IAAI,MAAM,GAAG,IAAI,CAMzC"}
|
package/dist/cli/utils/logs.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export declare function queryThreads(options: {
|
|
|
2
2
|
environment: string;
|
|
3
3
|
agentId?: string;
|
|
4
4
|
channel?: string;
|
|
5
|
+
phone?: string;
|
|
5
6
|
limit?: number;
|
|
6
7
|
}): Promise<{
|
|
7
8
|
data?: unknown;
|
|
@@ -15,6 +16,10 @@ export declare function queryThreadExecutions(threadId: string): Promise<{
|
|
|
15
16
|
data?: unknown;
|
|
16
17
|
error?: string;
|
|
17
18
|
}>;
|
|
19
|
+
export declare function resolveThreadId(shortId: string, environment?: string): Promise<{
|
|
20
|
+
data?: string;
|
|
21
|
+
error?: string;
|
|
22
|
+
}>;
|
|
18
23
|
export declare function resolveAgentSlug(slug: string, organizationId?: string): Promise<{
|
|
19
24
|
data?: string;
|
|
20
25
|
error?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/logs.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/logs.ts"],"names":[],"mappings":"AAqEA,wBAAsB,YAAY,CAAC,OAAO,EAAE;IAC1C,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,GAAG,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAsB9C;AAED,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAK5H;AAED,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAEzG;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAqBvH;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAMxH"}
|
|
@@ -104,5 +104,8 @@ export declare function listTriggerExecutions(options: {
|
|
|
104
104
|
limit?: number;
|
|
105
105
|
}): Promise<TriggerExecution[]>;
|
|
106
106
|
export declare function getTriggerExecutionDetail(eventId: string): Promise<TriggerExecution | null>;
|
|
107
|
+
export declare function retryImmediateExecution(eventId: string, environment: Environment): Promise<{
|
|
108
|
+
success: boolean;
|
|
109
|
+
}>;
|
|
107
110
|
export {};
|
|
108
111
|
//# sourceMappingURL=triggers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"triggers.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/triggers.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"triggers.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/triggers.ts"],"names":[],"mappings":"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"}
|