@standardagents/builder 0.22.1 → 0.23.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.
Files changed (33) hide show
  1. package/dist/built-in-routes.js +136 -43
  2. package/dist/built-in-routes.js.map +1 -1
  3. package/dist/client/{ApiKeysView-N0JkbRqs.js → ApiKeysView-1m7uIS8S.js} +1 -1
  4. package/dist/client/{CenteredContentView-DTm87Sif.js → CenteredContentView-DJzHRMGj.js} +1 -1
  5. package/dist/client/{CompositionView-DnSaz1Nk.js → CompositionView-nzqzVKAg.js} +1 -1
  6. package/dist/client/{ConfirmDialog.vue_vue_type_script_setup_true_lang-DgfpzkTb.js → ConfirmDialog.vue_vue_type_script_setup_true_lang-YX8WE_iB.js} +1 -1
  7. package/dist/client/{CopyButton.vue_vue_type_script_setup_true_lang-DaO8fv5n.js → CopyButton.vue_vue_type_script_setup_true_lang-BpJt6BT0.js} +1 -1
  8. package/dist/client/{DataTable.vue_vue_type_script_setup_true_lang-CXfKtM8R.js → DataTable.vue_vue_type_script_setup_true_lang-Dg3HMMJ0.js} +1 -1
  9. package/dist/client/{JsonViewer-dnp9s6ji.js → JsonViewer-BdNA5OCG.js} +1 -1
  10. package/dist/client/{LoginView-C4vODzeq.js → LoginView-BlF_2TtB.js} +1 -1
  11. package/dist/client/{MarketplaceView-D4QuJAyk.js → MarketplaceView-DrlOb57k.js} +1 -1
  12. package/dist/client/{Modal.vue_vue_type_script_setup_true_lang-DbzeQ2-L.js → Modal.vue_vue_type_script_setup_true_lang-hkOmEwrb.js} +1 -1
  13. package/dist/client/{ModelModal.vue_vue_type_script_setup_true_lang-CNIgneiU.js → ModelModal.vue_vue_type_script_setup_true_lang-p3esoV-i.js} +1 -1
  14. package/dist/client/{ModelsView-CYQm6yLC.js → ModelsView-CHBanMSH.js} +1 -1
  15. package/dist/client/{PromptEditView-BAJoqY8N.js → PromptEditView-b5B43l4Q.js} +1 -1
  16. package/dist/client/{PromptModal-CFd4gHai.js → PromptModal-BF5bdmNQ.js} +1 -1
  17. package/dist/client/{PromptsView-DDapP7U-.js → PromptsView-6TfMOScI.js} +1 -1
  18. package/dist/client/{ProvidersView-D2g5wSI1.js → ProvidersView-CA5Yx2Fn.js} +1 -1
  19. package/dist/client/{ThreadInspectorPane.vue_vue_type_script_setup_true_lang-Cyvuox_G.js → ThreadInspectorPane.vue_vue_type_script_setup_true_lang-ejyFhmNy.js} +15 -15
  20. package/dist/client/{ThreadsView-Dc3lr6Au.js → ThreadsView-yJpVmf42.js} +1 -1
  21. package/dist/client/{ToolsView-C-marn6m.js → ToolsView-DE1TDnlU.js} +1 -1
  22. package/dist/client/{UsersView-D4j8izbK.js → UsersView-BXDHjJLB.js} +1 -1
  23. package/dist/client/{VariablesView-d3lOE_O2.js → VariablesView-Bz-CbaEv.js} +1 -1
  24. package/dist/client/assets/index-V68N0r_5.css +1 -0
  25. package/dist/client/{index-DR9DbKrm.js → index-TIntu1KJ.js} +2 -2
  26. package/dist/client/index.html +2 -2
  27. package/dist/index.js +66 -3
  28. package/dist/index.js.map +1 -1
  29. package/dist/runtime.d.ts +29 -0
  30. package/dist/runtime.js +66 -3
  31. package/dist/runtime.js.map +1 -1
  32. package/package.json +5 -5
  33. package/dist/client/assets/index-_JaOWezk.css +0 -1
