@nextclaw/kernel 0.10.1 → 0.10.3
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/index.d.ts +46 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +295 -215
- package/dist/index.js.map +1 -1
- package/package.json +10 -10
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { AUTOMATIC_UPDATE_CHECK_INTERVAL_MS, getAutomaticUpdateCheckDelay, resolveAutomaticUpdateCheckIntervalMs } from "./utils/automatic-update-check.utils.js";
|
|
2
2
|
import { n as getUnsignedUpdateManifest, r as serializeUnsignedUpdateManifest, t as UpdateManifestReader } from "./update-manifest.types-C0qPrjGQ.js";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
|
-
import { APP_NAME, AgentRouteResolver, BUILTIN_MAIN_AGENT_ID, CLEAR_THINKING_TOKENS, CONTEXT_COMPACTION_METADATA_KEY, ConfigSchema, ContextCompactionService, ContextWindowBudgetService, CronService, CronTool, DEFAULT_PANELS_DIR, DEFAULT_SERVICE_APPS_DIR, DEFAULT_SESSION_SEARCH_LIMIT, DEFAULT_WORKSPACE_REPOSITORY_IDENTITY_RESOLVER, DIAGNOSTIC_CORRELATION_METADATA_KEY, DiagnosticRuntime, EditFileTool, ExecTool, ExtensionChannelAdapter, GatewayTool, InputBudgetPruner, LLMProvider, ListDirTool, LiteLLMProvider, MAX_SESSION_SEARCH_LIMIT, MemoryGetTool, MemorySearchTool, MemoryStore, MessageBus, MessageTool, ProviderModelDiscoveryService, ProviderRegistry, ReadFileTool, RequestedSkillsMetadataReader, SILENT_REPLY_TOKEN, SessionProjectContextResolver, SessionSearchService, SkillsLoader, THINKING_LEVELS, ViewImageTool, WebFetchTool, WebSearchTool, WriteFileTool, buildCompressingCompactionCheckpoint, buildConfigSchema, buildContextWindowSnapshot, buildReloadPlan, buildSessionRequestToolResult, buildToolCatalogEntries, createAgentProfile, createAssistantStreamDeltaControlMessage, createAssistantStreamResetControlMessage, createCompletedSessionRequest, createFailedSessionRequest, createRunningSessionRequest, createRuntimeChildEnv, createTypingStopControlMessage, diffConfigPaths, ensureDir, estimateInputTokens, evaluateSilentReply, expandHome, findEffectiveAgentProfile, getConfigPath, getDataDir, getDataPath, getSessionsPath, getWorkspacePath, getWorkspacePathFromConfig, isNextclawControlMessage, loadConfig, mergeExtensionConfigView, modelSupportsVision, normalizeAgentProfileId, normalizeInlineSecretRefs, normalizeModelThinkingCapability, normalizeProviderModelConfig, normalizeToolParams, parseAgentScopedSessionKey, parseThinkingLevel, readCompressedContextCompactionCheckpoint, readOptionalString, readParentSessionId, readSessionProjectRoot, redactConfigObject, removeAgentProfile, resolveConfigSecrets, resolveDefaultAgentProfileId, resolveEffectiveAgentProfiles, resolveNextclawSelfManageGuidePaths, resolveProviderRuntime, resolveRuntimeCommandLaunch, resolveSessionProjectContext, resolveSessionWorkspacePath, resolveThinkingLevel, safeFilename, sanitizeOutboundAssistantContent, saveConfig, summarizeSessionRequestTask, toExtensionConfigView, updateAgentProfile } from "@nextclaw/core";
|
|
4
|
+
import { APP_NAME, AgentRouteResolver, BUILTIN_MAIN_AGENT_ID, CLEAR_THINKING_TOKENS, CONTEXT_COMPACTION_METADATA_KEY, ConfigSchema, ContextCompactionService, ContextWindowBudgetService, CronService, CronTool, DEFAULT_PANELS_DIR, DEFAULT_SERVICE_APPS_DIR, DEFAULT_SESSION_SEARCH_LIMIT, DEFAULT_WORKSPACE_REPOSITORY_IDENTITY_RESOLVER, DIAGNOSTIC_CORRELATION_METADATA_KEY, DiagnosticRuntime, EditFileTool, ExecTool, ExtensionChannelAdapter, GatewayTool, InputBudgetPruner, LLMProvider, ListDirTool, LiteLLMProvider, LocalExecutionClaimService, MAX_SESSION_SEARCH_LIMIT, MemoryGetTool, MemorySearchTool, MemoryStore, MessageBus, MessageTool, ProviderModelDiscoveryService, ProviderRegistry, ReadFileTool, RequestedSkillsMetadataReader, SILENT_REPLY_TOKEN, SessionProjectContextResolver, SessionSearchService, SkillsLoader, THINKING_LEVELS, ViewImageTool, WebFetchTool, WebSearchTool, WriteFileTool, buildCompressingCompactionCheckpoint, buildConfigSchema, buildContextWindowSnapshot, buildReloadPlan, buildSessionRequestToolResult, buildToolCatalogEntries, createAgentProfile, createAssistantStreamDeltaControlMessage, createAssistantStreamResetControlMessage, createCompletedSessionRequest, createFailedSessionRequest, createRunningSessionRequest, createRuntimeChildEnv, createTypingStopControlMessage, diffConfigPaths, ensureDir, estimateInputTokens, evaluateSilentReply, expandHome, findEffectiveAgentProfile, getConfigPath, getDataDir, getDataPath, getSessionsPath, getWorkspacePath, getWorkspacePathFromConfig, isNextclawControlMessage, loadConfig, mergeExtensionConfigView, modelSupportsVision, normalizeAgentProfileId, normalizeInlineSecretRefs, normalizeModelThinkingCapability, normalizeProviderModelConfig, normalizeToolParams, parseAgentScopedSessionKey, parseThinkingLevel, readCompressedContextCompactionCheckpoint, readOptionalString, readParentSessionId, readSessionProjectRoot, redactConfigObject, removeAgentProfile, resolveConfigSecrets, resolveDefaultAgentProfileId, resolveEffectiveAgentProfiles, resolveNextclawSelfManageGuidePaths, resolveProviderRuntime, resolveRuntimeCommandLaunch, resolveSessionProjectContext, resolveSessionWorkspacePath, resolveThinkingLevel, safeFilename, sanitizeOutboundAssistantContent, saveConfig, summarizeSessionRequestTask, toExtensionConfigView, updateAgentProfile } from "@nextclaw/core";
|
|
5
5
|
import { NCP_AI_EXECUTION_METADATA_KEY, NCP_INTERNAL_VISIBILITY_METADATA_KEY, NCP_RUN_TRIGGER_METADATA_KEY, NcpEventType, OBSERVATION_EVENT_EXTENSION_TYPE, createUnavailableNcpAiExecutionMetadata, isHiddenNcpMessage, normalizeAssistantText, parseNcpRunTriggerInput, readNcpAiExecutionMetadata, sanitizeAssistantReplyTags } from "@nextclaw/ncp";
|
|
6
|
+
import { LocalAssetStore, buildAssetContentPath, buildOpenAiFunctionTool, isTextLikeAsset, ncpMessageToOpenAiMessages, validateToolArgs } from "@nextclaw/ncp-agent-runtime";
|
|
6
7
|
import { CHAT_CONTINUATION_TARGET_MESSAGE_METADATA_KEY, CHAT_CONVERSATION_EXCERPT_TOKEN_KIND, CHAT_INLINE_TOKENS_METADATA_KEY, CHAT_INLINE_TOKENS_SCHEMA_VERSION, CHAT_PROJECT_TOKEN_KIND, CHAT_SESSION_MATERIALIZATION_METADATA_KEY, CHAT_SYSTEM_OBJECT_TOKEN_KIND, CHAT_UI_RESOURCE_TOKEN_KIND, CHAT_WORKSPACE_DIRECTORY_TOKEN_KIND, CHAT_WORKSPACE_EXCERPT_TOKEN_KIND, CHAT_WORKSPACE_FILE_TOKEN_KIND, Contribution as Contribution$1, EventBus, EventBus as EventBus$1, Ingress, Ingress as Ingress$1, PANEL_APP_INLINE_HOST_CONTRACT, PANEL_APP_SCROLL_RESTORATION_CONTRACT, SYSTEM_OBJECT_REFERENCE_DEFAULT_LIMIT, SYSTEM_OBJECT_REFERENCE_MAX_LIMIT, SYSTEM_OBJECT_TYPE_CRON_JOB, SYSTEM_OBJECT_TYPE_INBOX_DELIVERY, UI_CONTENT_PARAMS_HOST_CONTRACT, classifyDiagnosticError, createSystemObjectReferenceUri, createTypedKey, eventKeys, eventKeys as eventKeys$1, ingressKeys, ingressKeys as ingressKeys$1, isRuntimeDefaultModelValue, isSilentReplyNcpMessage, normalizeRuntimeModelSelectionMode, parseSystemObjectReferenceUri, readChatUiResourceReference, readInlineContentHeight, readSystemObjectResolvedReference, readUiContentParams } from "@nextclaw/shared";
|
|
7
|
-
import { LocalAssetStore, buildAssetContentPath, buildNcpUserContent, buildOpenAiFunctionTool, isTextLikeAsset, ncpMessageToOpenAiMessages, validateToolArgs } from "@nextclaw/ncp-agent-runtime";
|
|
8
8
|
import { createHash, createHmac, randomBytes, randomUUID, scryptSync, timingSafeEqual } from "node:crypto";
|
|
9
9
|
import { catchError, filter, from, lastValueFrom, tap } from "rxjs";
|
|
10
10
|
import { DefaultNcpAgentConversationStateManager, insertMessageByTimeline, mergeToolExecutionTiming } from "@nextclaw/ncp-toolkit";
|
|
@@ -64,6 +64,7 @@ var AgentManager = class {
|
|
|
64
64
|
return {
|
|
65
65
|
...profile,
|
|
66
66
|
contextTokens,
|
|
67
|
+
maxToolIterations: profile.maxToolIterations ?? config.agents.defaults.maxToolIterations,
|
|
67
68
|
model: profile.model ?? config.agents.defaults.model,
|
|
68
69
|
reservedContextTokens: ContextWindowBudgetService.resolveReservedContextTokens({
|
|
69
70
|
contextTokens,
|
|
@@ -188,135 +189,6 @@ var ContextCompactionJournalRecoveryService = class {
|
|
|
188
189
|
};
|
|
189
190
|
};
|
|
190
191
|
//#endregion
|
|
191
|
-
//#region src/utils/agent-run-metadata.utils.ts
|
|
192
|
-
const AGENT_RUN_MESSAGE_RUN_SPEC_METADATA_KEY = "run_spec";
|
|
193
|
-
const LEGACY_RUN_METADATA_KEYS = [
|
|
194
|
-
"account_id",
|
|
195
|
-
"agent_id",
|
|
196
|
-
"chat_id",
|
|
197
|
-
"preferred_model",
|
|
198
|
-
"project_root",
|
|
199
|
-
"runtime",
|
|
200
|
-
"sender_id",
|
|
201
|
-
"session_key",
|
|
202
|
-
"session_type"
|
|
203
|
-
];
|
|
204
|
-
function stripLegacyRunMetadata(metadata) {
|
|
205
|
-
const nextMetadata = structuredClone(metadata);
|
|
206
|
-
for (const key of LEGACY_RUN_METADATA_KEYS) delete nextMetadata[key];
|
|
207
|
-
return nextMetadata;
|
|
208
|
-
}
|
|
209
|
-
function buildRunMetadata(params) {
|
|
210
|
-
const { message, metadata, route } = params;
|
|
211
|
-
return {
|
|
212
|
-
...stripLegacyRunMetadata({
|
|
213
|
-
...message.metadata ?? {},
|
|
214
|
-
...metadata ?? {}
|
|
215
|
-
}),
|
|
216
|
-
channel: message.channel,
|
|
217
|
-
chatId: message.chatId,
|
|
218
|
-
accountId: route.accountId,
|
|
219
|
-
agentId: route.agentId,
|
|
220
|
-
sessionKey: route.sessionKey,
|
|
221
|
-
senderId: message.senderId
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
//#endregion
|
|
225
|
-
//#region src/utils/ncp-message-bridge.utils.ts
|
|
226
|
-
function normalizeString$1(value) {
|
|
227
|
-
if (typeof value !== "string") return null;
|
|
228
|
-
const trimmed = value.trim();
|
|
229
|
-
return trimmed.length > 0 ? trimmed : null;
|
|
230
|
-
}
|
|
231
|
-
function ensureIsoTimestamp(value, fallback) {
|
|
232
|
-
if (typeof value !== "string") return fallback;
|
|
233
|
-
const timestamp = Date.parse(value);
|
|
234
|
-
if (!Number.isFinite(timestamp)) return fallback;
|
|
235
|
-
return new Date(timestamp).toISOString();
|
|
236
|
-
}
|
|
237
|
-
function serializeToolArgs(args) {
|
|
238
|
-
if (typeof args === "string") return args;
|
|
239
|
-
return JSON.stringify(args ?? {});
|
|
240
|
-
}
|
|
241
|
-
function serializeLegacyContent(parts) {
|
|
242
|
-
const text = parts.filter(isTextLikePart).map((part) => part.text).join("");
|
|
243
|
-
if (text.length > 0) return text;
|
|
244
|
-
if (parts.length === 0) return "";
|
|
245
|
-
return structuredClone(parts);
|
|
246
|
-
}
|
|
247
|
-
function extractTextFromNcpMessage(message) {
|
|
248
|
-
if (!message) return "";
|
|
249
|
-
return (message.role === "assistant" ? sanitizeAssistantReplyTags(message) : message).parts.filter(isTextLikePart).map((part) => part.text).join("");
|
|
250
|
-
}
|
|
251
|
-
function isTextLikePart(part) {
|
|
252
|
-
return part.type === "text" || part.type === "rich-text";
|
|
253
|
-
}
|
|
254
|
-
function buildLegacyUserContent(parts, options = {}) {
|
|
255
|
-
const content = buildNcpUserContent(parts, { assetStore: options.assetStore });
|
|
256
|
-
if (content === "") return serializeLegacyContent(parts);
|
|
257
|
-
return content;
|
|
258
|
-
}
|
|
259
|
-
function buildLegacyAssistantMessages(message, timestamp) {
|
|
260
|
-
const textContent = extractTextFromNcpMessage(message);
|
|
261
|
-
const reasoningParts = message.parts.filter((part) => part.type === "reasoning");
|
|
262
|
-
const reasoningContent = reasoningParts.map((part) => part.text).join("");
|
|
263
|
-
const toolInvocations = message.parts.filter((part) => part.type === "tool-invocation");
|
|
264
|
-
const assistantMessage = {
|
|
265
|
-
role: "assistant",
|
|
266
|
-
content: textContent,
|
|
267
|
-
timestamp,
|
|
268
|
-
ncp_message_id: message.id,
|
|
269
|
-
ncp_parts: structuredClone(message.parts)
|
|
270
|
-
};
|
|
271
|
-
if (typeof message.metadata?.reply_to === "string" && message.metadata.reply_to.trim().length > 0) assistantMessage.reply_to = message.metadata.reply_to.trim();
|
|
272
|
-
if (reasoningParts.length > 0) assistantMessage.reasoning_content = reasoningContent;
|
|
273
|
-
if (toolInvocations.length > 0) assistantMessage.tool_calls = toolInvocations.map((toolInvocation, index) => ({
|
|
274
|
-
id: toolInvocation.toolCallId ?? `${message.id}:tool:${index}`,
|
|
275
|
-
type: "function",
|
|
276
|
-
function: {
|
|
277
|
-
name: toolInvocation.toolName,
|
|
278
|
-
arguments: serializeToolArgs(toolInvocation.args)
|
|
279
|
-
}
|
|
280
|
-
}));
|
|
281
|
-
const messages = [assistantMessage];
|
|
282
|
-
for (const toolInvocation of toolInvocations) {
|
|
283
|
-
if (toolInvocation.state !== "result") continue;
|
|
284
|
-
messages.push({
|
|
285
|
-
role: "tool",
|
|
286
|
-
name: toolInvocation.toolName,
|
|
287
|
-
tool_call_id: toolInvocation.toolCallId,
|
|
288
|
-
content: typeof toolInvocation.result === "string" ? toolInvocation.result : JSON.stringify(toolInvocation.result ?? null),
|
|
289
|
-
...toolInvocation.resultContentItems ? { ncp_tool_result_content_items: structuredClone(toolInvocation.resultContentItems) } : {},
|
|
290
|
-
timestamp,
|
|
291
|
-
ncp_message_id: message.id
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
return messages;
|
|
295
|
-
}
|
|
296
|
-
function buildLegacyNonAssistantMessage(message, timestamp, options) {
|
|
297
|
-
return {
|
|
298
|
-
role: message.role === "service" && options.serviceRole === "system" ? "system" : message.role,
|
|
299
|
-
content: buildLegacyUserContent(message.parts, options),
|
|
300
|
-
timestamp,
|
|
301
|
-
ncp_message_id: message.id,
|
|
302
|
-
ncp_parts: structuredClone(message.parts),
|
|
303
|
-
...message.metadata ? { ncp_metadata: structuredClone(message.metadata) } : {}
|
|
304
|
-
};
|
|
305
|
-
}
|
|
306
|
-
function toLegacyMessages(messages, options = {}) {
|
|
307
|
-
const legacyMessages = [];
|
|
308
|
-
for (const rawMessage of messages) {
|
|
309
|
-
const message = rawMessage.role === "assistant" ? sanitizeAssistantReplyTags(rawMessage) : rawMessage;
|
|
310
|
-
const timestamp = ensureIsoTimestamp(message.timestamp, (/* @__PURE__ */ new Date()).toISOString());
|
|
311
|
-
if (message.role === "assistant") {
|
|
312
|
-
legacyMessages.push(...buildLegacyAssistantMessages(message, timestamp));
|
|
313
|
-
continue;
|
|
314
|
-
}
|
|
315
|
-
legacyMessages.push(buildLegacyNonAssistantMessage(message, timestamp, options));
|
|
316
|
-
}
|
|
317
|
-
return legacyMessages;
|
|
318
|
-
}
|
|
319
|
-
//#endregion
|
|
320
192
|
//#region src/utils/agent-model-input-budget.utils.ts
|
|
321
193
|
function buildContextBlockInputMessages(contextBlocks = []) {
|
|
322
194
|
const contextContent = contextBlocks.map((block) => block.trim()).filter(Boolean).join("\n\n");
|
|
@@ -938,6 +810,13 @@ function shouldRefreshContextWindowImmediately(event) {
|
|
|
938
810
|
}
|
|
939
811
|
//#endregion
|
|
940
812
|
//#region src/features/context-compaction/services/context-compaction-preflight.service.ts
|
|
813
|
+
function toCompactionModelMessages(messages, assetStore) {
|
|
814
|
+
return messages.flatMap((message) => ncpMessageToOpenAiMessages(message, { assetStore }).map((providerMessage) => ({
|
|
815
|
+
...providerMessage,
|
|
816
|
+
ncp_message_id: message.id,
|
|
817
|
+
timestamp: message.timestamp
|
|
818
|
+
})));
|
|
819
|
+
}
|
|
941
820
|
function estimateCompactionProjectionOverhead(phase) {
|
|
942
821
|
const summaryPlanOverhead = estimateInputTokens({
|
|
943
822
|
role: "user",
|
|
@@ -1006,8 +885,9 @@ var ContextCompactionPreflightService = class {
|
|
|
1006
885
|
compactionService = new ContextCompactionService();
|
|
1007
886
|
contextWindowBudgetService = new ContextWindowBudgetService();
|
|
1008
887
|
summaryGenerationService;
|
|
1009
|
-
constructor(agentManager, providerManager) {
|
|
888
|
+
constructor(agentManager, providerManager, assetStore = null) {
|
|
1010
889
|
this.agentManager = agentManager;
|
|
890
|
+
this.assetStore = assetStore;
|
|
1011
891
|
this.summaryGenerationService = new ContextCompactionSummaryGenerationService(providerManager);
|
|
1012
892
|
}
|
|
1013
893
|
preview = (params) => {
|
|
@@ -1025,7 +905,7 @@ var ContextCompactionPreflightService = class {
|
|
|
1025
905
|
const contextBlockInputTokens = estimateInputTokens(contextBlockMessages);
|
|
1026
906
|
const toolInputTokens = estimateToolInputTokens(tools);
|
|
1027
907
|
const snapshotFixedInputTokens = fixedInputTokens ?? contextBlockInputTokens + toolInputTokens;
|
|
1028
|
-
const messages = [...fixedInputTokens === void 0 ? contextBlockMessages : [], ...
|
|
908
|
+
const messages = [...fixedInputTokens === void 0 ? contextBlockMessages : [], ...toCompactionModelMessages(projectedMessages, this.assetStore)];
|
|
1029
909
|
return buildContextWindowSnapshotFromBudget({
|
|
1030
910
|
budget: this.contextWindowBudgetService.evaluate({
|
|
1031
911
|
messages,
|
|
@@ -1057,7 +937,7 @@ var ContextCompactionPreflightService = class {
|
|
|
1057
937
|
sessionMessages: ncpMessages
|
|
1058
938
|
}).messages : ncpMessages.filter((message) => !isContextCompactionTimelineMessage(message));
|
|
1059
939
|
const contextBlockMessages = buildContextBlockInputMessages(contextBlocks);
|
|
1060
|
-
const messages = [...contextBlockMessages, ...
|
|
940
|
+
const messages = [...contextBlockMessages, ...toCompactionModelMessages(projectedMessages, this.assetStore)];
|
|
1061
941
|
const preservableUserMessageIds = ncpMessages.flatMap((message) => message.role === "user" ? [message.id] : []);
|
|
1062
942
|
const fixedInputTokens = estimateToolInputTokens(tools);
|
|
1063
943
|
const snapshotFixedInputTokens = estimateInputTokens(contextBlockMessages) + fixedInputTokens;
|
|
@@ -1069,6 +949,7 @@ var ContextCompactionPreflightService = class {
|
|
|
1069
949
|
});
|
|
1070
950
|
const plan = trigger === "automatic" && !budget.shouldCompact ? null : this.compactionService.prepareForModelInput({
|
|
1071
951
|
messages,
|
|
952
|
+
coverLeadingSystemMessage: contextBlockMessages.length === 0 && isContextCompactionProjectionMessage(projectedMessages[0]),
|
|
1072
953
|
contextTokens,
|
|
1073
954
|
compactionThresholdTokens: trigger === "manual" ? 0 : budget.triggerTokens,
|
|
1074
955
|
fixedInputTokens,
|
|
@@ -1156,7 +1037,7 @@ var ContextCompactionPreflightService = class {
|
|
|
1156
1037
|
sessionMessages: [...pending.sessionMessages, timelineMessage]
|
|
1157
1038
|
}).messages;
|
|
1158
1039
|
const budget = this.contextWindowBudgetService.evaluate({
|
|
1159
|
-
messages: [...pending.contextBlockMessages, ...
|
|
1040
|
+
messages: [...pending.contextBlockMessages, ...toCompactionModelMessages(projectedMessages, this.assetStore)],
|
|
1160
1041
|
contextTokens: pending.contextTokens,
|
|
1161
1042
|
fixedInputTokens: pending.plan.fixedInputTokens,
|
|
1162
1043
|
reservedContextTokens: pending.reservedContextTokens
|
|
@@ -1193,11 +1074,11 @@ const MINIMUM_CONFIGURABLE_CONTEXT_TOKENS = 1e3;
|
|
|
1193
1074
|
var AgentContextWindowManager = class {
|
|
1194
1075
|
runInputBudgetBySession = /* @__PURE__ */ new Map();
|
|
1195
1076
|
preflightService;
|
|
1196
|
-
constructor(agentManager, contextProviderManager, toolProviderManager) {
|
|
1077
|
+
constructor(agentManager, contextProviderManager, toolProviderManager, assetStore = null) {
|
|
1197
1078
|
this.agentManager = agentManager;
|
|
1198
1079
|
this.contextProviderManager = contextProviderManager;
|
|
1199
1080
|
this.toolProviderManager = toolProviderManager;
|
|
1200
|
-
this.preflightService = new ContextCompactionPreflightService(agentManager);
|
|
1081
|
+
this.preflightService = new ContextCompactionPreflightService(agentManager, void 0, assetStore);
|
|
1201
1082
|
}
|
|
1202
1083
|
resolveRunSurface = async (request) => {
|
|
1203
1084
|
const surface = await this.buildRunSurface(request);
|
|
@@ -1332,8 +1213,8 @@ var AgentContextWindowManager = class {
|
|
|
1332
1213
|
//#region src/managers/agent-run-context-compaction.manager.ts
|
|
1333
1214
|
var AgentRunContextCompactionManager = class {
|
|
1334
1215
|
preflightService;
|
|
1335
|
-
constructor(agentManager, providerManager) {
|
|
1336
|
-
this.preflightService = new ContextCompactionPreflightService(agentManager, providerManager);
|
|
1216
|
+
constructor(agentManager, providerManager, assetStore = null) {
|
|
1217
|
+
this.preflightService = new ContextCompactionPreflightService(agentManager, providerManager, assetStore);
|
|
1337
1218
|
}
|
|
1338
1219
|
runPreflight = (input) => {
|
|
1339
1220
|
return this.run(input, "automatic", input.phase ?? "pre-run");
|
|
@@ -1787,13 +1668,14 @@ var AgentRunInputDeliveryService = class {
|
|
|
1787
1668
|
input: this.toPendingInput(moved)
|
|
1788
1669
|
};
|
|
1789
1670
|
};
|
|
1790
|
-
|
|
1671
|
+
promotePreferredSteeringInput = (sessionRun, queuedInputId, session) => {
|
|
1791
1672
|
try {
|
|
1792
|
-
|
|
1673
|
+
if (this.agentRuntimeManager.getOrCreate({
|
|
1793
1674
|
agentRuntimeId: session.agentRuntimeId,
|
|
1794
1675
|
session,
|
|
1795
1676
|
sessionRun
|
|
1796
|
-
}).capabilities?.nextStepInput
|
|
1677
|
+
}).capabilities?.nextStepInput !== true) return null;
|
|
1678
|
+
return sessionRun.moveQueuedRequestToNextStep(queuedInputId);
|
|
1797
1679
|
} catch {
|
|
1798
1680
|
return null;
|
|
1799
1681
|
}
|
|
@@ -1964,6 +1846,40 @@ function createUnavailableAiExecutionMetadataEvent(params) {
|
|
|
1964
1846
|
};
|
|
1965
1847
|
}
|
|
1966
1848
|
//#endregion
|
|
1849
|
+
//#region src/utils/agent-run-metadata.utils.ts
|
|
1850
|
+
const AGENT_RUN_MESSAGE_RUN_SPEC_METADATA_KEY = "run_spec";
|
|
1851
|
+
const LEGACY_RUN_METADATA_KEYS = [
|
|
1852
|
+
"account_id",
|
|
1853
|
+
"agent_id",
|
|
1854
|
+
"chat_id",
|
|
1855
|
+
"preferred_model",
|
|
1856
|
+
"project_root",
|
|
1857
|
+
"runtime",
|
|
1858
|
+
"sender_id",
|
|
1859
|
+
"session_key",
|
|
1860
|
+
"session_type"
|
|
1861
|
+
];
|
|
1862
|
+
function stripLegacyRunMetadata(metadata) {
|
|
1863
|
+
const nextMetadata = structuredClone(metadata);
|
|
1864
|
+
for (const key of LEGACY_RUN_METADATA_KEYS) delete nextMetadata[key];
|
|
1865
|
+
return nextMetadata;
|
|
1866
|
+
}
|
|
1867
|
+
function buildRunMetadata(params) {
|
|
1868
|
+
const { message, metadata, route } = params;
|
|
1869
|
+
return {
|
|
1870
|
+
...stripLegacyRunMetadata({
|
|
1871
|
+
...message.metadata ?? {},
|
|
1872
|
+
...metadata ?? {}
|
|
1873
|
+
}),
|
|
1874
|
+
channel: message.channel,
|
|
1875
|
+
chatId: message.chatId,
|
|
1876
|
+
accountId: route.accountId,
|
|
1877
|
+
agentId: route.agentId,
|
|
1878
|
+
sessionKey: route.sessionKey,
|
|
1879
|
+
senderId: message.senderId
|
|
1880
|
+
};
|
|
1881
|
+
}
|
|
1882
|
+
//#endregion
|
|
1967
1883
|
//#region src/utils/agent-run-request.utils.ts
|
|
1968
1884
|
function readOptionalString$12(value) {
|
|
1969
1885
|
if (typeof value !== "string") return;
|
|
@@ -2101,6 +2017,7 @@ function resolveRunSpec(params) {
|
|
|
2101
2017
|
agentId: session.agentId ?? request.agentId ?? defaultAgentId,
|
|
2102
2018
|
model,
|
|
2103
2019
|
requestedModel: request.model ?? null,
|
|
2020
|
+
maxToolIterations: params.maxToolIterations,
|
|
2104
2021
|
maxTokens: request.maxTokens ?? modelMaxTokens,
|
|
2105
2022
|
thinkingEffort: request.thinkingEffort ?? session.thinkingEffort ?? null,
|
|
2106
2023
|
correlationId: request.correlationId
|
|
@@ -2120,6 +2037,7 @@ function attachRunSpecMetadata(params) {
|
|
|
2120
2037
|
model: spec.model,
|
|
2121
2038
|
modelSource,
|
|
2122
2039
|
requestedModel: request.model ?? null,
|
|
2040
|
+
maxToolIterations: spec.maxToolIterations,
|
|
2123
2041
|
maxTokens: spec.maxTokens,
|
|
2124
2042
|
thinkingEffort: spec.thinkingEffort,
|
|
2125
2043
|
projectRoot: request.projectRoot ?? session.projectRoot ?? null,
|
|
@@ -2341,16 +2259,31 @@ function createIngressRunTriggerInput(params) {
|
|
|
2341
2259
|
}
|
|
2342
2260
|
function resolveRunTriggerMetadata(params) {
|
|
2343
2261
|
const { request, spec, startedAt } = params;
|
|
2262
|
+
return resolveTargetRunTriggerMetadata({
|
|
2263
|
+
request,
|
|
2264
|
+
targetRunId: spec.runId,
|
|
2265
|
+
fallbackTriggeredAt: startedAt
|
|
2266
|
+
});
|
|
2267
|
+
}
|
|
2268
|
+
function resolveSteeringRunTriggerMetadata(params) {
|
|
2269
|
+
return resolveTargetRunTriggerMetadata({
|
|
2270
|
+
request: params.request,
|
|
2271
|
+
targetRunId: params.targetRunId,
|
|
2272
|
+
fallbackTriggeredAt: params.acceptedAt
|
|
2273
|
+
});
|
|
2274
|
+
}
|
|
2275
|
+
function resolveTargetRunTriggerMetadata(params) {
|
|
2276
|
+
const { request } = params;
|
|
2344
2277
|
const input = request.trigger ?? createIngressRunTriggerInput({
|
|
2345
2278
|
request,
|
|
2346
2279
|
source: "internal"
|
|
2347
2280
|
});
|
|
2348
|
-
const triggeredAt = Number.isFinite(Date.parse(input.triggeredAt)) ? new Date(input.triggeredAt).toISOString() :
|
|
2281
|
+
const triggeredAt = Number.isFinite(Date.parse(input.triggeredAt)) ? new Date(input.triggeredAt).toISOString() : params.fallbackTriggeredAt;
|
|
2349
2282
|
return {
|
|
2350
2283
|
version: 1,
|
|
2351
2284
|
...structuredClone(input),
|
|
2352
2285
|
triggeredAt,
|
|
2353
|
-
targetRunId:
|
|
2286
|
+
targetRunId: params.targetRunId
|
|
2354
2287
|
};
|
|
2355
2288
|
}
|
|
2356
2289
|
function createRunTriggerMetadataEvent(params) {
|
|
@@ -2383,7 +2316,7 @@ var AgentRunRequestManager = class {
|
|
|
2383
2316
|
runtimeRuns;
|
|
2384
2317
|
pendingInputs;
|
|
2385
2318
|
started = false;
|
|
2386
|
-
constructor(agentRuntimeManager, agentManager, configManager, agentContextWindowManager, eventBus, ingress, sessionManager, sessionRunManager, diagnostics) {
|
|
2319
|
+
constructor(agentRuntimeManager, agentManager, configManager, agentContextWindowManager, eventBus, ingress, sessionManager, sessionRunManager, diagnostics, executionClaims) {
|
|
2387
2320
|
this.agentRuntimeManager = agentRuntimeManager;
|
|
2388
2321
|
this.agentManager = agentManager;
|
|
2389
2322
|
this.configManager = configManager;
|
|
@@ -2393,6 +2326,7 @@ var AgentRunRequestManager = class {
|
|
|
2393
2326
|
this.sessionManager = sessionManager;
|
|
2394
2327
|
this.sessionRunManager = sessionRunManager;
|
|
2395
2328
|
this.diagnostics = diagnostics;
|
|
2329
|
+
this.executionClaims = executionClaims;
|
|
2396
2330
|
this.pendingInputs = new AgentRunInputDeliveryService(agentRuntimeManager, sessionManager, sessionRunManager, this.publishRunQueueUpdated);
|
|
2397
2331
|
this.idempotency = new AgentRunRequestIdempotencyService(sessionManager, sessionRunManager);
|
|
2398
2332
|
this.runtimeRuns = new AgentRuntimeRunObserverService({
|
|
@@ -2466,7 +2400,8 @@ var AgentRunRequestManager = class {
|
|
|
2466
2400
|
sessionId: session.sessionId,
|
|
2467
2401
|
message: baseMessage
|
|
2468
2402
|
};
|
|
2469
|
-
const
|
|
2403
|
+
const queuedRequest = sessionRun.enqueueRequest(normalizedRequest, session);
|
|
2404
|
+
const steeringRequest = request.delivery === "prefer-steer" && sessionRun.isRunning() ? this.pendingInputs.promotePreferredSteeringInput(sessionRun, queuedRequest.id, session) : null;
|
|
2470
2405
|
if (steeringRequest) {
|
|
2471
2406
|
this.publishRunQueueUpdated(session.sessionId);
|
|
2472
2407
|
return {
|
|
@@ -2477,7 +2412,6 @@ var AgentRunRequestManager = class {
|
|
|
2477
2412
|
delivery: "steered"
|
|
2478
2413
|
};
|
|
2479
2414
|
}
|
|
2480
|
-
const queuedRequest = sessionRun.enqueueRequest(normalizedRequest, session);
|
|
2481
2415
|
const activeRequest = sessionRun.beginNextRun();
|
|
2482
2416
|
this.publishRunQueueUpdated(session.sessionId);
|
|
2483
2417
|
if (activeRequest?.id === queuedRequest.id) await this.startQueuedRun(sessionRun, activeRequest);
|
|
@@ -2493,20 +2427,17 @@ var AgentRunRequestManager = class {
|
|
|
2493
2427
|
startQueuedRun = async (sessionRun, activeRequest) => {
|
|
2494
2428
|
const { request, session } = activeRequest;
|
|
2495
2429
|
const requestRunStartedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2496
|
-
const
|
|
2497
|
-
const { modelSource, spec } = resolveRunSpec({
|
|
2498
|
-
defaultAgentId: this.agentManager.getDefaultAgentId(),
|
|
2499
|
-
model,
|
|
2500
|
-
modelMaxTokens: this.configManager.getModelMaxTokens(model),
|
|
2501
|
-
request,
|
|
2502
|
-
runId: activeRequest.runId,
|
|
2503
|
-
session
|
|
2504
|
-
});
|
|
2430
|
+
const { modelSource, spec } = this.resolveQueuedRunSpec(activeRequest);
|
|
2505
2431
|
const trigger = resolveRunTriggerMetadata({
|
|
2506
2432
|
request,
|
|
2507
2433
|
spec,
|
|
2508
2434
|
startedAt: requestRunStartedAt
|
|
2509
2435
|
});
|
|
2436
|
+
const executionClaim = await this.claimSessionExecutionOrFail({
|
|
2437
|
+
requestRunStartedAt,
|
|
2438
|
+
sessionRun,
|
|
2439
|
+
spec
|
|
2440
|
+
});
|
|
2510
2441
|
const message = attachRunSpecMetadata({
|
|
2511
2442
|
message: {
|
|
2512
2443
|
...request.message,
|
|
@@ -2550,10 +2481,10 @@ var AgentRunRequestManager = class {
|
|
|
2550
2481
|
spec,
|
|
2551
2482
|
trigger
|
|
2552
2483
|
});
|
|
2553
|
-
await sessionRun.applyEvents([messageSentEvent, triggerEvent]);
|
|
2554
|
-
this.publishNcpEvent(messageSentEvent);
|
|
2555
|
-
this.publishNcpEvent(triggerEvent);
|
|
2556
2484
|
try {
|
|
2485
|
+
await sessionRun.applyEvents([messageSentEvent, triggerEvent]);
|
|
2486
|
+
this.publishNcpEvent(messageSentEvent);
|
|
2487
|
+
this.publishNcpEvent(triggerEvent);
|
|
2557
2488
|
const runtime = this.agentRuntimeManager.getOrCreate({
|
|
2558
2489
|
agentRuntimeId: session.agentRuntimeId,
|
|
2559
2490
|
session,
|
|
@@ -2572,9 +2503,11 @@ var AgentRunRequestManager = class {
|
|
|
2572
2503
|
requestRunStartedAt,
|
|
2573
2504
|
runtime,
|
|
2574
2505
|
spec,
|
|
2575
|
-
parentCorrelationId
|
|
2506
|
+
parentCorrelationId,
|
|
2507
|
+
executionClaim
|
|
2576
2508
|
});
|
|
2577
2509
|
} catch (error) {
|
|
2510
|
+
this.releaseExecutionClaim(executionClaim);
|
|
2578
2511
|
const classification = classifyDiagnosticError(error, activeRequest.signal);
|
|
2579
2512
|
this.diagnostics?.record({
|
|
2580
2513
|
domain: "agent.run",
|
|
@@ -2598,10 +2531,54 @@ var AgentRunRequestManager = class {
|
|
|
2598
2531
|
throw error;
|
|
2599
2532
|
}
|
|
2600
2533
|
};
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2534
|
+
resolveQueuedRunSpec = (activeRequest) => {
|
|
2535
|
+
const { request, session } = activeRequest;
|
|
2536
|
+
const model = request.model ?? session.model ?? this.configManager.getDefaultModel();
|
|
2537
|
+
const defaultAgentId = this.agentManager.getDefaultAgentId();
|
|
2538
|
+
const agentId = session.agentId ?? request.agentId ?? defaultAgentId;
|
|
2539
|
+
const maxToolIterations = this.agentManager.resolveAgentProfileForRun({
|
|
2540
|
+
agentId,
|
|
2541
|
+
requestMetadata: request.metadata,
|
|
2542
|
+
storedAgentId: session.agentId
|
|
2543
|
+
}).maxToolIterations;
|
|
2544
|
+
return resolveRunSpec({
|
|
2545
|
+
defaultAgentId,
|
|
2546
|
+
model,
|
|
2547
|
+
modelMaxTokens: this.configManager.getModelMaxTokens(model),
|
|
2548
|
+
maxToolIterations,
|
|
2549
|
+
request,
|
|
2550
|
+
runId: activeRequest.runId,
|
|
2551
|
+
session
|
|
2552
|
+
});
|
|
2553
|
+
};
|
|
2554
|
+
claimSessionExecutionOrFail = async (params) => {
|
|
2555
|
+
const { requestRunStartedAt, sessionRun, spec } = params;
|
|
2556
|
+
const acquired = this.executionClaims?.tryAcquire(`session:${sessionRun.sessionId}`);
|
|
2557
|
+
if (!acquired || acquired.acquired) return acquired?.claim;
|
|
2558
|
+
const error = /* @__PURE__ */ new Error(`Session already has an active run owned by another NextClaw process: ${sessionRun.sessionId}`);
|
|
2559
|
+
await this.publishRunStartupFailure({
|
|
2560
|
+
error,
|
|
2561
|
+
requestRunStartedAt,
|
|
2562
|
+
sessionRun,
|
|
2563
|
+
spec
|
|
2564
|
+
});
|
|
2565
|
+
this.startNextQueuedRun(sessionRun);
|
|
2566
|
+
throw error;
|
|
2567
|
+
};
|
|
2568
|
+
startRuntimeRun = (params) => {
|
|
2569
|
+
const { executionClaim, ...runtimeParams } = params;
|
|
2570
|
+
this.runtimeRuns.start({
|
|
2571
|
+
...runtimeParams,
|
|
2572
|
+
onSettled: (sessionRun) => {
|
|
2573
|
+
this.releaseExecutionClaim(executionClaim);
|
|
2574
|
+
this.startNextQueuedRun(sessionRun);
|
|
2575
|
+
}
|
|
2576
|
+
});
|
|
2577
|
+
};
|
|
2578
|
+
releaseExecutionClaim = (claim) => {
|
|
2579
|
+
if (!claim) return;
|
|
2580
|
+
claim.release();
|
|
2581
|
+
};
|
|
2605
2582
|
publishRunStartupFailure = async (params) => {
|
|
2606
2583
|
const { error, requestRunStartedAt, sessionRun, spec } = params;
|
|
2607
2584
|
const metadataEvent = createUnavailableAiExecutionMetadataEvent({
|
|
@@ -3793,25 +3770,40 @@ var AppPackageManager = class {
|
|
|
3793
3770
|
throw error;
|
|
3794
3771
|
}
|
|
3795
3772
|
};
|
|
3796
|
-
listActiveComponentSources = async () =>
|
|
3773
|
+
listActiveComponentSources = async () => (await this.listActiveComponentSourcesWithDiagnostics()).sources;
|
|
3774
|
+
listActiveComponentSourcesWithDiagnostics = async () => {
|
|
3797
3775
|
const records = await this.registryService.listApps();
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3776
|
+
const results = await Promise.all(records.filter((record) => record.enabled).map(async (record) => {
|
|
3777
|
+
try {
|
|
3778
|
+
await this.installationService.assertVersionIntegrity(record.appId, record.activeVersion);
|
|
3779
|
+
const version = record.installedVersions[record.activeVersion];
|
|
3780
|
+
if (!version || version.manifestSchemaVersion !== 2) return { sources: [] };
|
|
3781
|
+
return { sources: (version.components ?? []).map((component) => ({
|
|
3782
|
+
kind: component.kind,
|
|
3783
|
+
id: component.id,
|
|
3784
|
+
packageId: record.appId,
|
|
3785
|
+
packageVersion: record.activeVersion,
|
|
3786
|
+
sourcePath: component.componentDirectory,
|
|
3787
|
+
manifestPath: component.manifestPath,
|
|
3788
|
+
dataDirectory: record.dataDirectory,
|
|
3789
|
+
instanceId: record.defaultInstance.id,
|
|
3790
|
+
storage: record.defaultInstance.storage,
|
|
3791
|
+
...this.resolveSecurity(version, record.appId)
|
|
3792
|
+
})) };
|
|
3793
|
+
} catch (error) {
|
|
3794
|
+
return {
|
|
3795
|
+
sources: [],
|
|
3796
|
+
unavailablePackage: {
|
|
3797
|
+
appId: record.appId,
|
|
3798
|
+
message: error instanceof Error ? error.message : String(error)
|
|
3799
|
+
}
|
|
3800
|
+
};
|
|
3801
|
+
}
|
|
3802
|
+
}));
|
|
3803
|
+
return {
|
|
3804
|
+
sources: results.flatMap((result) => result.sources),
|
|
3805
|
+
unavailablePackages: results.flatMap((result) => result.unavailablePackage ?? [])
|
|
3806
|
+
};
|
|
3815
3807
|
};
|
|
3816
3808
|
listOperations = async () => await this.operationManager.list();
|
|
3817
3809
|
startOperation = async (input) => {
|
|
@@ -8034,6 +8026,26 @@ function isMissingFileError$2(error) {
|
|
|
8034
8026
|
return isRecord$13(error) && error.code === "ENOENT";
|
|
8035
8027
|
}
|
|
8036
8028
|
//#endregion
|
|
8029
|
+
//#region src/utils/ncp-message-bridge.utils.ts
|
|
8030
|
+
function normalizeString$1(value) {
|
|
8031
|
+
if (typeof value !== "string") return null;
|
|
8032
|
+
const trimmed = value.trim();
|
|
8033
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
8034
|
+
}
|
|
8035
|
+
function ensureIsoTimestamp(value, fallback) {
|
|
8036
|
+
if (typeof value !== "string") return fallback;
|
|
8037
|
+
const timestamp = Date.parse(value);
|
|
8038
|
+
if (!Number.isFinite(timestamp)) return fallback;
|
|
8039
|
+
return new Date(timestamp).toISOString();
|
|
8040
|
+
}
|
|
8041
|
+
function extractTextFromNcpMessage(message) {
|
|
8042
|
+
if (!message) return "";
|
|
8043
|
+
return (message.role === "assistant" ? sanitizeAssistantReplyTags(message) : message).parts.filter(isTextLikePart).map((part) => part.text).join("");
|
|
8044
|
+
}
|
|
8045
|
+
function isTextLikePart(part) {
|
|
8046
|
+
return part.type === "text" || part.type === "rich-text";
|
|
8047
|
+
}
|
|
8048
|
+
//#endregion
|
|
8037
8049
|
//#region src/services/agent-run-client.service.ts
|
|
8038
8050
|
function readEventCorrelationId(event) {
|
|
8039
8051
|
if (!("payload" in event)) return;
|
|
@@ -9158,7 +9170,8 @@ var PanelAppManager = class {
|
|
|
9158
9170
|
return {
|
|
9159
9171
|
workspacePath,
|
|
9160
9172
|
panelsPath,
|
|
9161
|
-
entries: (await Promise.all(sources.map(({ source, packageSource }) => this.entryPresenter.build(source, appState.apps[encodePanelAppId(source.sourceName)] ?? {}, packageSource, appState.mainSidebarAppIds)))).sort(this.entryPresenter.compare)
|
|
9173
|
+
entries: (await Promise.all(sources.map(({ source, packageSource }) => this.entryPresenter.build(source, appState.apps[encodePanelAppId(source.sourceName)] ?? {}, packageSource, appState.mainSidebarAppIds)))).sort(this.entryPresenter.compare),
|
|
9174
|
+
unavailablePackages: await this.params.listPackageComponentDiagnostics?.() ?? []
|
|
9162
9175
|
};
|
|
9163
9176
|
};
|
|
9164
9177
|
getPanelAppContent = async (id, sourcePath) => {
|
|
@@ -9489,13 +9502,31 @@ var SessionPendingInputs = class {
|
|
|
9489
9502
|
intendedRunId
|
|
9490
9503
|
});
|
|
9491
9504
|
};
|
|
9492
|
-
moveNextRunToNextStep = (requestId, intendedRunId) => {
|
|
9505
|
+
moveNextRunToNextStep = (requestId, intendedRunId, activeRunSpec) => {
|
|
9493
9506
|
const index = this.nextRun.findIndex(({ id }) => id === requestId);
|
|
9494
9507
|
if (index < 0) return null;
|
|
9495
9508
|
const [request] = this.nextRun.splice(index, 1);
|
|
9496
9509
|
if (!request) return null;
|
|
9497
|
-
|
|
9498
|
-
|
|
9510
|
+
const steeringRequest = {
|
|
9511
|
+
...request,
|
|
9512
|
+
request: {
|
|
9513
|
+
...request.request,
|
|
9514
|
+
message: {
|
|
9515
|
+
...request.request.message,
|
|
9516
|
+
metadata: {
|
|
9517
|
+
...request.request.message.metadata ?? {},
|
|
9518
|
+
...activeRunSpec ? { [AGENT_RUN_MESSAGE_RUN_SPEC_METADATA_KEY]: structuredClone(activeRunSpec) } : {},
|
|
9519
|
+
[NCP_RUN_TRIGGER_METADATA_KEY]: resolveSteeringRunTriggerMetadata({
|
|
9520
|
+
request: request.request,
|
|
9521
|
+
targetRunId: intendedRunId,
|
|
9522
|
+
acceptedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
9523
|
+
})
|
|
9524
|
+
}
|
|
9525
|
+
}
|
|
9526
|
+
}
|
|
9527
|
+
};
|
|
9528
|
+
this.enqueueNextStep(steeringRequest, intendedRunId);
|
|
9529
|
+
return this.toPendingRequest(steeringRequest, "steering", intendedRunId);
|
|
9499
9530
|
};
|
|
9500
9531
|
list = () => [...this.nextStep.map((request) => this.toPendingRequest(request, "steering", request.intendedRunId)), ...this.nextRun.map((request) => this.toPendingRequest(request, "queued", null))];
|
|
9501
9532
|
listNextRun = () => structuredClone(this.nextRun);
|
|
@@ -9547,6 +9578,13 @@ var SessionPendingInputs = class {
|
|
|
9547
9578
|
function isConversationStateEvent(event) {
|
|
9548
9579
|
return event.type !== NcpEventType.ContextWindowUpdated;
|
|
9549
9580
|
}
|
|
9581
|
+
function findRunSpec(messages, runId) {
|
|
9582
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
9583
|
+
const runSpec = messages[index]?.metadata?.[AGENT_RUN_MESSAGE_RUN_SPEC_METADATA_KEY];
|
|
9584
|
+
if (runSpec && typeof runSpec === "object" && !Array.isArray(runSpec) && runSpec.runId === runId) return runSpec;
|
|
9585
|
+
}
|
|
9586
|
+
return null;
|
|
9587
|
+
}
|
|
9550
9588
|
var SessionRun = class {
|
|
9551
9589
|
sessionId;
|
|
9552
9590
|
statusListeners = /* @__PURE__ */ new Set();
|
|
@@ -9608,23 +9646,7 @@ var SessionRun = class {
|
|
|
9608
9646
|
};
|
|
9609
9647
|
moveQueuedRequestToNextStep = (queuedRequestId) => {
|
|
9610
9648
|
if (!this.activeRunId) return null;
|
|
9611
|
-
return this.pendingInputs.moveNextRunToNextStep(queuedRequestId, this.activeRunId);
|
|
9612
|
-
};
|
|
9613
|
-
enqueueNextStepRequest = (request, session) => {
|
|
9614
|
-
if (!this.activeRunId) return null;
|
|
9615
|
-
const pendingRequest = {
|
|
9616
|
-
id: `pending-input-${randomUUID()}`,
|
|
9617
|
-
runId: `agent-run-${randomUUID()}`,
|
|
9618
|
-
enqueuedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9619
|
-
request: structuredClone(request),
|
|
9620
|
-
session: structuredClone(session)
|
|
9621
|
-
};
|
|
9622
|
-
this.pendingInputs.enqueueNextStep(pendingRequest, this.activeRunId);
|
|
9623
|
-
return structuredClone({
|
|
9624
|
-
...pendingRequest,
|
|
9625
|
-
placement: "steering",
|
|
9626
|
-
intendedRunId: this.activeRunId
|
|
9627
|
-
});
|
|
9649
|
+
return this.pendingInputs.moveNextRunToNextStep(queuedRequestId, this.activeRunId, findRunSpec(this.getSnapshot().messages, this.activeRunId));
|
|
9628
9650
|
};
|
|
9629
9651
|
claimNextStepRequests = (runId) => this.pendingInputs.claimNextStep(runId).map((request) => ({
|
|
9630
9652
|
...request,
|
|
@@ -17647,6 +17669,13 @@ var SessionManager = class {
|
|
|
17647
17669
|
const summaryReadOptions = !peerId && limit !== void 0 ? { limit } : void 0;
|
|
17648
17670
|
return applyLimit((await journalStore.listSessionSummaries(summaryReadOptions)).filter((summary) => !peerId || summary.peerId === peerId).map(this.workingDirResolver.withWorkingDir), limit);
|
|
17649
17671
|
};
|
|
17672
|
+
listSessionPage = async (options) => {
|
|
17673
|
+
const result = await this.options.journalStore.listSessionSummaryPage(options);
|
|
17674
|
+
return {
|
|
17675
|
+
...result,
|
|
17676
|
+
sessions: result.sessions.map(this.workingDirResolver.withWorkingDir)
|
|
17677
|
+
};
|
|
17678
|
+
};
|
|
17650
17679
|
listSessionMessages = async (sessionId, options) => {
|
|
17651
17680
|
const { cursor, limit } = options ?? {};
|
|
17652
17681
|
const normalizedSessionId = normalizeSessionId(sessionId);
|
|
@@ -18890,6 +18919,28 @@ const SQLITE_DATABASE_FILE = ".ncp-agent-session-catalog.sqlite";
|
|
|
18890
18919
|
const CATALOG_SCHEMA_VERSION = 1;
|
|
18891
18920
|
const MIGRATION_STATUS_KEY = "migration_status";
|
|
18892
18921
|
const MIGRATION_COMPLETE = "complete";
|
|
18922
|
+
function buildCatalogFilter(query) {
|
|
18923
|
+
const normalized = query?.trim().toLocaleLowerCase();
|
|
18924
|
+
if (!normalized) return {
|
|
18925
|
+
sql: "deleted_at IS NULL",
|
|
18926
|
+
params: []
|
|
18927
|
+
};
|
|
18928
|
+
const pattern = `%${normalized.replace(/[\\%_]/g, "\\$&")}%`;
|
|
18929
|
+
return {
|
|
18930
|
+
sql: `deleted_at IS NULL AND (
|
|
18931
|
+
LOWER(session_id) LIKE ? ESCAPE '\\' OR
|
|
18932
|
+
LOWER(COALESCE(peer_id, '')) LIKE ? ESCAPE '\\' OR
|
|
18933
|
+
LOWER(COALESCE(agent_id, '')) LIKE ? ESCAPE '\\' OR
|
|
18934
|
+
LOWER(metadata_json) LIKE ? ESCAPE '\\'
|
|
18935
|
+
)`,
|
|
18936
|
+
params: [
|
|
18937
|
+
pattern,
|
|
18938
|
+
pattern,
|
|
18939
|
+
pattern,
|
|
18940
|
+
pattern
|
|
18941
|
+
]
|
|
18942
|
+
};
|
|
18943
|
+
}
|
|
18893
18944
|
function readEventMessage(event) {
|
|
18894
18945
|
if (event.type === NcpEventType.MessageSent || event.type === NcpEventType.MessageCompleted || event.type === "session.snapshot.message") return event.payload.message;
|
|
18895
18946
|
}
|
|
@@ -18938,11 +18989,25 @@ var NcpAgentSessionSummaryIndexStore = class {
|
|
|
18938
18989
|
const row = this.db().prepare("SELECT * FROM sessions WHERE session_id = ? AND deleted_at IS NULL LIMIT 1").get(normalizeNcpSessionId(sessionId));
|
|
18939
18990
|
return row ? structuredClone(rowToSummary(row)) : null;
|
|
18940
18991
|
};
|
|
18941
|
-
list = async () => {
|
|
18992
|
+
list = async (limit) => {
|
|
18942
18993
|
await this.ensureReady();
|
|
18994
|
+
const query = `SELECT * FROM sessions
|
|
18995
|
+
WHERE deleted_at IS NULL
|
|
18996
|
+
ORDER BY COALESCE(last_message_at, created_at, updated_at) DESC, session_id DESC`;
|
|
18997
|
+
return (limit === void 0 ? this.db().prepare(query).all() : this.db().prepare(`${query} LIMIT ?`).all(limit)).map((row) => structuredClone(rowToSummary(row)));
|
|
18998
|
+
};
|
|
18999
|
+
listPage = async (options) => {
|
|
19000
|
+
await this.ensureReady();
|
|
19001
|
+
const filter = buildCatalogFilter(options.query);
|
|
18943
19002
|
return this.db().prepare(`SELECT * FROM sessions
|
|
18944
|
-
WHERE
|
|
18945
|
-
ORDER BY COALESCE(last_message_at, created_at, updated_at) DESC, session_id DESC
|
|
19003
|
+
WHERE ${filter.sql}
|
|
19004
|
+
ORDER BY COALESCE(last_message_at, created_at, updated_at) DESC, session_id DESC
|
|
19005
|
+
LIMIT ? OFFSET ?`).all(...filter.params, options.limit, options.offset).map((row) => structuredClone(rowToSummary(row)));
|
|
19006
|
+
};
|
|
19007
|
+
count = async (query) => {
|
|
19008
|
+
await this.ensureReady();
|
|
19009
|
+
const filter = buildCatalogFilter(query);
|
|
19010
|
+
return this.db().prepare(`SELECT COUNT(*) AS total FROM sessions WHERE ${filter.sql}`).get(...filter.params).total;
|
|
18946
19011
|
};
|
|
18947
19012
|
upsert = async (summary) => {
|
|
18948
19013
|
await this.ensureReady();
|
|
@@ -19119,11 +19184,25 @@ var NcpAgentSessionSummaryReadStore = class {
|
|
|
19119
19184
|
this.options = options;
|
|
19120
19185
|
}
|
|
19121
19186
|
list = async (limit) => {
|
|
19122
|
-
const
|
|
19123
|
-
|
|
19187
|
+
const normalizedLimit = limit === void 0 || limit === Number.POSITIVE_INFINITY ? void 0 : Math.max(0, Math.trunc(limit));
|
|
19188
|
+
const summaries = await this.options.summaryIndex.list(normalizedLimit);
|
|
19189
|
+
return await mapWithConcurrency(normalizedLimit === void 0 ? summaries : summaries.slice(0, normalizedLimit), this.withMetadata);
|
|
19190
|
+
};
|
|
19191
|
+
listPage = async (options) => {
|
|
19192
|
+
const page = Math.max(1, Math.trunc(options.page));
|
|
19193
|
+
const pageSize = Math.max(1, Math.trunc(options.pageSize));
|
|
19194
|
+
const [summaries, total] = await Promise.all([this.options.summaryIndex.listPage({
|
|
19195
|
+
offset: (page - 1) * pageSize,
|
|
19196
|
+
limit: pageSize,
|
|
19197
|
+
...options.query?.trim() ? { query: options.query.trim() } : {}
|
|
19198
|
+
}), this.options.summaryIndex.count(options.query)]);
|
|
19199
|
+
return {
|
|
19200
|
+
sessions: await mapWithConcurrency(summaries, this.withMetadata),
|
|
19201
|
+
total
|
|
19202
|
+
};
|
|
19124
19203
|
};
|
|
19125
19204
|
get = async (sessionId) => {
|
|
19126
|
-
const indexed = await this.options.
|
|
19205
|
+
const indexed = await this.options.summaryIndex.get(sessionId);
|
|
19127
19206
|
if (indexed) return await this.withMetadata(indexed);
|
|
19128
19207
|
const messageCount = await this.options.readProjectedMessageCount(sessionId);
|
|
19129
19208
|
if (messageCount === null) return null;
|
|
@@ -19196,8 +19275,7 @@ var NcpAgentSessionJournalStore = class {
|
|
|
19196
19275
|
}
|
|
19197
19276
|
});
|
|
19198
19277
|
this.summaryReadStore = new NcpAgentSessionSummaryReadStore({
|
|
19199
|
-
|
|
19200
|
-
listIndexedSummaries: () => this.summaryIndexStore.list(),
|
|
19278
|
+
summaryIndex: this.summaryIndexStore,
|
|
19201
19279
|
readJournalModifiedAt: async (sessionId) => (await stat(this.sessionPath(sessionId))).mtime.toISOString(),
|
|
19202
19280
|
readMetadata: (sessionId, fallback) => this.metadataStore.read(sessionId, fallback),
|
|
19203
19281
|
readProjectedMessageCount: async (sessionId) => (await this.messageProjectionStore.readMeta(sessionId))?.total ?? null
|
|
@@ -19228,6 +19306,7 @@ var NcpAgentSessionJournalStore = class {
|
|
|
19228
19306
|
listSessionSummaries = async (options) => {
|
|
19229
19307
|
return await this.summaryReadStore.list(options?.limit);
|
|
19230
19308
|
};
|
|
19309
|
+
listSessionSummaryPage = (options) => this.summaryReadStore.listPage(options);
|
|
19231
19310
|
getSessionSummary = async (sessionId) => {
|
|
19232
19311
|
const normalizedSessionId = normalizeNcpSessionId(sessionId);
|
|
19233
19312
|
if (!normalizedSessionId) return null;
|
|
@@ -19579,7 +19658,7 @@ var NextclawKernel = class {
|
|
|
19579
19658
|
this.assetStore = new LocalAssetStore({ rootDir: resolve(getDataDir(), "assets") });
|
|
19580
19659
|
this.control = new NextclawKernelControlManager();
|
|
19581
19660
|
this.agents = new AgentManager(this.configManager);
|
|
19582
|
-
this.agentContextWindowManager = new AgentContextWindowManager(this.agents, this.contextProviderManager, this.toolProviderManager);
|
|
19661
|
+
this.agentContextWindowManager = new AgentContextWindowManager(this.agents, this.contextProviderManager, this.toolProviderManager, this.assetStore);
|
|
19583
19662
|
this.accessManager = new AccessManager({
|
|
19584
19663
|
configManager: this.configManager,
|
|
19585
19664
|
homeDir: options.homeDir
|
|
@@ -19608,7 +19687,8 @@ var NextclawKernel = class {
|
|
|
19608
19687
|
configManager: this.configManager,
|
|
19609
19688
|
eventBus: this.eventBus,
|
|
19610
19689
|
ingress: this.ingress,
|
|
19611
|
-
listPackageComponentSources: this.appPackageManager.listActiveComponentSources
|
|
19690
|
+
listPackageComponentSources: this.appPackageManager.listActiveComponentSources,
|
|
19691
|
+
listPackageComponentDiagnostics: async () => (await this.appPackageManager.listActiveComponentSourcesWithDiagnostics()).unavailablePackages
|
|
19612
19692
|
});
|
|
19613
19693
|
this.preferenceManager = new PreferenceManager({ storePath: resolveKernelPreferenceStorePath(options) });
|
|
19614
19694
|
({appDataManager: this.appDataManager, serviceAppManager: this.serviceAppManager} = createKernelServiceAppManagers({
|
|
@@ -19646,10 +19726,10 @@ var NextclawKernel = class {
|
|
|
19646
19726
|
ingress: this.ingress
|
|
19647
19727
|
})
|
|
19648
19728
|
});
|
|
19649
|
-
this.contextCompactionManager = new AgentRunContextCompactionManager(this.agents, this.llmProviders);
|
|
19729
|
+
this.contextCompactionManager = new AgentRunContextCompactionManager(this.agents, this.llmProviders, this.assetStore);
|
|
19650
19730
|
this.sessionRunManager = new SessionRunManager(this.sessionManager, options.productActivitySink);
|
|
19651
19731
|
this.sessionContextCompactionManager = new SessionContextCompactionManager(this.agentRuntimeManager, this.eventBus, this.sessionManager, this.sessionRunManager);
|
|
19652
|
-
this.agentRunRequestManager = new AgentRunRequestManager(this.agentRuntimeManager, this.agents, this.configManager, this.agentContextWindowManager, this.eventBus, this.ingress, this.sessionManager, this.sessionRunManager, this.diagnostics);
|
|
19732
|
+
this.agentRunRequestManager = new AgentRunRequestManager(this.agentRuntimeManager, this.agents, this.configManager, this.agentContextWindowManager, this.eventBus, this.ingress, this.sessionManager, this.sessionRunManager, this.diagnostics, new LocalExecutionClaimService(resolve(sessionsDir, ".execution-claims", "session-runs")));
|
|
19653
19733
|
this.contributions = this.createContributions();
|
|
19654
19734
|
}
|
|
19655
19735
|
createContributions = () => [
|