@standardagents/builder 0.30.2 → 0.32.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/built-in-routes.js +45 -3
- package/dist/built-in-routes.js.map +1 -1
- package/dist/client/{ApiKeysView-jhfg43UH.js → ApiKeysView-CxNw8yvZ.js} +1 -1
- package/dist/client/CenteredContentView-D4G91Thq.js +1 -0
- package/dist/client/{CompositionView-DhkLWmtE.js → CompositionView-BaWfyUW6.js} +1 -1
- package/dist/client/{ConfirmDialog.vue_vue_type_script_setup_true_lang-D-WToRMy.js → ConfirmDialog.vue_vue_type_script_setup_true_lang-CVzMoEOi.js} +1 -1
- package/dist/client/{CopyButton.vue_vue_type_script_setup_true_lang-Dhq0t0dd.js → CopyButton.vue_vue_type_script_setup_true_lang-Cz_ZrOAS.js} +1 -1
- package/dist/client/{DataTable.vue_vue_type_script_setup_true_lang-D1MDCns-.js → DataTable.vue_vue_type_script_setup_true_lang-CQwcIXyb.js} +1 -1
- package/dist/client/{JsonViewer-BoHrE76S.js → JsonViewer-Dsl-e2IH.js} +1 -1
- package/dist/client/{LoginView-BpR2nMNf.js → LoginView-CX0lmKUS.js} +1 -1
- package/dist/client/{MarketplaceView-uUf1JYla.js → MarketplaceView-BJAG7kej.js} +1 -1
- package/dist/client/{Modal.vue_vue_type_script_setup_true_lang-D-SDVFQI.js → Modal.vue_vue_type_script_setup_true_lang-B2Yd_pvh.js} +1 -1
- package/dist/client/{ModelModal.vue_vue_type_script_setup_true_lang-DE57Zr0r.js → ModelModal.vue_vue_type_script_setup_true_lang-CCH8VxwI.js} +1 -1
- package/dist/client/{ModelsView-CuM_OieH.js → ModelsView-CGgNBkY-.js} +1 -1
- package/dist/client/{PromptEditView-BWjrA2zr.js → PromptEditView-CL2LEH80.js} +1 -1
- package/dist/client/{PromptModal-BFxhuG0Z.js → PromptModal-DHHy53-v.js} +1 -1
- package/dist/client/{PromptsView-AlGsRB6k.js → PromptsView-BcTfvJdH.js} +1 -1
- package/dist/client/{ProvidersView-CbXBs3SH.js → ProvidersView-B2yy_Kbe.js} +1 -1
- package/dist/client/ThreadInspectorPane.vue_vue_type_script_setup_true_lang-BCiZyZu-.js +22 -0
- package/dist/client/{ThreadsView-rN9rzJi1.js → ThreadsView-BKSAJipV.js} +1 -1
- package/dist/client/{ToolsView-0Gpo_RFg.js → ToolsView-DBkare-6.js} +1 -1
- package/dist/client/{UiCodeBlock.vue_vue_type_script_setup_true_lang-CNncALQo.js → UiCodeBlock.vue_vue_type_script_setup_true_lang-QytRm7Ql.js} +1 -1
- package/dist/client/{UsersView-iXPbcguY.js → UsersView-yBnliXIU.js} +1 -1
- package/dist/client/{VariablesView-C9BB9h34.js → VariablesView-N-VgGqPg.js} +1 -1
- package/dist/client/assets/ThreadInspectorPane-DSQsKyG6.css +1 -0
- package/dist/client/assets/index-C4KCxdCv.css +1 -0
- package/dist/client/{check-BdJVlUmI.js → check-pGlck8qX.js} +1 -1
- package/dist/client/{chevron-right-D49O3XLU.js → chevron-right-FpPE1Obh.js} +1 -1
- package/dist/client/{copy-40uDyTgY.js → copy-Dt1FLh3s.js} +1 -1
- package/dist/client/{formkit-Bl-sERnF.js → formkit-DcZQH9-p.js} +1 -1
- package/dist/client/{index-BCoE48be.js → index-DANZMMwO.js} +3 -3
- package/dist/client/index.html +4 -4
- package/dist/client/{package-1UgoERpx.js → package-DSNwOrcN.js} +1 -1
- package/dist/client/{plus-BzCjfYs0.js → plus-D0GkkdA7.js} +1 -1
- package/dist/client/{timeAgo-cFwldMu-.js → timeAgo-X3Xeq5Kz.js} +1 -1
- package/dist/client/{useActionFeedback-BVifffYQ.js → useActionFeedback-Dxh_Xp0q.js} +1 -1
- package/dist/client/vue-KXHVRwln.js +1 -0
- package/dist/{index-CcnGEkPh.d.ts → index-1AMgutkG.d.ts} +27 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +203 -16
- package/dist/index.js.map +1 -1
- package/dist/plugin.js +6 -0
- package/dist/plugin.js.map +1 -1
- package/dist/runtime.d.ts +48 -2
- package/dist/runtime.js +197 -16
- package/dist/runtime.js.map +1 -1
- package/dist/test.d.ts +1 -1
- package/package.json +5 -5
- package/dist/client/CenteredContentView-CS0mV2EJ.js +0 -1
- package/dist/client/ThreadInspectorPane.vue_vue_type_script_setup_true_lang-Dm3d37hz.js +0 -22
- package/dist/client/assets/ThreadInspectorPane-CfpdDnUQ.css +0 -1
- package/dist/client/assets/index-BTPsPULO.css +0 -1
- package/dist/client/vue-CmmJuziT.js +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ModelDefinition, AgentDefinition } from './runtime.js';
|
|
2
2
|
export { AgentBuilderEnv, AuthContext, AuthUser, BroadcastOptions, CodeExecutionBridge, DurableAgentBuilder, DurableThread, DurableUserHub, FlowStateSdk, FlowStateWithSdk, HubClientInfo, ImageContextConfig, InjectMessageOptions, LLMProviderInterface, NamespaceResolutionError, PromptContent, PromptDefinition, PromptIncludePart, PromptPart, PromptToolConfig, Provider, ProviderContentPart, ProviderFilePart, ProviderImagePart, ProviderRegistry, ProviderTextPart, SessionToolBinding, SessionToolConfig, SideConfig, SubagentToolConfig, SubpromptConfig, ThreadRegistryEntry, ThreadWatchdog, ThreadWatchdogState, ToolConfig, UpdateThreadParams, User, WatchdogCheckin, WatchdogProbeResult, authenticate, buildImageDescription, cat, createNamespaceContext, emitThreadEvent, enhanceFlowState, exists, find, forceTurn, generateImageDescription, getFileStats, getMessages, getMessagesToSummarize, getShortName, getThumbnail, getUnsummarizedImageAttachments, getVisibleAgentNames, getVisibleModelNames, getVisiblePromptNames, getVisibleToolNames, grep, hasImageAttachments, head, injectMessage, isQualifiedName, linkFile, mkdir, move, optimizeImageContext, parseQualifiedName, qualifyName, queueTool, readFile, readdir, reloadHistory, rename, replaceImagesWithDescriptions, requireAdmin, requireAuth, resolveAgent, resolveHook, resolveModel, resolvePrompt, resolveTool, rmdir, stat, tail, unlink, updateThread, writeFile, writeImage } from './runtime.js';
|
|
3
3
|
export { AgentPluginOptions, agentbuilder, builder } from './plugin.js';
|
|
4
|
-
export { A as Agent, x as AttachmentRef, f as BuilderThreadEndpointHandler, C as CLIENT_STREAM_CHUNK_BYTES, o as ClientDuplex, p as ClientForwarding, m as ClientStreamRequest, n as ClientStreamResponse, k as ClientToolRequest, l as ClientToolResponse, B as Controller, a as ControllerContext, E as Env, w as FileRecord, y as FileStats, u as FlowResult, F as FlowState, G as GrepResult, D as ImageContentPart, I as ImageMetadata, L as LLMResponse, M as Message, J as MessageContent, H as MultimodalContent, R as RequestContext, S as StorageBackend, v as TelemetryEvent, z as TextContentPart, b as ThreadEndpointContext, e as ThreadEnv, q as ThreadInstance, r as ThreadMetadata, T as ToolCall, t as ToolResult, g as callClient, h as callClientStream, c as createThreadEndpointHandler, j as decodeStreamChunk, d as defineController, i as encodeStreamChunk, s as supportsClientForwarding } from './index-
|
|
4
|
+
export { A as Agent, x as AttachmentRef, f as BuilderThreadEndpointHandler, C as CLIENT_STREAM_CHUNK_BYTES, o as ClientDuplex, p as ClientForwarding, m as ClientStreamRequest, n as ClientStreamResponse, k as ClientToolRequest, l as ClientToolResponse, B as Controller, a as ControllerContext, E as Env, w as FileRecord, y as FileStats, u as FlowResult, F as FlowState, G as GrepResult, D as ImageContentPart, I as ImageMetadata, L as LLMResponse, M as Message, J as MessageContent, H as MultimodalContent, R as RequestContext, S as StorageBackend, v as TelemetryEvent, z as TextContentPart, b as ThreadEndpointContext, e as ThreadEnv, q as ThreadInstance, r as ThreadMetadata, T as ToolCall, t as ToolResult, g as callClient, h as callClientStream, c as createThreadEndpointHandler, j as decodeStreamChunk, d as defineController, i as encodeStreamChunk, s as supportsClientForwarding } from './index-1AMgutkG.js';
|
|
5
5
|
export { AgentType, DefinitionLoader, GlobalNamespaceContext, HookSignatures, ImageContent, ModelCapabilities, ModelProvider, NamespaceContext, PackageSignature, PackedExports, PackedMeta, PackedMetadata, PackedNamespaceContext, PromptInput, PromptTextPart, ProviderAssistantMessage, ProviderConfigSlot, ProviderConfigSlots, ProviderConfigValueSource, ProviderDefinition, ProviderError, ProviderErrorCode, ProviderFactory, ProviderFactoryConfig, ProviderFinishReason, ProviderGeneratedImage, ProviderMessage, ProviderMessageContent, ProviderMethodOverrides, ModelCapabilities as ProviderModelCapabilities, ProviderOverride, ProviderOverrideContext, ProviderReasoningDetail, ProviderRequest, ProviderResponse, ProviderStreamChunk, ProviderSyncOverride, ProviderSystemMessage, ProviderTool, ProviderToolCallPart, ProviderToolMessage, ProviderToolResultContent, ProviderUsage, ProviderUserMessage, ReasoningConfig, StructuredPrompt, TextContent, Tool, ToolArgs, ToolArgsNode, ToolArgsRawShape, ToolContent, belongsToPackage, defineAgent, defineHook, defineModel, definePrompt, defineProvider, defineTool, isPacked, isVisibleInNamespace, mapReasoningLevel, providerConst, providerEnv, providerValue } from '@standardagents/spec';
|
|
6
6
|
export { C as ConstituentItem, D as DiscoveredPackage, N as NamespacedRegistry, P as PackingAnalysis, a as PackingOptions, b as PackingResult, c as UnpackOptions, d as UnpackResult } from './types-Bpe7IANZ.js';
|
|
7
7
|
export { D as DiscoveryConfig, P as PackageDiscoveryService, d as discoverPackages } from './discovery-DiMJWisl.js';
|
package/dist/index.js
CHANGED
|
@@ -14891,6 +14891,12 @@ declare module 'virtual:@standardagents/builder' {
|
|
|
14891
14891
|
parent: string | null;
|
|
14892
14892
|
terminated: number | null;
|
|
14893
14893
|
created_at: number;
|
|
14894
|
+
/** Unix seconds of the last message or execution on this thread (or a descendant). */
|
|
14895
|
+
last_activity_at?: number | null;
|
|
14896
|
+
/** True while the thread is executing a flow. */
|
|
14897
|
+
executing?: boolean;
|
|
14898
|
+
/** Short excerpt of the most recent user message, for thread-list rows. */
|
|
14899
|
+
last_message_preview?: string | null;
|
|
14894
14900
|
}
|
|
14895
14901
|
|
|
14896
14902
|
export interface UpdateThreadParams {
|
|
@@ -26192,9 +26198,9 @@ var DurableThread = class _DurableThread extends DurableObject {
|
|
|
26192
26198
|
* Each migration is run in order, starting from the current version + 1.
|
|
26193
26199
|
*/
|
|
26194
26200
|
async runMigrations(fromVersion) {
|
|
26195
|
-
for (const
|
|
26196
|
-
if (
|
|
26197
|
-
await
|
|
26201
|
+
for (const migration49 of migrations) {
|
|
26202
|
+
if (migration49.version > fromVersion) {
|
|
26203
|
+
await migration49.up(this.ctx.storage.sql);
|
|
26198
26204
|
}
|
|
26199
26205
|
}
|
|
26200
26206
|
}
|
|
@@ -29588,6 +29594,28 @@ ${resultContent}${attachmentSummary}`;
|
|
|
29588
29594
|
if (!namespace || typeof namespace.idFromName !== "function") return null;
|
|
29589
29595
|
return namespace.get(namespace.idFromName(threadId));
|
|
29590
29596
|
}
|
|
29597
|
+
/**
|
|
29598
|
+
* Stamp thread activity on the registry so thread lists can sort by recency
|
|
29599
|
+
* of real work and show which threads are executing right now. Registry
|
|
29600
|
+
* bookkeeping is presentation state: a failure here must never take down the
|
|
29601
|
+
* turn that triggered it.
|
|
29602
|
+
*/
|
|
29603
|
+
async recordRegistryActivity(threadId, executing, messagePreview) {
|
|
29604
|
+
try {
|
|
29605
|
+
const namespace = this.env.AGENT_BUILDER;
|
|
29606
|
+
if (!namespace || typeof namespace.idFromName !== "function") return;
|
|
29607
|
+
const agentBuilder = namespace.get(namespace.idFromName("singleton"));
|
|
29608
|
+
await agentBuilder.recordThreadActivity?.(threadId, {
|
|
29609
|
+
executing,
|
|
29610
|
+
...messagePreview !== void 0 ? { messagePreview } : {}
|
|
29611
|
+
});
|
|
29612
|
+
} catch (error) {
|
|
29613
|
+
console.error(
|
|
29614
|
+
"[DurableThread] Failed to record thread activity (non-fatal):",
|
|
29615
|
+
error
|
|
29616
|
+
);
|
|
29617
|
+
}
|
|
29618
|
+
}
|
|
29591
29619
|
/** Arm the standing watchdog for an execution start. One pending row max. */
|
|
29592
29620
|
async armExecutionWatchdog(threadId) {
|
|
29593
29621
|
try {
|
|
@@ -29774,6 +29802,7 @@ ${resultContent}${attachmentSummary}`;
|
|
|
29774
29802
|
}
|
|
29775
29803
|
this.isExecuting = false;
|
|
29776
29804
|
this.currentAbortController = null;
|
|
29805
|
+
await this.recordRegistryActivity(threadId, false);
|
|
29777
29806
|
tookOver = true;
|
|
29778
29807
|
} else if (incomplete.length > 0 && silenceMs <= ceiling) {
|
|
29779
29808
|
return report("observing", "none");
|
|
@@ -29977,6 +30006,7 @@ Its execution was lost (the executor restarted or hung) and automatic recovery w
|
|
|
29977
30006
|
this.isExecuting = true;
|
|
29978
30007
|
this.currentAbortController = new AbortController();
|
|
29979
30008
|
await this.armExecutionWatchdog(threadId);
|
|
30009
|
+
await this.recordRegistryActivity(threadId, true);
|
|
29980
30010
|
try {
|
|
29981
30011
|
const agentDef = await this.loadAgent(agentName);
|
|
29982
30012
|
const packageId = agentDef.__package?.packageId;
|
|
@@ -30108,6 +30138,7 @@ Its execution was lost (the executor restarted or hung) and automatic recovery w
|
|
|
30108
30138
|
this.isExecuting = false;
|
|
30109
30139
|
this.currentAbortController = null;
|
|
30110
30140
|
await this.disarmExecutionWatchdog(threadId);
|
|
30141
|
+
await this.recordRegistryActivity(threadId, false);
|
|
30111
30142
|
}
|
|
30112
30143
|
}
|
|
30113
30144
|
/**
|
|
@@ -30168,6 +30199,11 @@ Its execution was lost (the executor restarted or hung) and automatic recovery w
|
|
|
30168
30199
|
this.isExecuting = true;
|
|
30169
30200
|
this.currentAbortController = new AbortController();
|
|
30170
30201
|
await this.armExecutionWatchdog(threadId);
|
|
30202
|
+
await this.recordRegistryActivity(
|
|
30203
|
+
threadId,
|
|
30204
|
+
true,
|
|
30205
|
+
role === "user" ? content : void 0
|
|
30206
|
+
);
|
|
30171
30207
|
try {
|
|
30172
30208
|
const agentBuilderId = this.env.AGENT_BUILDER.idFromName("singleton");
|
|
30173
30209
|
const agentBuilder = this.env.AGENT_BUILDER.get(agentBuilderId);
|
|
@@ -30307,6 +30343,7 @@ Its execution was lost (the executor restarted or hung) and automatic recovery w
|
|
|
30307
30343
|
this.isExecuting = false;
|
|
30308
30344
|
this.currentAbortController = null;
|
|
30309
30345
|
await this.disarmExecutionWatchdog(threadId);
|
|
30346
|
+
await this.recordRegistryActivity(threadId, false);
|
|
30310
30347
|
}
|
|
30311
30348
|
}
|
|
30312
30349
|
/**
|
|
@@ -30324,6 +30361,7 @@ Its execution was lost (the executor restarted or hung) and automatic recovery w
|
|
|
30324
30361
|
this.isExecuting = true;
|
|
30325
30362
|
this.currentAbortController = new AbortController();
|
|
30326
30363
|
await this.armExecutionWatchdog(threadId);
|
|
30364
|
+
await this.recordRegistryActivity(threadId, true);
|
|
30327
30365
|
try {
|
|
30328
30366
|
const agentBuilderId = this.env.AGENT_BUILDER.idFromName("singleton");
|
|
30329
30367
|
const agentBuilder = this.env.AGENT_BUILDER.get(agentBuilderId);
|
|
@@ -30433,6 +30471,7 @@ Its execution was lost (the executor restarted or hung) and automatic recovery w
|
|
|
30433
30471
|
this.isExecuting = false;
|
|
30434
30472
|
this.currentAbortController = null;
|
|
30435
30473
|
await this.disarmExecutionWatchdog(threadId);
|
|
30474
|
+
await this.recordRegistryActivity(threadId, false);
|
|
30436
30475
|
const latestQueuedSide = await this.getLatestQueuedMessageSide();
|
|
30437
30476
|
if (latestQueuedSide) {
|
|
30438
30477
|
await this.ensureQueuedMessageExecution(threadId, latestQueuedSide);
|
|
@@ -31526,9 +31565,43 @@ var migration46 = {
|
|
|
31526
31565
|
}
|
|
31527
31566
|
};
|
|
31528
31567
|
|
|
31568
|
+
// src/durable-objects/agentbuilder-migrations/0013_add_thread_activity.ts
|
|
31569
|
+
var migration47 = {
|
|
31570
|
+
version: 13,
|
|
31571
|
+
async up(sql) {
|
|
31572
|
+
sql.exec(`ALTER TABLE threads ADD COLUMN last_activity_at INTEGER`);
|
|
31573
|
+
sql.exec(`ALTER TABLE threads ADD COLUMN executing_since INTEGER`);
|
|
31574
|
+
sql.exec(
|
|
31575
|
+
`CREATE INDEX IF NOT EXISTS idx_threads_last_activity_at ON threads(last_activity_at)`
|
|
31576
|
+
);
|
|
31577
|
+
sql.exec(`UPDATE threads SET last_activity_at = created_at`);
|
|
31578
|
+
sql.exec(`
|
|
31579
|
+
INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '13')
|
|
31580
|
+
`);
|
|
31581
|
+
}
|
|
31582
|
+
};
|
|
31583
|
+
|
|
31584
|
+
// src/durable-objects/agentbuilder-migrations/0014_thread_activity_scale.ts
|
|
31585
|
+
var migration48 = {
|
|
31586
|
+
version: 14,
|
|
31587
|
+
async up(sql) {
|
|
31588
|
+
sql.exec(`ALTER TABLE threads ADD COLUMN last_message_preview TEXT`);
|
|
31589
|
+
sql.exec(
|
|
31590
|
+
`CREATE INDEX IF NOT EXISTS idx_threads_executing_since
|
|
31591
|
+
ON threads(executing_since) WHERE executing_since IS NOT NULL`
|
|
31592
|
+
);
|
|
31593
|
+
sql.exec(
|
|
31594
|
+
`UPDATE threads SET last_activity_at = created_at WHERE last_activity_at IS NULL`
|
|
31595
|
+
);
|
|
31596
|
+
sql.exec(`
|
|
31597
|
+
INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '14')
|
|
31598
|
+
`);
|
|
31599
|
+
}
|
|
31600
|
+
};
|
|
31601
|
+
|
|
31529
31602
|
// src/durable-objects/agentbuilder-migrations/index.ts
|
|
31530
|
-
var migrations2 = [migration35, migration36, migration37, migration38, migration39, migration40, migration41, migration42, migration43, migration44, migration45, migration46];
|
|
31531
|
-
var LATEST_SCHEMA_VERSION2 =
|
|
31603
|
+
var migrations2 = [migration35, migration36, migration37, migration38, migration39, migration40, migration41, migration42, migration43, migration44, migration45, migration46, migration47, migration48];
|
|
31604
|
+
var LATEST_SCHEMA_VERSION2 = 14;
|
|
31532
31605
|
|
|
31533
31606
|
// src/utils/crypto.ts
|
|
31534
31607
|
var CryptoUtil = class {
|
|
@@ -31727,6 +31800,14 @@ function parseStoredPermissions(value) {
|
|
|
31727
31800
|
return null;
|
|
31728
31801
|
}
|
|
31729
31802
|
}
|
|
31803
|
+
var EXECUTING_STALE_AFTER_SECONDS = 15 * 60;
|
|
31804
|
+
var THREAD_PREVIEW_MAX_CHARS = 140;
|
|
31805
|
+
var buildThreadPreview = (content) => {
|
|
31806
|
+
const collapsed = content.replace(/\s+/g, " ").trim();
|
|
31807
|
+
if (!collapsed) return null;
|
|
31808
|
+
return collapsed.length > THREAD_PREVIEW_MAX_CHARS ? `${collapsed.slice(0, THREAD_PREVIEW_MAX_CHARS - 1)}\u2026` : collapsed;
|
|
31809
|
+
};
|
|
31810
|
+
var isThreadExecuting = (executingSince, nowSeconds) => executingSince != null && nowSeconds - executingSince < EXECUTING_STALE_AFTER_SECONDS;
|
|
31730
31811
|
var DurableAgentBuilder = class extends DurableObject {
|
|
31731
31812
|
migratedToVersion = null;
|
|
31732
31813
|
eventSockets = /* @__PURE__ */ new Set();
|
|
@@ -32295,9 +32376,9 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
32295
32376
|
}
|
|
32296
32377
|
}
|
|
32297
32378
|
async runMigrations(fromVersion) {
|
|
32298
|
-
for (const
|
|
32299
|
-
if (
|
|
32300
|
-
await
|
|
32379
|
+
for (const migration49 of migrations2) {
|
|
32380
|
+
if (migration49.version > fromVersion) {
|
|
32381
|
+
await migration49.up(this.ctx.storage.sql);
|
|
32301
32382
|
}
|
|
32302
32383
|
}
|
|
32303
32384
|
}
|
|
@@ -32339,8 +32420,8 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
32339
32420
|
const encryptedEnv = await this.encryptEnvRecord(env);
|
|
32340
32421
|
const properties = this.withEnvTypeRecord(params.properties ?? null, envTypes);
|
|
32341
32422
|
await this.ctx.storage.sql.exec(
|
|
32342
|
-
`INSERT INTO threads (id, agent_name, user_id, tags, env, tenvs, properties, parent, terminated, created_at)
|
|
32343
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, NULL, ?)`,
|
|
32423
|
+
`INSERT INTO threads (id, agent_name, user_id, tags, env, tenvs, properties, parent, terminated, created_at, last_activity_at)
|
|
32424
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?)`,
|
|
32344
32425
|
id,
|
|
32345
32426
|
params.agent_name,
|
|
32346
32427
|
params.user_id || null,
|
|
@@ -32349,6 +32430,7 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
32349
32430
|
encryptedEnv,
|
|
32350
32431
|
properties ? JSON.stringify(properties) : null,
|
|
32351
32432
|
params.parent ?? null,
|
|
32433
|
+
now,
|
|
32352
32434
|
now
|
|
32353
32435
|
);
|
|
32354
32436
|
const thread = {
|
|
@@ -32362,7 +32444,9 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
32362
32444
|
properties,
|
|
32363
32445
|
parent: params.parent ?? null,
|
|
32364
32446
|
terminated: null,
|
|
32365
|
-
created_at: now
|
|
32447
|
+
created_at: now,
|
|
32448
|
+
last_activity_at: now,
|
|
32449
|
+
executing: false
|
|
32366
32450
|
};
|
|
32367
32451
|
const eventThread = await this.toThreadEventPayload(thread);
|
|
32368
32452
|
this.broadcastEvent({ type: "thread_created", thread: eventThread });
|
|
@@ -32418,7 +32502,10 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
32418
32502
|
*/
|
|
32419
32503
|
async getThread(id) {
|
|
32420
32504
|
await this.ensureMigrated();
|
|
32421
|
-
const cursor = await this.ctx.storage.sql.exec(
|
|
32505
|
+
const cursor = await this.ctx.storage.sql.exec(
|
|
32506
|
+
`SELECT id, agent_name, user_id, tags, env, tenvs, properties, parent, terminated, created_at, last_activity_at, executing_since, last_message_preview FROM threads WHERE id = ?`,
|
|
32507
|
+
id
|
|
32508
|
+
);
|
|
32422
32509
|
const rows = cursor.toArray();
|
|
32423
32510
|
if (rows.length === 0) {
|
|
32424
32511
|
return null;
|
|
@@ -32438,7 +32525,13 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
32438
32525
|
properties,
|
|
32439
32526
|
parent: row.parent,
|
|
32440
32527
|
terminated: row.terminated,
|
|
32441
|
-
created_at: row.created_at
|
|
32528
|
+
created_at: row.created_at,
|
|
32529
|
+
last_activity_at: row.last_activity_at ?? row.created_at,
|
|
32530
|
+
executing: isThreadExecuting(
|
|
32531
|
+
row.executing_since,
|
|
32532
|
+
Math.floor(Date.now() / 1e3)
|
|
32533
|
+
),
|
|
32534
|
+
last_message_preview: row.last_message_preview
|
|
32442
32535
|
};
|
|
32443
32536
|
}
|
|
32444
32537
|
/**
|
|
@@ -32479,6 +32572,7 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
32479
32572
|
*/
|
|
32480
32573
|
async listThreads(params) {
|
|
32481
32574
|
await this.ensureMigrated();
|
|
32575
|
+
const nowSeconds = Math.floor(Date.now() / 1e3);
|
|
32482
32576
|
const whereClauses = [];
|
|
32483
32577
|
const args = [];
|
|
32484
32578
|
if (params?.agent_name) {
|
|
@@ -32514,6 +32608,18 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
32514
32608
|
whereClauses.push("created_at <= ?");
|
|
32515
32609
|
args.push(params.endDate);
|
|
32516
32610
|
}
|
|
32611
|
+
if (params?.executing === true) {
|
|
32612
|
+
whereClauses.push("executing_since IS NOT NULL AND executing_since > ?");
|
|
32613
|
+
args.push(nowSeconds - EXECUTING_STALE_AFTER_SECONDS);
|
|
32614
|
+
} else if (params?.executing === false) {
|
|
32615
|
+
whereClauses.push("(executing_since IS NULL OR executing_since <= ?)");
|
|
32616
|
+
args.push(nowSeconds - EXECUTING_STALE_AFTER_SECONDS);
|
|
32617
|
+
}
|
|
32618
|
+
if (params?.terminated === true) {
|
|
32619
|
+
whereClauses.push("terminated IS NOT NULL");
|
|
32620
|
+
} else if (params?.terminated === false) {
|
|
32621
|
+
whereClauses.push("terminated IS NULL");
|
|
32622
|
+
}
|
|
32517
32623
|
const whereClause = whereClauses.length > 0 ? `WHERE ${whereClauses.join(" AND ")}` : "";
|
|
32518
32624
|
const countCursor = await this.ctx.storage.sql.exec(
|
|
32519
32625
|
`SELECT COUNT(*) as count FROM threads ${whereClause}`,
|
|
@@ -32522,10 +32628,11 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
32522
32628
|
const total = countCursor.one().count;
|
|
32523
32629
|
const limit = params?.limit ?? 100;
|
|
32524
32630
|
const offset = params?.offset ?? 0;
|
|
32631
|
+
const orderByClause = params?.sort === "created" ? "created_at DESC" : params?.sort === "oldest" ? "created_at ASC" : "last_activity_at DESC, created_at DESC";
|
|
32525
32632
|
const cursor = await this.ctx.storage.sql.exec(
|
|
32526
|
-
`SELECT id, agent_name, user_id, tags, properties, parent, terminated, created_at FROM threads
|
|
32633
|
+
`SELECT id, agent_name, user_id, tags, properties, parent, terminated, created_at, last_activity_at, executing_since, last_message_preview FROM threads
|
|
32527
32634
|
${whereClause}
|
|
32528
|
-
ORDER BY
|
|
32635
|
+
ORDER BY ${orderByClause}
|
|
32529
32636
|
LIMIT ? OFFSET ?`,
|
|
32530
32637
|
...args,
|
|
32531
32638
|
limit,
|
|
@@ -32545,10 +32652,90 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
32545
32652
|
properties: row.properties ? JSON.parse(row.properties) : null,
|
|
32546
32653
|
parent: row.parent,
|
|
32547
32654
|
terminated: row.terminated,
|
|
32548
|
-
created_at: row.created_at
|
|
32655
|
+
created_at: row.created_at,
|
|
32656
|
+
last_activity_at: row.last_activity_at ?? row.created_at,
|
|
32657
|
+
executing: isThreadExecuting(row.executing_since, nowSeconds),
|
|
32658
|
+
last_message_preview: row.last_message_preview
|
|
32549
32659
|
}));
|
|
32550
32660
|
return { threads, total };
|
|
32551
32661
|
}
|
|
32662
|
+
/**
|
|
32663
|
+
* Distinct owners of threads visible to the caller, with counts, so a thread
|
|
32664
|
+
* list can offer an "owner" filter without exposing the admin-only user
|
|
32665
|
+
* directory (which is unavailable on hosted instances).
|
|
32666
|
+
*/
|
|
32667
|
+
async listThreadOwners(params) {
|
|
32668
|
+
await this.ensureMigrated();
|
|
32669
|
+
const whereClause = params?.user_id ? "WHERE t.user_id = ?" : "";
|
|
32670
|
+
const args = params?.user_id ? [params.user_id] : [];
|
|
32671
|
+
const cursor = await this.ctx.storage.sql.exec(
|
|
32672
|
+
`SELECT t.user_id AS user_id,
|
|
32673
|
+
u.username AS username,
|
|
32674
|
+
u.display_name AS display_name,
|
|
32675
|
+
u.email AS email,
|
|
32676
|
+
COUNT(*) AS thread_count
|
|
32677
|
+
FROM threads t
|
|
32678
|
+
LEFT JOIN users u ON u.id = t.user_id
|
|
32679
|
+
${whereClause}
|
|
32680
|
+
GROUP BY t.user_id
|
|
32681
|
+
ORDER BY thread_count DESC`,
|
|
32682
|
+
...args
|
|
32683
|
+
);
|
|
32684
|
+
return cursor.toArray();
|
|
32685
|
+
}
|
|
32686
|
+
/**
|
|
32687
|
+
* Record that a thread did work: stamp `last_activity_at` and flip the
|
|
32688
|
+
* executing marker. Activity bubbles up the parent chain so a root thread
|
|
32689
|
+
* sorts by the freshest work anywhere in its subagent tree — otherwise a
|
|
32690
|
+
* long-running subagent would let its parent sink down an activity-sorted
|
|
32691
|
+
* list.
|
|
32692
|
+
*/
|
|
32693
|
+
async recordThreadActivity(threadId, options) {
|
|
32694
|
+
await this.ensureMigrated();
|
|
32695
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
32696
|
+
const executing = options?.executing;
|
|
32697
|
+
const preview = typeof options?.messagePreview === "string" ? buildThreadPreview(options.messagePreview) : void 0;
|
|
32698
|
+
await this.ctx.storage.sql.exec(
|
|
32699
|
+
`UPDATE threads
|
|
32700
|
+
SET last_activity_at = ?
|
|
32701
|
+
WHERE id IN (
|
|
32702
|
+
WITH RECURSIVE ancestry(id, parent) AS (
|
|
32703
|
+
SELECT id, parent FROM threads WHERE id = ?
|
|
32704
|
+
UNION ALL
|
|
32705
|
+
SELECT t.id, t.parent FROM threads t JOIN ancestry a ON t.id = a.parent
|
|
32706
|
+
)
|
|
32707
|
+
SELECT id FROM ancestry
|
|
32708
|
+
)`,
|
|
32709
|
+
now,
|
|
32710
|
+
threadId
|
|
32711
|
+
);
|
|
32712
|
+
if (executing === true) {
|
|
32713
|
+
await this.ctx.storage.sql.exec(
|
|
32714
|
+
`UPDATE threads SET executing_since = ? WHERE id = ? AND executing_since IS NULL`,
|
|
32715
|
+
now,
|
|
32716
|
+
threadId
|
|
32717
|
+
);
|
|
32718
|
+
} else if (executing === false) {
|
|
32719
|
+
await this.ctx.storage.sql.exec(
|
|
32720
|
+
`UPDATE threads SET executing_since = NULL WHERE id = ?`,
|
|
32721
|
+
threadId
|
|
32722
|
+
);
|
|
32723
|
+
}
|
|
32724
|
+
if (preview !== void 0) {
|
|
32725
|
+
await this.ctx.storage.sql.exec(
|
|
32726
|
+
`UPDATE threads SET last_message_preview = ? WHERE id = ?`,
|
|
32727
|
+
preview,
|
|
32728
|
+
threadId
|
|
32729
|
+
);
|
|
32730
|
+
}
|
|
32731
|
+
this.broadcastEvent({
|
|
32732
|
+
type: "thread_activity",
|
|
32733
|
+
threadId,
|
|
32734
|
+
last_activity_at: now,
|
|
32735
|
+
executing: executing === true,
|
|
32736
|
+
...preview !== void 0 ? { last_message_preview: preview } : {}
|
|
32737
|
+
});
|
|
32738
|
+
}
|
|
32552
32739
|
/**
|
|
32553
32740
|
* Delete a thread from the registry.
|
|
32554
32741
|
*/
|