@@ -5755,7 +5755,7 @@ ${attachmentPaths}`;
5755
5755
  const attachmentId = crypto.randomUUID();
5756
5756
  const timestamp = Date.now();
5757
5757
  const ext = attachment.mimeType === "image/png" ? "png" : attachment.mimeType === "image/jpeg" ? "jpg" : attachment.mimeType === "image/gif" ? "gif" : attachment.mimeType === "image/webp" ? "webp" : attachment.name.split(".").pop() || "bin";
5758
- const path9 = `/attachments/${timestamp}-${attachmentId}.${ext}`;
5758
+ const path9 = `/attachments/${timestamp}-${attachmentId.slice(0, 8)}.${ext}`;
5759
5759
  const binaryString = atob(attachment.data);
5760
5760
  const dataBuffer = new Uint8Array(binaryString.length);
5761
5761
  for (let i = 0; i < binaryString.length; i++) {
@@ -9342,7 +9342,7 @@ ${lines.join("\n\n")}`
9342
9342
  const base64Data = match2[2];
9343
9343
  const ext = mimeType.split("/")[1] || "png";
9344
9344
  const attachmentId = crypto.randomUUID();
9345
- const path9 = `/attachments/${Date.now()}-${attachmentId}.${ext}`;
9345
+ const path9 = `/attachments/${Date.now()}-${attachmentId.slice(0, 8)}.${ext}`;
9346
9346
  try {
9347
9347
  await state.thread.instance.writeFile(path9, base64Data, mimeType);
9348
9348
  if (image.id) {
@@ -9412,7 +9412,7 @@ ${lines.join("\n\n")}`
9412
9412
  const base64Data = imageUrl.slice(base64Index + base64Marker.length);
9413
9413
  const ext = mimeType.split("/")[1] || "png";
9414
9414
  const attachmentId = crypto.randomUUID();
9415
- const path9 = `/attachments/${Date.now()}-${attachmentId}.${ext}`;
9415
+ const path9 = `/attachments/${Date.now()}-${attachmentId.slice(0, 8)}.${ext}`;
9416
9416
  try {
9417
9417
  await state.thread.instance.writeFile(path9, base64Data, mimeType);
9418
9418
  const attachmentRef = {
@@ -69077,7 +69077,54 @@ var continue_post_default = defineController2(async ({ req, params, env: env2 })
69077
69077
  }
69078
69078
  });
69079
69079
 
69080
+ // src/agents/cost-summary.ts
69081
+ function emptyCostSummary() {
69082
+ return { totalCost: 0, requestCount: 0, messageCount: 0, byModel: {} };
69083
+ }
69084
+ function mergeByModel(summaries) {
69085
+ const merged = {};
69086
+ for (const summary of summaries) {
69087
+ for (const [modelName, acc] of Object.entries(summary.byModel)) {
69088
+ const entry = merged[modelName] ?? { totalCost: 0, count: 0 };
69089
+ entry.totalCost += acc.totalCost;
69090
+ entry.count += acc.count;
69091
+ merged[modelName] = entry;
69092
+ }
69093
+ }
69094
+ return merged;
69095
+ }
69096
+ function sumSummaries(summaries) {
69097
+ let totalCost = 0;
69098
+ let requestCount = 0;
69099
+ let messageCount = 0;
69100
+ for (const summary of summaries) {
69101
+ totalCost += summary.totalCost;
69102
+ requestCount += summary.requestCount;
69103
+ messageCount += summary.messageCount;
69104
+ }
69105
+ return { totalCost, requestCount, messageCount };
69106
+ }
69107
+ function buildModelBreakdown(byModel) {
69108
+ return Object.entries(byModel).map(([modelName, acc]) => ({
69109
+ modelName,
69110
+ totalCost: acc.totalCost,
69111
+ requestCount: acc.count,
69112
+ avgCostPerRequest: acc.count > 0 ? acc.totalCost / acc.count : 0
69113
+ })).sort((a, b) => b.totalCost - a.totalCost);
69114
+ }
69115
+ function threadNameFromTags(tags) {
69116
+ for (const tag of tags ?? []) {
69117
+ if (typeof tag === "string" && tag.startsWith("name:")) {
69118
+ const value = tag.slice("name:".length).trim();
69119
+ if (value) return value;
69120
+ }
69121
+ }
69122
+ return null;
69123
+ }
69124
+
69080
69125
  // src/api/threads/[id]/cost.get.ts
69126
+ var MAX_DESCENDANTS = 200;
69127
+ var SUMMARY_BATCH = 10;
69081
69128
  var cost_get_default = defineController2(async ({ req, params, env: env2 }) => {
69082
69129
  const threadId = params.id;
69083
69130
  if (!threadId) {
@@ -69093,52 +69140,70 @@ var cost_get_default = defineController2(async ({ req, params, env: env2 }) => {
69093
69140
  { status: 404 }
69094
69141
  );
69095
69142
  }
69096
- const durableId = env2.AGENT_BUILDER_THREAD.idFromName(threadId);
69097
- const stub = env2.AGENT_BUILDER_THREAD.get(durableId);
69098
- const logsResult = await stub.getLogs(1e4, 0, "ASC");
69099
- const logs = logsResult.logs || [];
69100
- let totalCost = 0;
69101
- const modelCosts = {};
69102
- const uniqueMessages = /* @__PURE__ */ new Set();
69103
- for (const log of logs) {
69104
- const cost = log.cost_total;
69105
- if (cost !== null && cost !== void 0 && !isNaN(cost)) {
69106
- totalCost += cost;
69107
- if (log.message_id) {
69108
- uniqueMessages.add(log.message_id);
69109
- }
69110
- const modelKey = log.model_name || log.model || "unknown";
69111
- if (!modelCosts[modelKey]) {
69112
- modelCosts[modelKey] = {
69113
- totalCost: 0,
69114
- count: 0
69115
- };
69116
- }
69117
- modelCosts[modelKey].totalCost += cost;
69118
- modelCosts[modelKey].count += 1;
69143
+ const descendants = (await agentBuilder.getDescendantThreads(threadId) ?? []).slice(
69144
+ 0,
69145
+ MAX_DESCENDANTS + 1
69146
+ );
69147
+ const truncated = descendants.length > MAX_DESCENDANTS;
69148
+ if (truncated) descendants.length = MAX_DESCENDANTS;
69149
+ const summarize = async (id) => {
69150
+ try {
69151
+ const durableId = env2.AGENT_BUILDER_THREAD.idFromName(id);
69152
+ const stub = env2.AGENT_BUILDER_THREAD.get(durableId);
69153
+ return await stub.getCostSummary() ?? emptyCostSummary();
69154
+ } catch {
69155
+ return emptyCostSummary();
69119
69156
  }
69157
+ };
69158
+ const ownSummary = await summarize(threadId);
69159
+ const descendantSummaries = [];
69160
+ for (let i = 0; i < descendants.length; i += SUMMARY_BATCH) {
69161
+ const batch = descendants.slice(i, i + SUMMARY_BATCH);
69162
+ descendantSummaries.push(
69163
+ ...await Promise.all(batch.map((child) => summarize(child.id)))
69164
+ );
69120
69165
  }
69121
- const messageCount = uniqueMessages.size;
69122
- const avgCostPerMessage = messageCount > 0 ? totalCost / messageCount : 0;
69166
+ const allSummaries = [ownSummary, ...descendantSummaries];
69167
+ const totals = sumSummaries(allSummaries);
69168
+ const byModel = mergeByModel(allSummaries);
69169
+ const modelBreakdown = buildModelBreakdown(byModel);
69123
69170
  const avgCostPerMessageByModel = {};
69124
- for (const [modelName, data] of Object.entries(modelCosts)) {
69125
- avgCostPerMessageByModel[modelName] = {
69126
- avgCost: data.count > 0 ? data.totalCost / data.count : 0,
69127
- messageCount: data.count
69171
+ for (const entry of modelBreakdown) {
69172
+ avgCostPerMessageByModel[entry.modelName] = {
69173
+ avgCost: entry.avgCostPerRequest,
69174
+ messageCount: entry.requestCount
69128
69175
  };
69129
69176
  }
69130
- const modelBreakdown = Object.entries(modelCosts).map(([modelName, data]) => ({
69131
- modelName,
69132
- totalCost: data.totalCost,
69133
- requestCount: data.count,
69134
- avgCostPerRequest: data.count > 0 ? data.totalCost / data.count : 0
69135
- }));
69177
+ const threads = [
69178
+ {
69179
+ threadId,
69180
+ agentName: thread.agent_name ?? null,
69181
+ threadName: threadNameFromTags(thread.tags),
69182
+ parent: null,
69183
+ isRoot: true,
69184
+ totalCost: ownSummary.totalCost,
69185
+ requestCount: ownSummary.requestCount
69186
+ },
69187
+ ...descendants.map((child, index) => ({
69188
+ threadId: child.id,
69189
+ agentName: child.agent_name ?? null,
69190
+ threadName: threadNameFromTags(child.tags),
69191
+ parent: child.parent,
69192
+ isRoot: false,
69193
+ totalCost: descendantSummaries[index]?.totalCost ?? 0,
69194
+ requestCount: descendantSummaries[index]?.requestCount ?? 0
69195
+ })).filter((row) => row.requestCount > 0)
69196
+ ];
69136
69197
  return Response.json({
69137
- totalCost,
69138
- messageCount,
69139
- avgCostPerMessage,
69198
+ totalCost: totals.totalCost,
69199
+ ownCost: ownSummary.totalCost,
69200
+ requestCount: totals.requestCount,
69201
+ messageCount: totals.messageCount,
69202
+ avgCostPerMessage: totals.messageCount > 0 ? totals.totalCost / totals.messageCount : 0,
69140
69203
  modelBreakdown,
69141
- avgCostPerMessageByModel
69204
+ avgCostPerMessageByModel,
69205
+ threads,
69206
+ truncated
69142
69207
  });
69143
69208
  } catch (error) {
69144
69209
  console.error(`Error calculating cost for thread ${threadId}:`, error);
@@ -69604,7 +69669,7 @@ var messages_post_default = defineController2(async ({ req, params, env: env2 })
69604
69669
  }
69605
69670
  }
69606
69671
  const ext = mimeType === "image/png" ? "png" : mimeType === "image/jpeg" ? "jpg" : attachment.name.split(".").pop() || "bin";
69607
- const path9 = `/attachments/${timestamp}-${attachmentId}.${ext}`;
69672
+ const path9 = `/attachments/${timestamp}-${attachmentId.slice(0, 8)}.${ext}`;
69608
69673
  const base64Size = fileData.length;
69609
69674
  const binarySize = Math.ceil(base64Size * 3 / 4);
69610
69675
  console.log(`[writeFile] Storing ${attachment.name}: ${(binarySize / 1024 / 1024).toFixed(2)}MB binary (${(base64Size / 1024 / 1024).toFixed(2)}MB base64) to ${path9}`);
@@ -70639,6 +70704,20 @@ async function handleChunkedUploadComplete(stub, filePath, req) {
70639
70704
 
70640
70705
  // src/api/threads/[id]/logs/[logId].get.ts
70641
70706
  var logId_get_default = defineController2(async ({ req, params, env: env2 }) => {
70707
+ if (isPlatformHosted(env2)) {
70708
+ const authResult = await requirePermission(req, env2, "logs");
70709
+ if (authResult instanceof Response) {
70710
+ return authResult;
70711
+ }
70712
+ } else {
70713
+ const authContext = await authenticate(req, env2);
70714
+ if (authContext && !hasPermission(authContext.user, "logs")) {
70715
+ return Response.json(
70716
+ { error: "Forbidden: 'logs' access required" },
70717
+ { status: 403 }
70718
+ );
70719
+ }
70720
+ }
70642
70721
  const threadId = params.id;
70643
70722
  const logId = params.logId;
70644
70723
  if (!threadId) {
@@ -71054,6 +71133,20 @@ function createInspectProviderConfig(providerName, factory, env2) {
71054
71133
  };
71055
71134
  }
71056
71135
  var provider_get_default = defineController2(async ({ req, params, env: env2 }) => {
71136
+ if (isPlatformHosted(env2)) {
71137
+ const authResult = await requirePermission(req, env2, "logs");
71138
+ if (authResult instanceof Response) {
71139
+ return authResult;
71140
+ }
71141
+ } else {
71142
+ const authContext = await authenticate(req, env2);
71143
+ if (authContext && !hasPermission(authContext.user, "logs")) {
71144
+ return Response.json(
71145
+ { error: "Forbidden: 'logs' access required" },
71146
+ { status: 403 }
71147
+ );
71148
+ }
71149
+ }
71057
71150
  const threadId = params.id;
71058
71151
  const logId = params.logId;
71059
71152
  const providerName = params.provider;