@nextclaw/kernel 0.6.9 → 0.6.11
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 +63 -40
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +652 -120
- package/dist/index.js.map +1 -1
- package/package.json +14 -14
package/dist/index.js
CHANGED
|
@@ -2,15 +2,15 @@ import { AUTOMATIC_UPDATE_CHECK_INTERVAL_MS, getAutomaticUpdateCheckDelay, resol
|
|
|
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
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, EditFileTool, ExecTool, ExtensionChannelAdapter, GatewayTool, InputBudgetPruner, LLMProvider, ListDirTool, LiteLLMProvider, MAX_SESSION_SEARCH_LIMIT, MemoryGetTool, MemorySearchTool, MemoryStore, MessageBus, MessageTool, 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, 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, resolveSessionProjectContext, resolveSessionWorkspacePath, resolveThinkingLevel, safeFilename, sanitizeOutboundAssistantContent, saveConfig, summarizeSessionRequestTask, toExtensionConfigView, updateAgentProfile } from "@nextclaw/core";
|
|
5
|
-
import { NcpEventType, normalizeAssistantText, sanitizeAssistantReplyTags } from "@nextclaw/ncp";
|
|
5
|
+
import { NCP_AI_EXECUTION_METADATA_KEY, NcpEventType, createUnavailableNcpAiExecutionMetadata, normalizeAssistantText, readNcpAiExecutionMetadata, sanitizeAssistantReplyTags } from "@nextclaw/ncp";
|
|
6
6
|
import { LocalAssetStore, buildAssetContentPath, buildNcpUserContent, buildOpenAiFunctionTool, ncpMessageToOpenAiMessages, validateToolArgs } from "@nextclaw/ncp-agent-runtime";
|
|
7
7
|
import { createHash, createHmac, randomBytes, randomUUID, scryptSync, timingSafeEqual } from "node:crypto";
|
|
8
|
-
import { CHAT_INLINE_TOKENS_METADATA_KEY, CHAT_SESSION_MATERIALIZATION_METADATA_KEY, CHAT_WORKSPACE_DIRECTORY_TOKEN_KIND, CHAT_WORKSPACE_FILE_TOKEN_KIND, EventBus, Ingress, eventKeys, ingressKeys, isRuntimeDefaultModelValue, normalizeRuntimeModelSelectionMode } from "@nextclaw/shared";
|
|
8
|
+
import { CHAT_INLINE_TOKENS_METADATA_KEY, CHAT_SESSION_MATERIALIZATION_METADATA_KEY, CHAT_WORKSPACE_DIRECTORY_TOKEN_KIND, CHAT_WORKSPACE_FILE_TOKEN_KIND, EventBus, Ingress, PANEL_APP_INLINE_HOST_CONTRACT, eventKeys, ingressKeys, isRuntimeDefaultModelValue, normalizeRuntimeModelSelectionMode, readInlineContentHeight } from "@nextclaw/shared";
|
|
9
9
|
import { catchError, from, lastValueFrom, tap } from "rxjs";
|
|
10
10
|
import { appendFileSync, chmodSync, constants, existsSync, mkdirSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
11
11
|
import { basename, delimiter, dirname, extname, isAbsolute, join, normalize, relative, resolve, sep } from "node:path";
|
|
12
12
|
import { execFileSync, spawn } from "node:child_process";
|
|
13
|
-
import { access, appendFile, mkdir, open, readFile, readdir, realpath, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
|
|
13
|
+
import { access, appendFile, mkdir, mkdtemp, open, readFile, readdir, realpath, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
|
|
14
14
|
import { fileURLToPath } from "node:url";
|
|
15
15
|
import { BUILTIN_PROVIDER_PLUGINS } from "@nextclaw/runtime";
|
|
16
16
|
import { McpRegistryService, McpServerLifecycleManager } from "@nextclaw/mcp";
|
|
@@ -658,6 +658,32 @@ const AGENT_RUN_EXECUTION_METADATA = {
|
|
|
658
658
|
}
|
|
659
659
|
}
|
|
660
660
|
};
|
|
661
|
+
function readAgentRunStartedAt(event, fallback) {
|
|
662
|
+
if (event.type !== NcpEventType.RunStarted) return fallback;
|
|
663
|
+
return event.payload.startedAt ?? event.occurredAt ?? fallback;
|
|
664
|
+
}
|
|
665
|
+
function hasAiExecutionMetadata(event) {
|
|
666
|
+
return event.type === NcpEventType.RunMetadata && Boolean(readNcpAiExecutionMetadata(event.payload.metadata));
|
|
667
|
+
}
|
|
668
|
+
function createUnavailableAiExecutionMetadataEvent(params) {
|
|
669
|
+
const { sessionId, spec } = params;
|
|
670
|
+
return {
|
|
671
|
+
occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
672
|
+
type: NcpEventType.RunMetadata,
|
|
673
|
+
payload: {
|
|
674
|
+
runId: spec.runId,
|
|
675
|
+
sessionId,
|
|
676
|
+
correlationId: spec.correlationId,
|
|
677
|
+
metadata: { [NCP_AI_EXECUTION_METADATA_KEY]: createUnavailableNcpAiExecutionMetadata({
|
|
678
|
+
runId: spec.runId,
|
|
679
|
+
runtimeId: spec.runtimeId,
|
|
680
|
+
model: spec.model,
|
|
681
|
+
requestedModel: spec.requestedModel,
|
|
682
|
+
outcome: "failed"
|
|
683
|
+
}) }
|
|
684
|
+
}
|
|
685
|
+
};
|
|
686
|
+
}
|
|
661
687
|
//#endregion
|
|
662
688
|
//#region src/managers/agent-run-request.manager.ts
|
|
663
689
|
function toAgentRunRequest(envelope) {
|
|
@@ -717,10 +743,6 @@ function readOptionalString$11(value) {
|
|
|
717
743
|
if (typeof value !== "string") return;
|
|
718
744
|
return value.trim() || void 0;
|
|
719
745
|
}
|
|
720
|
-
function readRunStartedAt(event, fallback) {
|
|
721
|
-
if (event.type !== NcpEventType.RunStarted) return fallback;
|
|
722
|
-
return event.payload.startedAt ?? event.occurredAt ?? fallback;
|
|
723
|
-
}
|
|
724
746
|
function createCompletedAssistantMessageEvent(params) {
|
|
725
747
|
return {
|
|
726
748
|
occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -781,12 +803,15 @@ function resolveRunSpec(params) {
|
|
|
781
803
|
const { agentManager, configManager, request, runId, session } = params;
|
|
782
804
|
const modelSource = request.model !== void 0 ? "request" : session.model !== void 0 ? "session" : "default";
|
|
783
805
|
const model = request.model ?? session.model ?? configManager.getDefaultModel();
|
|
806
|
+
const agentId = request.agentId ?? session.agentId ?? agentManager.getDefaultAgentId();
|
|
784
807
|
return {
|
|
785
808
|
modelSource,
|
|
786
809
|
spec: {
|
|
787
810
|
runId,
|
|
788
|
-
|
|
811
|
+
runtimeId: session.agentRuntimeId,
|
|
812
|
+
agentId,
|
|
789
813
|
model,
|
|
814
|
+
requestedModel: request.model ?? null,
|
|
790
815
|
maxTokens: request.maxTokens ?? configManager.getModelMaxTokens(model),
|
|
791
816
|
thinkingEffort: request.thinkingEffort ?? session.thinkingEffort ?? null,
|
|
792
817
|
correlationId: request.correlationId
|
|
@@ -921,19 +946,37 @@ var AgentRunRequestManager = class {
|
|
|
921
946
|
});
|
|
922
947
|
const contextBlocks = await this.contextProviderManager.buildContext(providerRequest);
|
|
923
948
|
const tools = await this.toolProviderManager.buildTools(providerRequest);
|
|
949
|
+
this.startRuntimeRun({
|
|
950
|
+
options: {
|
|
951
|
+
contextBlocks,
|
|
952
|
+
session,
|
|
953
|
+
sessionRun,
|
|
954
|
+
signal: activeRun.signal,
|
|
955
|
+
tools
|
|
956
|
+
},
|
|
957
|
+
requestRunStartedAt,
|
|
958
|
+
runtime,
|
|
959
|
+
spec
|
|
960
|
+
});
|
|
961
|
+
return {
|
|
962
|
+
sessionId: session.sessionId,
|
|
963
|
+
userMessageId: message.id,
|
|
964
|
+
runId: spec.runId,
|
|
965
|
+
correlationId: request.correlationId
|
|
966
|
+
};
|
|
967
|
+
};
|
|
968
|
+
startRuntimeRun = (params) => {
|
|
969
|
+
const { options, requestRunStartedAt, runtime, spec } = params;
|
|
970
|
+
const { session, sessionRun } = options;
|
|
924
971
|
let messageCompletedSeen = false;
|
|
972
|
+
let executionMetadataSeen = false;
|
|
925
973
|
let runtimeFailed = false;
|
|
926
974
|
let runStartedAt = requestRunStartedAt;
|
|
927
|
-
lastValueFrom(from(runtime.run(spec, {
|
|
928
|
-
contextBlocks,
|
|
929
|
-
session,
|
|
930
|
-
sessionRun,
|
|
931
|
-
signal: activeRun.signal,
|
|
932
|
-
tools
|
|
933
|
-
})).pipe(tap((event) => {
|
|
975
|
+
lastValueFrom(from(runtime.run(spec, options)).pipe(tap((event) => {
|
|
934
976
|
const eventsToPublish = [];
|
|
935
977
|
if (event.type === NcpEventType.RunError) runtimeFailed = true;
|
|
936
|
-
|
|
978
|
+
if (hasAiExecutionMetadata(event)) executionMetadataSeen = true;
|
|
979
|
+
runStartedAt = readAgentRunStartedAt(event, runStartedAt);
|
|
937
980
|
if (event.type === NcpEventType.MessageCompleted) messageCompletedSeen = true;
|
|
938
981
|
if (event.type === NcpEventType.RunFinished && !messageCompletedSeen) {
|
|
939
982
|
const message = findCompletedAssistantMessage(sessionRun.getSnapshot().messages, event.payload.messageId);
|
|
@@ -952,6 +995,17 @@ var AgentRunRequestManager = class {
|
|
|
952
995
|
});
|
|
953
996
|
}), catchError(async (error) => {
|
|
954
997
|
runtimeFailed = true;
|
|
998
|
+
if (!executionMetadataSeen) {
|
|
999
|
+
const metadataEvent = createUnavailableAiExecutionMetadataEvent({
|
|
1000
|
+
spec,
|
|
1001
|
+
sessionId: session.sessionId
|
|
1002
|
+
});
|
|
1003
|
+
await sessionRun.applyEvents([metadataEvent]);
|
|
1004
|
+
this.eventBus.emit(eventKeys.ncpEvent, metadataEvent, {
|
|
1005
|
+
emittedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1006
|
+
source: "agent-run-request"
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
955
1009
|
const event = createSyntheticRunErrorEvent({
|
|
956
1010
|
error,
|
|
957
1011
|
runId: spec.runId,
|
|
@@ -972,12 +1026,6 @@ var AgentRunRequestManager = class {
|
|
|
972
1026
|
sessionRun
|
|
973
1027
|
}).catch(() => void 0);
|
|
974
1028
|
});
|
|
975
|
-
return {
|
|
976
|
-
sessionId: session.sessionId,
|
|
977
|
-
userMessageId: message.id,
|
|
978
|
-
runId: spec.runId,
|
|
979
|
-
correlationId: request.correlationId
|
|
980
|
-
};
|
|
981
1029
|
};
|
|
982
1030
|
getOrCreateSessionForRequest = async (request) => {
|
|
983
1031
|
const sessionMaterialization = readSessionMaterialization(request.metadata ?? {});
|
|
@@ -1031,14 +1079,24 @@ function normalizeAgentRuntimeSessionTypeIcon(value) {
|
|
|
1031
1079
|
...alt ? { alt } : {}
|
|
1032
1080
|
};
|
|
1033
1081
|
}
|
|
1034
|
-
const BUILTIN_RUNTIME_PRESENTATION = {
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1082
|
+
const BUILTIN_RUNTIME_PRESENTATION = {
|
|
1083
|
+
hermes: {
|
|
1084
|
+
label: "Hermes",
|
|
1085
|
+
icon: {
|
|
1086
|
+
kind: "image",
|
|
1087
|
+
src: "app://runtime-icons/hermes-agent.png",
|
|
1088
|
+
alt: "Hermes"
|
|
1089
|
+
}
|
|
1090
|
+
},
|
|
1091
|
+
opencode: {
|
|
1092
|
+
label: "OpenCode",
|
|
1093
|
+
icon: {
|
|
1094
|
+
kind: "image",
|
|
1095
|
+
src: "app://runtime-icons/opencode.svg",
|
|
1096
|
+
alt: "OpenCode"
|
|
1097
|
+
}
|
|
1040
1098
|
}
|
|
1041
|
-
}
|
|
1099
|
+
};
|
|
1042
1100
|
function readString$7(value) {
|
|
1043
1101
|
if (typeof value !== "string") return;
|
|
1044
1102
|
return value.trim() || void 0;
|
|
@@ -3665,16 +3723,24 @@ function upsertNcpAgentSessionSummaryEvent(params) {
|
|
|
3665
3723
|
status: "idle"
|
|
3666
3724
|
};
|
|
3667
3725
|
}
|
|
3668
|
-
async function replayNcpAgentSessionEvents(events) {
|
|
3726
|
+
async function replayNcpAgentSessionEvents(events, seedMessages = []) {
|
|
3669
3727
|
const stateManager = new DefaultNcpAgentConversationStateManager();
|
|
3670
|
-
|
|
3728
|
+
if (seedMessages.length > 0) stateManager.hydrate({
|
|
3729
|
+
sessionId: seedMessages[0]?.sessionId ?? "",
|
|
3730
|
+
messages: seedMessages
|
|
3731
|
+
});
|
|
3732
|
+
const knownMessageIds = new Set(seedMessages.map((message) => message.id));
|
|
3671
3733
|
const toolResultsByCallId = /* @__PURE__ */ new Map();
|
|
3672
3734
|
for (const event of events) {
|
|
3673
3735
|
if (isJournalOnlyEvent(event)) continue;
|
|
3674
3736
|
const replayEvent = createReplayEvent(event, toolResultsByCallId);
|
|
3675
|
-
const
|
|
3676
|
-
if (
|
|
3677
|
-
|
|
3737
|
+
const bootstrap = createReplayStreamingBootstrapEvent(replayEvent, knownMessageIds);
|
|
3738
|
+
if (bootstrap) {
|
|
3739
|
+
knownMessageIds.add(bootstrap.messageId);
|
|
3740
|
+
await stateManager.dispatch(bootstrap.event);
|
|
3741
|
+
}
|
|
3742
|
+
const replayMessageId = readReplayMessageId(replayEvent);
|
|
3743
|
+
if (replayMessageId) knownMessageIds.add(replayMessageId);
|
|
3678
3744
|
await stateManager.dispatch(replayEvent);
|
|
3679
3745
|
if (replayEvent.type === NcpEventType.MessageToolCallResult) toolResultsByCallId.set(replayEvent.payload.toolCallId, replayEvent.payload);
|
|
3680
3746
|
}
|
|
@@ -3731,26 +3797,27 @@ function readLegacyContextCompactionMessageId(message) {
|
|
|
3731
3797
|
function createReplayStreamingBootstrapEvent(event, knownMessageIds) {
|
|
3732
3798
|
const messageId = readStreamingMessageId(event);
|
|
3733
3799
|
if (!messageId || knownMessageIds.has(messageId)) return null;
|
|
3734
|
-
knownMessageIds.add(messageId);
|
|
3735
3800
|
return {
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
id: messageId,
|
|
3801
|
+
messageId,
|
|
3802
|
+
event: {
|
|
3803
|
+
occurredAt: event.occurredAt,
|
|
3804
|
+
type: NcpEventType.MessageSent,
|
|
3805
|
+
payload: {
|
|
3742
3806
|
sessionId: readEventSessionId$2(event),
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3807
|
+
message: {
|
|
3808
|
+
id: messageId,
|
|
3809
|
+
sessionId: readEventSessionId$2(event),
|
|
3810
|
+
role: "assistant",
|
|
3811
|
+
status: "streaming",
|
|
3812
|
+
parts: [],
|
|
3813
|
+
timestamp: readReplayPayloadTimestamp(event) ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
3814
|
+
}
|
|
3747
3815
|
}
|
|
3748
3816
|
}
|
|
3749
3817
|
};
|
|
3750
3818
|
}
|
|
3751
|
-
function
|
|
3752
|
-
|
|
3753
|
-
if (message?.id) knownMessageIds.add(message.id);
|
|
3819
|
+
function readReplayMessageId(event) {
|
|
3820
|
+
return readMessageFromSummaryEvent(event)?.id ?? null;
|
|
3754
3821
|
}
|
|
3755
3822
|
function readEventSessionId$2(event) {
|
|
3756
3823
|
const sessionId = ("payload" in event && isRecord$11(event.payload) ? event.payload : null)?.sessionId;
|
|
@@ -3805,6 +3872,15 @@ function readMessageFromSummaryEvent(event) {
|
|
|
3805
3872
|
}
|
|
3806
3873
|
//#endregion
|
|
3807
3874
|
//#region src/types/session.types.ts
|
|
3875
|
+
var SessionMessageCursorError = class extends Error {
|
|
3876
|
+
constructor(message = "Invalid session message cursor.") {
|
|
3877
|
+
super(message);
|
|
3878
|
+
this.name = "SessionMessageCursorError";
|
|
3879
|
+
}
|
|
3880
|
+
};
|
|
3881
|
+
function isSessionMessageCursorError(error) {
|
|
3882
|
+
return error instanceof SessionMessageCursorError;
|
|
3883
|
+
}
|
|
3808
3884
|
var SessionSettingsError = class extends Error {
|
|
3809
3885
|
constructor(code, message) {
|
|
3810
3886
|
super(message);
|
|
@@ -4502,13 +4578,40 @@ var SessionManager = class {
|
|
|
4502
4578
|
return applyLimit((await this.options.journalStore.listSessionSummaries()).filter((summary) => !peerId || summary.peerId === peerId).map(this.workingDirResolver.withWorkingDir), options?.limit);
|
|
4503
4579
|
};
|
|
4504
4580
|
listSessionMessages = async (sessionId, options) => {
|
|
4581
|
+
const { cursor, limit } = options ?? {};
|
|
4505
4582
|
const normalizedSessionId = normalizeSessionId(sessionId);
|
|
4506
4583
|
if (!normalizedSessionId) return [];
|
|
4507
|
-
return
|
|
4584
|
+
if (limit !== void 0 || cursor) return (await this.listSessionMessagePage(normalizedSessionId, {
|
|
4585
|
+
limit: limit ?? 200,
|
|
4586
|
+
...cursor ? { cursor } : {}
|
|
4587
|
+
}))?.messages ?? [];
|
|
4588
|
+
return await this.options.journalStore.listSessionMessages(normalizedSessionId);
|
|
4589
|
+
};
|
|
4590
|
+
listSessionMessagePage = async (sessionId, options) => {
|
|
4591
|
+
const { cursor, limit } = options;
|
|
4592
|
+
const normalizedSessionId = normalizeSessionId(sessionId);
|
|
4593
|
+
if (!normalizedSessionId) return null;
|
|
4594
|
+
const page = await this.options.journalStore.listSessionMessagePage({
|
|
4595
|
+
sessionId: normalizedSessionId,
|
|
4596
|
+
limit,
|
|
4597
|
+
...cursor ? { cursor } : {}
|
|
4598
|
+
});
|
|
4599
|
+
if (!page || page.contextWindow) return page;
|
|
4600
|
+
const record = await this.options.journalStore.getSession(normalizedSessionId);
|
|
4601
|
+
if (!record) return page;
|
|
4602
|
+
const contextWindow = this.createSummaryFromRecord(record, true).contextWindow ?? null;
|
|
4603
|
+
await this.options.journalStore.updateSessionMessageProjectionContextWindow(normalizedSessionId, contextWindow);
|
|
4604
|
+
return {
|
|
4605
|
+
...page,
|
|
4606
|
+
contextWindow
|
|
4607
|
+
};
|
|
4508
4608
|
};
|
|
4509
4609
|
getSession = async (sessionId) => {
|
|
4510
4610
|
const record = await this.getSessionRecord(sessionId);
|
|
4511
|
-
|
|
4611
|
+
if (!record) return null;
|
|
4612
|
+
const summary = this.createSummaryFromRecord(record, true);
|
|
4613
|
+
await this.options.journalStore.updateSessionMessageProjectionContextWindow(record.sessionId, summary.contextWindow ?? null);
|
|
4614
|
+
return summary;
|
|
4512
4615
|
};
|
|
4513
4616
|
getContextWindow = async (sessionId, liveRecord) => {
|
|
4514
4617
|
return (liveRecord ? this.createSummaryFromRecord(liveRecord, true) : await this.getSession(sessionId))?.contextWindow ?? null;
|
|
@@ -5369,6 +5472,51 @@ var PanelAppAgentBridgeService = class {
|
|
|
5369
5472
|
//#endregion
|
|
5370
5473
|
//#region src/utils/panel-app-bridge.utils.ts
|
|
5371
5474
|
const PANEL_APP_BRIDGE_MARKER = "nextclaw:panel-app-service-actions:request";
|
|
5475
|
+
function getPanelAppInlineContentHeightReporterScript() {
|
|
5476
|
+
return `
|
|
5477
|
+
function installInlineContentHeightReporter() {
|
|
5478
|
+
const inlineHostContract = ${JSON.stringify(PANEL_APP_INLINE_HOST_CONTRACT)};
|
|
5479
|
+
const readInlineContentHeight = ${readInlineContentHeight.toString()};
|
|
5480
|
+
if (!window.location || !window.document) {
|
|
5481
|
+
return;
|
|
5482
|
+
}
|
|
5483
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
5484
|
+
if (
|
|
5485
|
+
searchParams.get(inlineHostContract.displayModeSearchParam) !== inlineHostContract.displayMode ||
|
|
5486
|
+
searchParams.get(inlineHostContract.placementSearchParam) !== inlineHostContract.placement
|
|
5487
|
+
) {
|
|
5488
|
+
return;
|
|
5489
|
+
}
|
|
5490
|
+
const start = () => {
|
|
5491
|
+
const { body, documentElement } = window.document;
|
|
5492
|
+
if (!documentElement) {
|
|
5493
|
+
return;
|
|
5494
|
+
}
|
|
5495
|
+
let lastHeight = 0;
|
|
5496
|
+
const reportHeight = () => {
|
|
5497
|
+
const height = readInlineContentHeight(body, documentElement);
|
|
5498
|
+
if (height > 0 && height !== lastHeight) {
|
|
5499
|
+
lastHeight = height;
|
|
5500
|
+
window.parent.postMessage({ type: inlineHostContract.contentHeightMessageType, height }, "*");
|
|
5501
|
+
}
|
|
5502
|
+
};
|
|
5503
|
+
if (typeof window.ResizeObserver === "function") {
|
|
5504
|
+
const observer = new window.ResizeObserver(reportHeight);
|
|
5505
|
+
observer.observe(documentElement);
|
|
5506
|
+
if (body) {
|
|
5507
|
+
observer.observe(body);
|
|
5508
|
+
}
|
|
5509
|
+
}
|
|
5510
|
+
window.addEventListener("load", reportHeight);
|
|
5511
|
+
reportHeight();
|
|
5512
|
+
};
|
|
5513
|
+
if (window.document.readyState === "loading") {
|
|
5514
|
+
window.document.addEventListener("DOMContentLoaded", start, { once: true });
|
|
5515
|
+
return;
|
|
5516
|
+
}
|
|
5517
|
+
start();
|
|
5518
|
+
}`.trim();
|
|
5519
|
+
}
|
|
5372
5520
|
function injectPanelAppBridgeScript(html, params) {
|
|
5373
5521
|
if (html.includes(PANEL_APP_BRIDGE_MARKER)) return html;
|
|
5374
5522
|
const script = `<script>${getPanelAppBridgeScript(params)}<\/script>`;
|
|
@@ -5405,6 +5553,8 @@ function getPanelAppBridgeScript(params = {
|
|
|
5405
5553
|
});
|
|
5406
5554
|
}
|
|
5407
5555
|
|
|
5556
|
+
${getPanelAppInlineContentHeightReporterScript()}
|
|
5557
|
+
|
|
5408
5558
|
function resolveApiFetchUrl(input) {
|
|
5409
5559
|
const raw = typeof input === "string" || input instanceof URL ? input.toString() : input?.url;
|
|
5410
5560
|
if (typeof raw !== "string") {
|
|
@@ -5502,6 +5652,7 @@ function getPanelAppBridgeScript(params = {
|
|
|
5502
5652
|
}
|
|
5503
5653
|
}
|
|
5504
5654
|
});
|
|
5655
|
+
installInlineContentHeightReporter();
|
|
5505
5656
|
})();
|
|
5506
5657
|
`.trim();
|
|
5507
5658
|
}
|
|
@@ -7425,6 +7576,90 @@ function resolveAgentHandoffDepth(metadata) {
|
|
|
7425
7576
|
return Math.trunc(rawDepth);
|
|
7426
7577
|
}
|
|
7427
7578
|
//#endregion
|
|
7579
|
+
//#region src/utils/ncp-agent-session-journal-entry.utils.ts
|
|
7580
|
+
function isNcpAgentSessionMessageProjectionBoundaryEvent(event) {
|
|
7581
|
+
return event.type === NcpEventType.MessageSent || event.type === NcpEventType.MessageCompleted || event.type === NcpEventType.MessageAbort || event.type === NcpEventType.RunFinished || event.type === NcpEventType.RunError || event.type === "session.snapshot.message";
|
|
7582
|
+
}
|
|
7583
|
+
function serializeNcpAgentSessionJournalEntry(entry) {
|
|
7584
|
+
const serialized = JSON.stringify(entry);
|
|
7585
|
+
if (!serialized) throw new Error("ncp agent session journal entry serialization produced empty output");
|
|
7586
|
+
if (!isRecord$11(JSON.parse(serialized))) throw new Error("ncp agent session journal entry serialization produced a non-object entry");
|
|
7587
|
+
return serialized;
|
|
7588
|
+
}
|
|
7589
|
+
function attachNcpAgentSessionJournalTimestamp(event, timestamp) {
|
|
7590
|
+
if (!("payload" in event) || !isRecord$11(event.payload)) return event;
|
|
7591
|
+
return {
|
|
7592
|
+
...event,
|
|
7593
|
+
payload: {
|
|
7594
|
+
...event.payload,
|
|
7595
|
+
timestamp
|
|
7596
|
+
}
|
|
7597
|
+
};
|
|
7598
|
+
}
|
|
7599
|
+
var NcpAgentSessionJournalParser = class {
|
|
7600
|
+
metadata = {};
|
|
7601
|
+
agentId;
|
|
7602
|
+
createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7603
|
+
updatedAt = this.createdAt;
|
|
7604
|
+
nextSeq = 1;
|
|
7605
|
+
projectedJournalOffset = 0;
|
|
7606
|
+
events = [];
|
|
7607
|
+
append = (line, index, lineEndOffset) => {
|
|
7608
|
+
if (!line.trim()) return;
|
|
7609
|
+
const parsed = this.parseLine(line, index);
|
|
7610
|
+
if (!parsed) return;
|
|
7611
|
+
if (parsed._type === "metadata") {
|
|
7612
|
+
this.applyMetadata(parsed);
|
|
7613
|
+
return;
|
|
7614
|
+
}
|
|
7615
|
+
if (parsed._type === "event" && isRecord$11(parsed.event)) this.applyEvent(parsed, lineEndOffset);
|
|
7616
|
+
};
|
|
7617
|
+
finish = () => ({
|
|
7618
|
+
metadata: this.metadata,
|
|
7619
|
+
...this.agentId ? { agentId: this.agentId } : {},
|
|
7620
|
+
createdAt: this.createdAt,
|
|
7621
|
+
updatedAt: this.updatedAt,
|
|
7622
|
+
nextSeq: this.nextSeq,
|
|
7623
|
+
projectedJournalOffset: this.projectedJournalOffset,
|
|
7624
|
+
events: this.events
|
|
7625
|
+
});
|
|
7626
|
+
parseLine = (line, index) => {
|
|
7627
|
+
try {
|
|
7628
|
+
const parsed = JSON.parse(line);
|
|
7629
|
+
return isRecord$11(parsed) ? parsed : null;
|
|
7630
|
+
} catch (error) {
|
|
7631
|
+
console.warn(`[ncp-agent-session-journal] skipped corrupted journal line ${index + 1}: ${error instanceof Error ? error.message : String(error)}`);
|
|
7632
|
+
return null;
|
|
7633
|
+
}
|
|
7634
|
+
};
|
|
7635
|
+
applyMetadata = (entry) => {
|
|
7636
|
+
this.metadata = isRecord$11(entry.metadata) ? structuredClone(entry.metadata) : {};
|
|
7637
|
+
this.agentId = normalizeNcpAgentId(typeof entry.agent_id === "string" ? entry.agent_id : void 0);
|
|
7638
|
+
this.createdAt = toIsoString(entry.created_at, this.createdAt);
|
|
7639
|
+
this.updatedAt = toIsoString(entry.updated_at, this.updatedAt);
|
|
7640
|
+
};
|
|
7641
|
+
applyEvent = (entry, lineEndOffset) => {
|
|
7642
|
+
const seq = Number(entry.seq);
|
|
7643
|
+
this.nextSeq = Math.max(this.nextSeq, Number.isFinite(seq) ? Math.trunc(seq) + 1 : this.nextSeq);
|
|
7644
|
+
const eventTimestamp = toIsoString(entry.timestamp, this.updatedAt);
|
|
7645
|
+
this.updatedAt = eventTimestamp;
|
|
7646
|
+
const replayEvent = attachNcpAgentSessionJournalTimestamp(structuredClone(entry.event), eventTimestamp);
|
|
7647
|
+
this.events.push(replayEvent);
|
|
7648
|
+
if (isNcpAgentSessionMessageProjectionBoundaryEvent(replayEvent)) this.projectedJournalOffset = lineEndOffset;
|
|
7649
|
+
};
|
|
7650
|
+
};
|
|
7651
|
+
function parseNcpAgentSessionJournal(raw) {
|
|
7652
|
+
const parser = new NcpAgentSessionJournalParser();
|
|
7653
|
+
let byteOffset = 0;
|
|
7654
|
+
const lines = raw.split("\n");
|
|
7655
|
+
for (const [index, line] of lines.entries()) {
|
|
7656
|
+
const lineEndOffset = byteOffset + Buffer.byteLength(line, "utf-8") + (index < lines.length - 1 ? 1 : 0);
|
|
7657
|
+
parser.append(line, index, lineEndOffset);
|
|
7658
|
+
byteOffset = lineEndOffset;
|
|
7659
|
+
}
|
|
7660
|
+
return parser.finish();
|
|
7661
|
+
}
|
|
7662
|
+
//#endregion
|
|
7428
7663
|
//#region src/stores/ncp-agent-session-metadata.store.ts
|
|
7429
7664
|
var NcpAgentSessionMetadataStore = class {
|
|
7430
7665
|
constructor(journalDir) {
|
|
@@ -7467,6 +7702,266 @@ var NcpAgentSessionMetadataStore = class {
|
|
|
7467
7702
|
};
|
|
7468
7703
|
};
|
|
7469
7704
|
//#endregion
|
|
7705
|
+
//#region src/utils/ncp-agent-session-message-projection.utils.ts
|
|
7706
|
+
const OFFSET_FIELD_WIDTH = 20;
|
|
7707
|
+
OFFSET_FIELD_WIDTH * 2 + 2;
|
|
7708
|
+
function serializeNcpAgentSessionMessage(message) {
|
|
7709
|
+
return Buffer.from(`${JSON.stringify(message)}\n`, "utf-8");
|
|
7710
|
+
}
|
|
7711
|
+
function serializeNcpAgentSessionMessageLocation(location) {
|
|
7712
|
+
const offset = String(location.offset).padStart(OFFSET_FIELD_WIDTH, "0");
|
|
7713
|
+
const length = String(location.length).padStart(OFFSET_FIELD_WIDTH, "0");
|
|
7714
|
+
if (offset.length !== OFFSET_FIELD_WIDTH || length.length !== OFFSET_FIELD_WIDTH) throw new Error("Session message projection exceeded its supported file size.");
|
|
7715
|
+
return `${offset}:${length}\n`;
|
|
7716
|
+
}
|
|
7717
|
+
function parseNcpAgentSessionMessageLocation(value) {
|
|
7718
|
+
const match = /^(\d{20}):(\d{20})\n$/.exec(value);
|
|
7719
|
+
const offset = Number(match?.[1]);
|
|
7720
|
+
const length = Number(match?.[2]);
|
|
7721
|
+
if (!Number.isSafeInteger(offset) || !Number.isSafeInteger(length) || offset < 0 || length < 1) throw new Error("Session message projection contains an invalid offset record.");
|
|
7722
|
+
return {
|
|
7723
|
+
offset,
|
|
7724
|
+
length
|
|
7725
|
+
};
|
|
7726
|
+
}
|
|
7727
|
+
function encodeNcpAgentSessionMessageCursor(ordinal) {
|
|
7728
|
+
return Buffer.from(`v1:${ordinal}`, "utf-8").toString("base64url");
|
|
7729
|
+
}
|
|
7730
|
+
function decodeNcpAgentSessionMessageCursor(cursor, maximumBoundary) {
|
|
7731
|
+
let decoded = "";
|
|
7732
|
+
try {
|
|
7733
|
+
decoded = Buffer.from(cursor, "base64url").toString("utf-8");
|
|
7734
|
+
} catch {
|
|
7735
|
+
throw new SessionMessageCursorError();
|
|
7736
|
+
}
|
|
7737
|
+
const match = /^v1:([1-9]\d*)$/.exec(decoded);
|
|
7738
|
+
const ordinal = Number(match?.[1]);
|
|
7739
|
+
if (!Number.isSafeInteger(ordinal) || ordinal < 1 || ordinal > maximumBoundary) throw new SessionMessageCursorError();
|
|
7740
|
+
return ordinal;
|
|
7741
|
+
}
|
|
7742
|
+
function deduplicateNcpAgentSessionTailMessages(messages) {
|
|
7743
|
+
const byId = /* @__PURE__ */ new Map();
|
|
7744
|
+
for (const message of messages) {
|
|
7745
|
+
byId.delete(message.id);
|
|
7746
|
+
byId.set(message.id, structuredClone(message));
|
|
7747
|
+
}
|
|
7748
|
+
return [...byId.values()];
|
|
7749
|
+
}
|
|
7750
|
+
//#endregion
|
|
7751
|
+
//#region src/stores/ncp-agent-session-message-projection.store.ts
|
|
7752
|
+
const PROJECTION_VERSION = 1;
|
|
7753
|
+
const PROJECTION_ROOT_DIRECTORY = ".message-projections";
|
|
7754
|
+
var NcpAgentSessionMessageProjectionStore = class {
|
|
7755
|
+
constructor(journalDir, source) {
|
|
7756
|
+
this.journalDir = journalDir;
|
|
7757
|
+
this.source = source;
|
|
7758
|
+
}
|
|
7759
|
+
readMeta = async (sessionId) => {
|
|
7760
|
+
try {
|
|
7761
|
+
const parsed = JSON.parse(await readFile(this.metaPath(sessionId), "utf-8"));
|
|
7762
|
+
if (parsed.version !== PROJECTION_VERSION || parsed.sessionId !== sessionId || !Number.isSafeInteger(parsed.total) || !Number.isSafeInteger(parsed.projectedJournalOffset) || !Number.isSafeInteger(parsed.dataBytes) || parsed.lastMessageId !== null && typeof parsed.lastMessageId !== "string" || parsed.contextWindow !== null && !isRecord$11(parsed.contextWindow)) return null;
|
|
7763
|
+
const meta = parsed;
|
|
7764
|
+
const [dataStat, offsetsStat] = await Promise.all([stat(this.dataPath(sessionId)), stat(this.offsetsPath(sessionId))]);
|
|
7765
|
+
if (dataStat.size !== meta.dataBytes || offsetsStat.size !== meta.total * 42 || meta.total < 0 || meta.projectedJournalOffset < 0 || meta.dataBytes < 0) return null;
|
|
7766
|
+
return structuredClone(meta);
|
|
7767
|
+
} catch {
|
|
7768
|
+
return null;
|
|
7769
|
+
}
|
|
7770
|
+
};
|
|
7771
|
+
rebuild = async (params) => {
|
|
7772
|
+
const { contextWindow, messages, projectedJournalOffset, sessionId } = params;
|
|
7773
|
+
const projectionPath = this.projectionPath(sessionId);
|
|
7774
|
+
const projectionRoot = dirname(projectionPath);
|
|
7775
|
+
await mkdir(projectionRoot, { recursive: true });
|
|
7776
|
+
const temporaryPath = await mkdtemp(join(projectionRoot, ".rebuild-"));
|
|
7777
|
+
try {
|
|
7778
|
+
const dataFile = await open(join(temporaryPath, "messages.jsonl"), "w");
|
|
7779
|
+
let dataBytes = 0;
|
|
7780
|
+
try {
|
|
7781
|
+
const offsetsFile = await open(join(temporaryPath, "offsets.idx"), "w");
|
|
7782
|
+
try {
|
|
7783
|
+
for (const message of messages) {
|
|
7784
|
+
const serialized = serializeNcpAgentSessionMessage(message);
|
|
7785
|
+
await dataFile.write(serialized, 0, serialized.length, dataBytes);
|
|
7786
|
+
await offsetsFile.write(serializeNcpAgentSessionMessageLocation({
|
|
7787
|
+
offset: dataBytes,
|
|
7788
|
+
length: serialized.length
|
|
7789
|
+
}));
|
|
7790
|
+
dataBytes += serialized.length;
|
|
7791
|
+
}
|
|
7792
|
+
await Promise.all([dataFile.sync(), offsetsFile.sync()]);
|
|
7793
|
+
} finally {
|
|
7794
|
+
await offsetsFile.close();
|
|
7795
|
+
}
|
|
7796
|
+
} finally {
|
|
7797
|
+
await dataFile.close();
|
|
7798
|
+
}
|
|
7799
|
+
const meta = {
|
|
7800
|
+
version: PROJECTION_VERSION,
|
|
7801
|
+
sessionId,
|
|
7802
|
+
total: messages.length,
|
|
7803
|
+
lastMessageId: messages.at(-1)?.id ?? null,
|
|
7804
|
+
projectedJournalOffset,
|
|
7805
|
+
dataBytes,
|
|
7806
|
+
contextWindow: contextWindow ? structuredClone(contextWindow) : null
|
|
7807
|
+
};
|
|
7808
|
+
await writeFile(join(temporaryPath, "meta.json"), `${JSON.stringify(meta)}\n`, "utf-8");
|
|
7809
|
+
await rm(projectionPath, {
|
|
7810
|
+
recursive: true,
|
|
7811
|
+
force: true
|
|
7812
|
+
});
|
|
7813
|
+
await rename(temporaryPath, projectionPath);
|
|
7814
|
+
} catch (error) {
|
|
7815
|
+
await rm(temporaryPath, {
|
|
7816
|
+
recursive: true,
|
|
7817
|
+
force: true
|
|
7818
|
+
});
|
|
7819
|
+
throw error;
|
|
7820
|
+
}
|
|
7821
|
+
};
|
|
7822
|
+
synchronize = async (params) => {
|
|
7823
|
+
const { messages: sourceMessages, projectedJournalOffset, sessionId } = params;
|
|
7824
|
+
const meta = await this.readMeta(sessionId);
|
|
7825
|
+
if (!meta) return false;
|
|
7826
|
+
const messages = deduplicateNcpAgentSessionTailMessages(sourceMessages);
|
|
7827
|
+
const dataFile = await open(this.dataPath(sessionId), "r+");
|
|
7828
|
+
const offsetsFile = await open(this.offsetsPath(sessionId), "r+");
|
|
7829
|
+
try {
|
|
7830
|
+
for (const message of messages) {
|
|
7831
|
+
const serialized = serializeNcpAgentSessionMessage(message);
|
|
7832
|
+
const location = {
|
|
7833
|
+
offset: meta.dataBytes,
|
|
7834
|
+
length: serialized.length
|
|
7835
|
+
};
|
|
7836
|
+
const serializedLocation = Buffer.from(serializeNcpAgentSessionMessageLocation(location), "utf-8");
|
|
7837
|
+
await dataFile.write(serialized, 0, serialized.length, meta.dataBytes);
|
|
7838
|
+
meta.dataBytes += serialized.length;
|
|
7839
|
+
if (message.id === meta.lastMessageId && meta.total > 0) {
|
|
7840
|
+
await offsetsFile.write(serializedLocation, 0, 42, (meta.total - 1) * 42);
|
|
7841
|
+
continue;
|
|
7842
|
+
}
|
|
7843
|
+
await offsetsFile.write(serializedLocation, 0, 42, meta.total * 42);
|
|
7844
|
+
meta.total += 1;
|
|
7845
|
+
meta.lastMessageId = message.id;
|
|
7846
|
+
}
|
|
7847
|
+
await Promise.all([dataFile.sync(), offsetsFile.sync()]);
|
|
7848
|
+
} finally {
|
|
7849
|
+
await Promise.all([dataFile.close(), offsetsFile.close()]);
|
|
7850
|
+
}
|
|
7851
|
+
meta.projectedJournalOffset = projectedJournalOffset;
|
|
7852
|
+
await this.writeMeta(meta);
|
|
7853
|
+
return true;
|
|
7854
|
+
};
|
|
7855
|
+
updateContextWindow = async (sessionId, contextWindow) => {
|
|
7856
|
+
const meta = await this.readMeta(sessionId);
|
|
7857
|
+
if (!meta) return;
|
|
7858
|
+
meta.contextWindow = contextWindow ? structuredClone(contextWindow) : null;
|
|
7859
|
+
await this.writeMeta(meta);
|
|
7860
|
+
};
|
|
7861
|
+
listPage = async (params) => {
|
|
7862
|
+
const { cursor, limit, sessionId } = params;
|
|
7863
|
+
let meta = await this.readMeta(sessionId);
|
|
7864
|
+
let tailMessages = null;
|
|
7865
|
+
const journalStat = await stat(this.journalPath(sessionId));
|
|
7866
|
+
if (meta && meta.projectedJournalOffset > journalStat.size) meta = null;
|
|
7867
|
+
if (!meta) {
|
|
7868
|
+
const loaded = await this.source?.loadSession(sessionId);
|
|
7869
|
+
if (!loaded) return null;
|
|
7870
|
+
tailMessages = await this.readJournalTailMessages(sessionId, loaded.projectedJournalOffset);
|
|
7871
|
+
const tailMessageIds = new Set(tailMessages.map((message) => message.id));
|
|
7872
|
+
await this.rebuild({
|
|
7873
|
+
sessionId,
|
|
7874
|
+
messages: loaded.record.messages.filter((message) => !tailMessageIds.has(message.id)),
|
|
7875
|
+
projectedJournalOffset: loaded.projectedJournalOffset
|
|
7876
|
+
});
|
|
7877
|
+
meta = await this.readMeta(sessionId);
|
|
7878
|
+
}
|
|
7879
|
+
if (!meta) throw new Error(`Failed to build session message projection: ${sessionId}`);
|
|
7880
|
+
return await this.readPage({
|
|
7881
|
+
sessionId,
|
|
7882
|
+
limit,
|
|
7883
|
+
cursor,
|
|
7884
|
+
tailMessages: tailMessages ?? await this.readJournalTailMessages(sessionId, meta.projectedJournalOffset)
|
|
7885
|
+
});
|
|
7886
|
+
};
|
|
7887
|
+
readPage = async (params) => {
|
|
7888
|
+
const { cursor, limit: requestedLimit, sessionId, tailMessages } = params;
|
|
7889
|
+
const meta = await this.readMeta(sessionId);
|
|
7890
|
+
if (!meta) return null;
|
|
7891
|
+
const uniqueTailMessages = deduplicateNcpAgentSessionTailMessages(tailMessages ?? []);
|
|
7892
|
+
const tailById = new Map(uniqueTailMessages.map((message) => [message.id, message]));
|
|
7893
|
+
const additionalTailMessages = uniqueTailMessages.filter((message) => message.id !== meta.lastMessageId);
|
|
7894
|
+
const limit = Number.isFinite(requestedLimit) ? Math.min(200, Math.max(1, Math.trunc(requestedLimit))) : 80;
|
|
7895
|
+
const boundary = cursor ? decodeNcpAgentSessionMessageCursor(cursor, meta.total + 1) : meta.total + 1;
|
|
7896
|
+
const includeTail = !cursor;
|
|
7897
|
+
const stableLimit = includeTail ? Math.max(0, limit - additionalTailMessages.length) : limit;
|
|
7898
|
+
const endOrdinal = Math.min(meta.total, boundary - 1);
|
|
7899
|
+
const startOrdinal = stableLimit > 0 ? Math.max(1, endOrdinal - stableLimit + 1) : endOrdinal + 1;
|
|
7900
|
+
const stableMessages = startOrdinal <= endOrdinal ? await this.readMessages(sessionId, startOrdinal, endOrdinal) : [];
|
|
7901
|
+
const messages = stableMessages.map((message) => tailById.get(message.id) ?? message);
|
|
7902
|
+
if (includeTail) messages.push(...additionalTailMessages);
|
|
7903
|
+
const cursorOrdinal = stableMessages.length > 0 ? startOrdinal : meta.total + 1;
|
|
7904
|
+
return {
|
|
7905
|
+
messages,
|
|
7906
|
+
total: meta.total + additionalTailMessages.length,
|
|
7907
|
+
pageInfo: {
|
|
7908
|
+
startCursor: messages.length > 0 ? encodeNcpAgentSessionMessageCursor(cursorOrdinal) : null,
|
|
7909
|
+
hasPreviousPage: cursorOrdinal > 1
|
|
7910
|
+
},
|
|
7911
|
+
contextWindow: meta.contextWindow ? structuredClone(meta.contextWindow) : null
|
|
7912
|
+
};
|
|
7913
|
+
};
|
|
7914
|
+
readJournalTailMessages = async (sessionId, offset) => {
|
|
7915
|
+
const file = await open(this.journalPath(sessionId), "r");
|
|
7916
|
+
try {
|
|
7917
|
+
const fileStat = await file.stat();
|
|
7918
|
+
if (offset < 0 || offset > fileStat.size || offset === fileStat.size) return [];
|
|
7919
|
+
const buffer = Buffer.alloc(fileStat.size - offset);
|
|
7920
|
+
const result = await file.read(buffer, 0, buffer.length, offset);
|
|
7921
|
+
return await replayNcpAgentSessionEvents(parseNcpAgentSessionJournal(buffer.subarray(0, result.bytesRead).toString("utf-8")).events);
|
|
7922
|
+
} finally {
|
|
7923
|
+
await file.close();
|
|
7924
|
+
}
|
|
7925
|
+
};
|
|
7926
|
+
delete = async (sessionId) => {
|
|
7927
|
+
await rm(this.projectionPath(sessionId), {
|
|
7928
|
+
recursive: true,
|
|
7929
|
+
force: true
|
|
7930
|
+
});
|
|
7931
|
+
};
|
|
7932
|
+
readMessages = async (sessionId, startOrdinal, endOrdinal) => {
|
|
7933
|
+
const count = endOrdinal - startOrdinal + 1;
|
|
7934
|
+
const indexBuffer = Buffer.alloc(count * 42);
|
|
7935
|
+
const offsetsFile = await open(this.offsetsPath(sessionId), "r");
|
|
7936
|
+
const dataFile = await open(this.dataPath(sessionId), "r");
|
|
7937
|
+
try {
|
|
7938
|
+
if ((await offsetsFile.read(indexBuffer, 0, indexBuffer.length, (startOrdinal - 1) * 42)).bytesRead !== indexBuffer.length) throw new Error("Session message projection ended before the requested page.");
|
|
7939
|
+
const messages = [];
|
|
7940
|
+
for (let index = 0; index < count; index += 1) {
|
|
7941
|
+
const recordStart = index * 42;
|
|
7942
|
+
const location = parseNcpAgentSessionMessageLocation(indexBuffer.subarray(recordStart, recordStart + 42).toString("utf-8"));
|
|
7943
|
+
const messageBuffer = Buffer.alloc(location.length);
|
|
7944
|
+
if ((await dataFile.read(messageBuffer, 0, location.length, location.offset)).bytesRead !== location.length) throw new Error("Session message projection contains a truncated message.");
|
|
7945
|
+
messages.push(JSON.parse(messageBuffer.toString("utf-8")));
|
|
7946
|
+
}
|
|
7947
|
+
return messages;
|
|
7948
|
+
} finally {
|
|
7949
|
+
await Promise.all([offsetsFile.close(), dataFile.close()]);
|
|
7950
|
+
}
|
|
7951
|
+
};
|
|
7952
|
+
writeMeta = async (meta) => {
|
|
7953
|
+
const path = this.metaPath(meta.sessionId);
|
|
7954
|
+
const temporaryPath = `${path}.${process.pid}.tmp`;
|
|
7955
|
+
await writeFile(temporaryPath, `${JSON.stringify(meta)}\n`, "utf-8");
|
|
7956
|
+
await rename(temporaryPath, path);
|
|
7957
|
+
};
|
|
7958
|
+
projectionPath = (sessionId) => join(this.journalDir, PROJECTION_ROOT_DIRECTORY, safeNcpSessionFilename(sessionId));
|
|
7959
|
+
journalPath = (sessionId) => join(this.journalDir, `${safeNcpSessionFilename(sessionId)}.jsonl`);
|
|
7960
|
+
metaPath = (sessionId) => join(this.projectionPath(sessionId), "meta.json");
|
|
7961
|
+
dataPath = (sessionId) => join(this.projectionPath(sessionId), "messages.jsonl");
|
|
7962
|
+
offsetsPath = (sessionId) => join(this.projectionPath(sessionId), "offsets.idx");
|
|
7963
|
+
};
|
|
7964
|
+
//#endregion
|
|
7470
7965
|
//#region src/stores/ncp-agent-session-summary-index.store.ts
|
|
7471
7966
|
function stripSummaryMetadata(summary) {
|
|
7472
7967
|
const { metadata: _metadata, ...nextSummary } = summary;
|
|
@@ -7543,31 +8038,21 @@ var NcpAgentSessionSummaryIndexStore = class {
|
|
|
7543
8038
|
};
|
|
7544
8039
|
//#endregion
|
|
7545
8040
|
//#region src/stores/ncp-agent-session-journal.store.ts
|
|
7546
|
-
function serializeJournalEntry(entry) {
|
|
7547
|
-
const serialized = JSON.stringify(entry);
|
|
7548
|
-
if (!serialized) throw new Error("ncp agent session journal entry serialization produced empty output");
|
|
7549
|
-
if (!isRecord$11(JSON.parse(serialized))) throw new Error("ncp agent session journal entry serialization produced a non-object entry");
|
|
7550
|
-
return serialized;
|
|
7551
|
-
}
|
|
7552
|
-
function attachJournalTimestamp(event, timestamp) {
|
|
7553
|
-
if (!("payload" in event) || !isRecord$11(event.payload)) return event;
|
|
7554
|
-
return {
|
|
7555
|
-
...event,
|
|
7556
|
-
payload: {
|
|
7557
|
-
...event.payload,
|
|
7558
|
-
timestamp
|
|
7559
|
-
}
|
|
7560
|
-
};
|
|
7561
|
-
}
|
|
7562
8041
|
var NcpAgentSessionJournalStore = class {
|
|
7563
8042
|
sessions = /* @__PURE__ */ new Map();
|
|
7564
8043
|
nextSeqBySession = /* @__PURE__ */ new Map();
|
|
7565
8044
|
writeChains = /* @__PURE__ */ new Map();
|
|
7566
8045
|
metadataStore;
|
|
8046
|
+
messageProjectionStore;
|
|
7567
8047
|
summaryIndexStore;
|
|
7568
8048
|
constructor(journalDir) {
|
|
7569
8049
|
this.journalDir = journalDir;
|
|
7570
8050
|
this.metadataStore = new NcpAgentSessionMetadataStore(journalDir);
|
|
8051
|
+
this.messageProjectionStore = new NcpAgentSessionMessageProjectionStore(journalDir, { loadSession: async (sessionId) => {
|
|
8052
|
+
const loaded = this.sessions.get(sessionId) ?? await this.loadSession(sessionId);
|
|
8053
|
+
if (loaded) this.sessions.set(sessionId, loaded);
|
|
8054
|
+
return loaded;
|
|
8055
|
+
} });
|
|
7571
8056
|
this.summaryIndexStore = new NcpAgentSessionSummaryIndexStore(journalDir, async (sessionId) => this.loadSession(sessionId));
|
|
7572
8057
|
}
|
|
7573
8058
|
appendSessionEvent = async (params) => {
|
|
@@ -7598,6 +8083,20 @@ var NcpAgentSessionJournalStore = class {
|
|
|
7598
8083
|
const session = await this.getSession(sessionId);
|
|
7599
8084
|
return session ? session.messages.map((message) => structuredClone(message)) : [];
|
|
7600
8085
|
};
|
|
8086
|
+
listSessionMessagePage = async (params) => {
|
|
8087
|
+
const sessionId = normalizeNcpSessionId(params.sessionId);
|
|
8088
|
+
if (!sessionId) return null;
|
|
8089
|
+
return await this.messageProjectionStore.listPage({
|
|
8090
|
+
sessionId,
|
|
8091
|
+
limit: params.limit,
|
|
8092
|
+
cursor: params.cursor
|
|
8093
|
+
});
|
|
8094
|
+
};
|
|
8095
|
+
updateSessionMessageProjectionContextWindow = async (sessionId, contextWindow) => {
|
|
8096
|
+
const normalizedSessionId = normalizeNcpSessionId(sessionId);
|
|
8097
|
+
if (!normalizedSessionId) return;
|
|
8098
|
+
await this.messageProjectionStore.updateContextWindow(normalizedSessionId, contextWindow);
|
|
8099
|
+
};
|
|
7601
8100
|
setSessionMetadata = async (params) => {
|
|
7602
8101
|
const sessionId = normalizeNcpSessionId(params.sessionId);
|
|
7603
8102
|
if (!sessionId) return false;
|
|
@@ -7629,7 +8128,8 @@ var NcpAgentSessionJournalStore = class {
|
|
|
7629
8128
|
await this.metadataStore.write(nextRecord);
|
|
7630
8129
|
this.sessions.set(sessionId, {
|
|
7631
8130
|
record: nextRecord,
|
|
7632
|
-
nextSeq: loaded.nextSeq
|
|
8131
|
+
nextSeq: loaded.nextSeq,
|
|
8132
|
+
projectedJournalOffset: loaded.projectedJournalOffset
|
|
7633
8133
|
});
|
|
7634
8134
|
this.nextSeqBySession.set(sessionId, loaded.nextSeq);
|
|
7635
8135
|
await this.summaryIndexStore.upsert(createNcpAgentSessionSummary(nextRecord));
|
|
@@ -7668,13 +8168,20 @@ var NcpAgentSessionJournalStore = class {
|
|
|
7668
8168
|
}
|
|
7669
8169
|
}
|
|
7670
8170
|
}));
|
|
7671
|
-
await writeFile(this.sessionPath(sessionId), entries.length > 0 ? `${entries.map(
|
|
8171
|
+
await writeFile(this.sessionPath(sessionId), entries.length > 0 ? `${entries.map(serializeNcpAgentSessionJournalEntry).join("\n")}\n` : "", "utf-8");
|
|
7672
8172
|
const nextSeq = nextRecord.messages.length + 1;
|
|
8173
|
+
const journalStat = await stat(this.sessionPath(sessionId));
|
|
7673
8174
|
this.sessions.set(sessionId, {
|
|
7674
8175
|
record: nextRecord,
|
|
7675
|
-
nextSeq
|
|
8176
|
+
nextSeq,
|
|
8177
|
+
projectedJournalOffset: journalStat.size
|
|
7676
8178
|
});
|
|
7677
8179
|
this.nextSeqBySession.set(sessionId, nextSeq);
|
|
8180
|
+
await this.messageProjectionStore.rebuild({
|
|
8181
|
+
sessionId,
|
|
8182
|
+
messages: nextRecord.messages,
|
|
8183
|
+
projectedJournalOffset: journalStat.size
|
|
8184
|
+
});
|
|
7678
8185
|
await this.summaryIndexStore.upsert(createNcpAgentSessionSummary(nextRecord));
|
|
7679
8186
|
};
|
|
7680
8187
|
deleteSession = async (sessionId) => {
|
|
@@ -7687,6 +8194,7 @@ var NcpAgentSessionJournalStore = class {
|
|
|
7687
8194
|
await unlink(this.sessionPath(normalizedSessionId));
|
|
7688
8195
|
} catch {}
|
|
7689
8196
|
await this.metadataStore.delete(normalizedSessionId);
|
|
8197
|
+
await this.messageProjectionStore.delete(normalizedSessionId);
|
|
7690
8198
|
await this.summaryIndexStore.remove(normalizedSessionId);
|
|
7691
8199
|
return existing;
|
|
7692
8200
|
};
|
|
@@ -7712,6 +8220,18 @@ var NcpAgentSessionJournalStore = class {
|
|
|
7712
8220
|
await this.appendJournalEntry(path, entry);
|
|
7713
8221
|
this.nextSeqBySession.set(sessionId, nextSeq + 1);
|
|
7714
8222
|
this.sessions.delete(sessionId);
|
|
8223
|
+
if (isNcpAgentSessionMessageProjectionBoundaryEvent(event)) {
|
|
8224
|
+
const journalStat = await stat(path);
|
|
8225
|
+
const projectionMeta = await this.messageProjectionStore.readMeta(sessionId);
|
|
8226
|
+
if (projectionMeta) {
|
|
8227
|
+
const projectionTail = await this.messageProjectionStore.readJournalTailMessages(sessionId, projectionMeta.projectedJournalOffset);
|
|
8228
|
+
await this.messageProjectionStore.synchronize({
|
|
8229
|
+
sessionId,
|
|
8230
|
+
messages: projectionTail,
|
|
8231
|
+
projectedJournalOffset: journalStat.size
|
|
8232
|
+
});
|
|
8233
|
+
}
|
|
8234
|
+
}
|
|
7715
8235
|
await this.summaryIndexStore.upsertForEvent({
|
|
7716
8236
|
sessionId,
|
|
7717
8237
|
event,
|
|
@@ -7740,9 +8260,9 @@ var NcpAgentSessionJournalStore = class {
|
|
|
7740
8260
|
} catch {
|
|
7741
8261
|
return null;
|
|
7742
8262
|
}
|
|
7743
|
-
const parsedJournal =
|
|
8263
|
+
const parsedJournal = parseNcpAgentSessionJournal(raw);
|
|
7744
8264
|
const { agentId, createdAt, updatedAt, metadata } = await this.metadataStore.read(sessionId, parsedJournal);
|
|
7745
|
-
const { events, nextSeq } = parsedJournal;
|
|
8265
|
+
const { events, nextSeq, projectedJournalOffset } = parsedJournal;
|
|
7746
8266
|
const messages = await replayNcpAgentSessionEvents(events);
|
|
7747
8267
|
const record = {
|
|
7748
8268
|
sessionId,
|
|
@@ -7755,53 +8275,12 @@ var NcpAgentSessionJournalStore = class {
|
|
|
7755
8275
|
this.nextSeqBySession.set(sessionId, nextSeq);
|
|
7756
8276
|
return {
|
|
7757
8277
|
record,
|
|
7758
|
-
nextSeq
|
|
7759
|
-
};
|
|
7760
|
-
};
|
|
7761
|
-
parseSessionJournal = (raw) => {
|
|
7762
|
-
let metadata = {};
|
|
7763
|
-
let agentId;
|
|
7764
|
-
let createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7765
|
-
let updatedAt = createdAt;
|
|
7766
|
-
let nextSeq = 1;
|
|
7767
|
-
const events = [];
|
|
7768
|
-
for (const [index, line] of raw.split("\n").entries()) {
|
|
7769
|
-
if (!line.trim()) continue;
|
|
7770
|
-
let parsed;
|
|
7771
|
-
try {
|
|
7772
|
-
parsed = JSON.parse(line);
|
|
7773
|
-
} catch (error) {
|
|
7774
|
-
console.warn(`[ncp-agent-session-journal] skipped corrupted journal line ${index + 1}: ${error instanceof Error ? error.message : String(error)}`);
|
|
7775
|
-
continue;
|
|
7776
|
-
}
|
|
7777
|
-
if (!isRecord$11(parsed)) continue;
|
|
7778
|
-
if (parsed._type === "metadata") {
|
|
7779
|
-
metadata = isRecord$11(parsed.metadata) ? structuredClone(parsed.metadata) : {};
|
|
7780
|
-
agentId = normalizeNcpAgentId(typeof parsed.agent_id === "string" ? parsed.agent_id : void 0);
|
|
7781
|
-
createdAt = toIsoString(parsed.created_at, createdAt);
|
|
7782
|
-
updatedAt = toIsoString(parsed.updated_at, updatedAt);
|
|
7783
|
-
continue;
|
|
7784
|
-
}
|
|
7785
|
-
if (parsed._type === "event" && isRecord$11(parsed.event)) {
|
|
7786
|
-
const seq = Number(parsed.seq);
|
|
7787
|
-
nextSeq = Math.max(nextSeq, Number.isFinite(seq) ? Math.trunc(seq) + 1 : nextSeq);
|
|
7788
|
-
const eventTimestamp = toIsoString(parsed.timestamp, updatedAt);
|
|
7789
|
-
updatedAt = eventTimestamp;
|
|
7790
|
-
const event = structuredClone(parsed.event);
|
|
7791
|
-
events.push(attachJournalTimestamp(event, eventTimestamp));
|
|
7792
|
-
}
|
|
7793
|
-
}
|
|
7794
|
-
return {
|
|
7795
|
-
metadata,
|
|
7796
|
-
...agentId ? { agentId } : {},
|
|
7797
|
-
createdAt,
|
|
7798
|
-
updatedAt,
|
|
7799
8278
|
nextSeq,
|
|
7800
|
-
|
|
8279
|
+
projectedJournalOffset
|
|
7801
8280
|
};
|
|
7802
8281
|
};
|
|
7803
8282
|
appendJournalEntry = async (path, entry) => {
|
|
7804
|
-
await appendFile(path, `${
|
|
8283
|
+
await appendFile(path, `${serializeNcpAgentSessionJournalEntry(entry)}\n`, "utf-8");
|
|
7805
8284
|
};
|
|
7806
8285
|
ensureJournalDir = async () => {
|
|
7807
8286
|
await mkdir(this.journalDir, { recursive: true });
|
|
@@ -8920,9 +9399,10 @@ var NcpAgentRuntimeWrapper = class {
|
|
|
8920
9399
|
this.params = params;
|
|
8921
9400
|
}
|
|
8922
9401
|
run = async function* (spec, options) {
|
|
8923
|
-
const { sessionRun, tools } = options;
|
|
9402
|
+
const { session, sessionRun, signal, tools } = options;
|
|
8924
9403
|
this.currentTools = tools.map(this.toOpenAiTool);
|
|
8925
9404
|
const messages = sessionRun.inbox.drain();
|
|
9405
|
+
let executionMetadataSeen = false;
|
|
8926
9406
|
try {
|
|
8927
9407
|
for (const event of this.toMessageSentEvents(messages, spec, sessionRun.sessionId)) yield await this.applyEvent(sessionRun, event);
|
|
8928
9408
|
const input = {
|
|
@@ -8930,10 +9410,18 @@ var NcpAgentRuntimeWrapper = class {
|
|
|
8930
9410
|
runId: spec.runId,
|
|
8931
9411
|
messages,
|
|
8932
9412
|
correlationId: spec.correlationId,
|
|
8933
|
-
metadata: this.buildMetadata(
|
|
8934
|
-
executionContext: { cwd:
|
|
9413
|
+
metadata: this.buildMetadata(session, spec),
|
|
9414
|
+
executionContext: { cwd: session.workingDir }
|
|
8935
9415
|
};
|
|
8936
|
-
for await (const event of this.getRuntime().run(input, { signal
|
|
9416
|
+
for await (const event of this.getRuntime().run(input, { signal })) {
|
|
9417
|
+
if (event.type === NcpEventType.RunMetadata && readNcpAiExecutionMetadata(event.payload.metadata)) executionMetadataSeen = true;
|
|
9418
|
+
const terminalOutcome = this.readTerminalOutcome(event);
|
|
9419
|
+
if (terminalOutcome && !executionMetadataSeen) {
|
|
9420
|
+
yield await this.applyEvent(sessionRun, this.createExecutionMetadataEvent(spec, session, event, terminalOutcome));
|
|
9421
|
+
executionMetadataSeen = true;
|
|
9422
|
+
}
|
|
9423
|
+
yield await this.applyEvent(sessionRun, event);
|
|
9424
|
+
}
|
|
8937
9425
|
} finally {
|
|
8938
9426
|
this.currentTools = [];
|
|
8939
9427
|
}
|
|
@@ -8971,6 +9459,28 @@ var NcpAgentRuntimeWrapper = class {
|
|
|
8971
9459
|
preferred_model: spec.model,
|
|
8972
9460
|
thinkingEffort: spec.thinkingEffort
|
|
8973
9461
|
});
|
|
9462
|
+
readTerminalOutcome = (event) => {
|
|
9463
|
+
if (event.type === NcpEventType.RunFinished) return "completed";
|
|
9464
|
+
if (event.type === NcpEventType.RunError) return "failed";
|
|
9465
|
+
if (event.type === NcpEventType.MessageAbort) return "aborted";
|
|
9466
|
+
return null;
|
|
9467
|
+
};
|
|
9468
|
+
createExecutionMetadataEvent = (spec, session, terminalEvent, outcome) => ({
|
|
9469
|
+
occurredAt: terminalEvent.occurredAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
9470
|
+
type: NcpEventType.RunMetadata,
|
|
9471
|
+
payload: {
|
|
9472
|
+
runId: spec.runId,
|
|
9473
|
+
sessionId: session.sessionId,
|
|
9474
|
+
correlationId: spec.correlationId,
|
|
9475
|
+
metadata: { [NCP_AI_EXECUTION_METADATA_KEY]: createUnavailableNcpAiExecutionMetadata({
|
|
9476
|
+
runId: spec.runId,
|
|
9477
|
+
runtimeId: spec.runtimeId,
|
|
9478
|
+
model: spec.model,
|
|
9479
|
+
requestedModel: spec.requestedModel,
|
|
9480
|
+
outcome
|
|
9481
|
+
}) }
|
|
9482
|
+
}
|
|
9483
|
+
});
|
|
8974
9484
|
toOpenAiTool = (tool) => buildOpenAiFunctionTool({
|
|
8975
9485
|
name: tool.name,
|
|
8976
9486
|
description: tool.description,
|
|
@@ -9489,17 +9999,39 @@ var SkillsContextProvider = class {
|
|
|
9489
9999
|
};
|
|
9490
10000
|
//#endregion
|
|
9491
10001
|
//#region src/contributions/context-provider/providers/tooling-context.provider.ts
|
|
10002
|
+
function readSearchApiKey(searchConfig, provider) {
|
|
10003
|
+
if (provider === "bocha") return searchConfig?.providers?.bocha?.apiKey?.trim() ?? "";
|
|
10004
|
+
if (provider === "tavily") return searchConfig?.providers?.tavily?.apiKey?.trim() ?? "";
|
|
10005
|
+
return searchConfig?.providers?.brave?.apiKey?.trim() ?? "";
|
|
10006
|
+
}
|
|
10007
|
+
function renderWebSearchReadiness(params) {
|
|
10008
|
+
const { searchConfig, toolNames } = params;
|
|
10009
|
+
if (!toolNames.includes("web_search")) return "web_search is unavailable in this turn.";
|
|
10010
|
+
const provider = searchConfig?.provider ?? "bocha";
|
|
10011
|
+
if (!(searchConfig?.enabledProviders ?? ["bocha"]).includes(provider)) return `web_search is not ready: provider ${provider} is not enabled.`;
|
|
10012
|
+
if (!readSearchApiKey(searchConfig, provider)) return `web_search is not ready: provider ${provider} has no API key configured.`;
|
|
10013
|
+
return `web_search is ready with provider ${provider}.`;
|
|
10014
|
+
}
|
|
9492
10015
|
var ToolingContextProvider = class {
|
|
9493
10016
|
constructor(context) {
|
|
9494
10017
|
this.context = context;
|
|
9495
10018
|
}
|
|
9496
10019
|
provide = async (request) => {
|
|
9497
|
-
const { toolCatalog } = await this.context.resolve(request);
|
|
10020
|
+
const { runContext, toolCatalog } = await this.context.resolve(request);
|
|
9498
10021
|
return [[
|
|
9499
10022
|
"## Tooling",
|
|
9500
10023
|
"Tool availability (filtered by policy):",
|
|
9501
10024
|
"Tool names are case-sensitive. Call tools exactly as listed.",
|
|
9502
10025
|
...toolCatalog.length > 0 ? toolCatalog.map((tool) => `- ${tool.name}: ${tool.description ?? "No description available"}`) : ["- No tools available for this turn."],
|
|
10026
|
+
"Web access policy:",
|
|
10027
|
+
`- ${renderWebSearchReadiness({
|
|
10028
|
+
searchConfig: runContext.profile.searchConfig,
|
|
10029
|
+
toolNames: toolCatalog.map((tool) => tool.name)
|
|
10030
|
+
})}`,
|
|
10031
|
+
"- web_search and Agent Browser are distinct capabilities: web_search is for open-ended source discovery; Agent Browser operates real browser pages.",
|
|
10032
|
+
"- In this policy, Agent Browser means the external agent-browser CLI documented by the builtin skill. web_fetch, Chrome/Edge DevTools MCP, and Browser Connector are separate capabilities and must not be called Agent Browser.",
|
|
10033
|
+
"- Prefer a ready web_search for open-ended discovery. If it is unavailable, not configured, or returns an error, and browser navigation can still make progress, briefly tell the user you are switching to browser automation, then read and follow the builtin agent-browser skill.",
|
|
10034
|
+
"- Do not describe Agent Browser output as web_search output, and do not silently install its external CLI.",
|
|
9503
10035
|
"TOOLS.md does not control tool availability; it is user guidance for how to use external tools.",
|
|
9504
10036
|
"For long waits, avoid rapid poll loops: use exec with enough yieldMs.",
|
|
9505
10037
|
"For relative time/date scheduling requests (for example 'in 5 minutes' / '1分钟后'), first check the current local time with an available tool such as exec/date, then convert it to an absolute ISO time with timezone. Do not guess.",
|
|
@@ -11857,6 +12389,6 @@ function resolveLegacyEventType(message) {
|
|
|
11857
12389
|
return `message.${role || "other"}`;
|
|
11858
12390
|
}
|
|
11859
12391
|
//#endregion
|
|
11860
|
-
export { AUTOMATIC_UPDATE_CHECK_INTERVAL_MS, AccessManager, AgentManager, AgentRunClient, AutomationManager, BuiltinNarpRuntimeProviderService, CONTEXT_COMPACTION_PROJECTION_KIND, CONTEXT_COMPACTION_PROJECTION_METADATA_KEY, CONTEXT_COMPACTION_TIMELINE_KIND, ChannelManager, CommandRegistry, ConfigManager, ContextCompactionPreflightService, ContextWindowPreviewManager, DEFAULT_AGENT_RUNTIME_ENTRY_ID, DEFAULT_SERVICE_ACTION_RISK, ExtensionManager, GatewayInboundProcessor, LlmProviderManager, LlmUsageManager, LlmUsageStore, McpManager, McpServiceAppRuntimeService, NARP_HTTP_RUNTIME_KIND, NARP_STDIO_RUNTIME_KIND, NEXTCLAW_TIMELINE_KIND_METADATA_KEY, NcpAgentSessionJournalStore, NextclawKernel, PANEL_APP_AGENT_CAPABILITIES, PROJECT_TEMPLATE_IDS, PanelAppAssetTokenService, PanelAppError, PanelAppManager, PreferenceError, PreferenceManager, ProjectError, ProjectManager, ProviderManagerNcpLLMApi, SERVICE_APP_MANIFEST_FILE_NAME, ServiceAppError, ServiceAppManager, SessionManager, SessionRequestManager, SessionSettingsError, SkillManager, UpdateManifestReader, buildAgentRunSendPayload, buildContextCompactionModelInput, buildContextCompactionTimelineNcpMessage, buildLlmUsageSummary, buildLocalizedTextMap, buildNextclawNcpRunContext, buildServiceActionId, createAgentRuntimeSessionRequestDispatcher, createAssetTools, createContextCompactionMessageId, createContextWindowSignature, createLlmUsageRecord, describeAgentRuntimeSessionTypes, dispatchAgentRuntimeSessionRequest, dispatchChannelReplyRoute, dispatchPromptOverNcp, getAutomaticUpdateCheckDelay, getServiceActionName, getServiceAppManifestPath, getUnsignedUpdateManifest, hasLlmUsageTelemetry, isContextCompactionProjectionMessage, isContextCompactionTimelineMessage, isContextWindowSnapshot, isPanelAppAgentCapability, isPanelAppError, isPreferenceError, isProjectError, isReplyCapableChannel, isServiceAppError, isSessionSettingsError, listExtensionChannelIds, listServiceAppManifestActions, mergeServiceAppRuntimeActions, normalizeAgentRuntimeSessionTypeIcon, normalizeLlmUsageModel, normalizeOptionalString, parseServiceAppManifest, parseSkillFrontmatter, readContextWindowEventSessionId, readLatestContextCompactionCheckpoint, readLearningLoopRuntimeConfig, readMetadataModel, readMetadataThinking, readServiceAppManifest, resolveAgentRuntimeEntries, resolveAutomaticUpdateCheckIntervalMs, resolveChannelReplyRoute, resolveEffectiveModel, resolveLegacyEventType, resolveSessionChannelContext, runGatewayInboundLoop, sanitizeLlmUsage, serializeUnsignedUpdateManifest, shouldRefreshContextWindowDuringStream, shouldRefreshContextWindowImmediately, stripSkillFrontmatter, syncSessionThinkingPreference, toNcpMessages, waitForAgentRuntimeSessionReply };
|
|
12392
|
+
export { AUTOMATIC_UPDATE_CHECK_INTERVAL_MS, AccessManager, AgentManager, AgentRunClient, AutomationManager, BuiltinNarpRuntimeProviderService, CONTEXT_COMPACTION_PROJECTION_KIND, CONTEXT_COMPACTION_PROJECTION_METADATA_KEY, CONTEXT_COMPACTION_TIMELINE_KIND, ChannelManager, CommandRegistry, ConfigManager, ContextCompactionPreflightService, ContextWindowPreviewManager, DEFAULT_AGENT_RUNTIME_ENTRY_ID, DEFAULT_SERVICE_ACTION_RISK, ExtensionManager, GatewayInboundProcessor, LlmProviderManager, LlmUsageManager, LlmUsageStore, McpManager, McpServiceAppRuntimeService, NARP_HTTP_RUNTIME_KIND, NARP_STDIO_RUNTIME_KIND, NEXTCLAW_TIMELINE_KIND_METADATA_KEY, NcpAgentSessionJournalStore, NextclawKernel, PANEL_APP_AGENT_CAPABILITIES, PROJECT_TEMPLATE_IDS, PanelAppAssetTokenService, PanelAppError, PanelAppManager, PreferenceError, PreferenceManager, ProjectError, ProjectManager, ProviderManagerNcpLLMApi, SERVICE_APP_MANIFEST_FILE_NAME, ServiceAppError, ServiceAppManager, SessionManager, SessionMessageCursorError, SessionRequestManager, SessionSettingsError, SkillManager, UpdateManifestReader, buildAgentRunSendPayload, buildContextCompactionModelInput, buildContextCompactionTimelineNcpMessage, buildLlmUsageSummary, buildLocalizedTextMap, buildNextclawNcpRunContext, buildServiceActionId, createAgentRuntimeSessionRequestDispatcher, createAssetTools, createContextCompactionMessageId, createContextWindowSignature, createLlmUsageRecord, describeAgentRuntimeSessionTypes, dispatchAgentRuntimeSessionRequest, dispatchChannelReplyRoute, dispatchPromptOverNcp, getAutomaticUpdateCheckDelay, getServiceActionName, getServiceAppManifestPath, getUnsignedUpdateManifest, hasLlmUsageTelemetry, isContextCompactionProjectionMessage, isContextCompactionTimelineMessage, isContextWindowSnapshot, isPanelAppAgentCapability, isPanelAppError, isPreferenceError, isProjectError, isReplyCapableChannel, isServiceAppError, isSessionMessageCursorError, isSessionSettingsError, listExtensionChannelIds, listServiceAppManifestActions, mergeServiceAppRuntimeActions, normalizeAgentRuntimeSessionTypeIcon, normalizeLlmUsageModel, normalizeOptionalString, parseServiceAppManifest, parseSkillFrontmatter, readContextWindowEventSessionId, readLatestContextCompactionCheckpoint, readLearningLoopRuntimeConfig, readMetadataModel, readMetadataThinking, readServiceAppManifest, resolveAgentRuntimeEntries, resolveAutomaticUpdateCheckIntervalMs, resolveChannelReplyRoute, resolveEffectiveModel, resolveLegacyEventType, resolveSessionChannelContext, runGatewayInboundLoop, sanitizeLlmUsage, serializeUnsignedUpdateManifest, shouldRefreshContextWindowDuringStream, shouldRefreshContextWindowImmediately, stripSkillFrontmatter, syncSessionThinkingPreference, toNcpMessages, waitForAgentRuntimeSessionReply };
|
|
11861
12393
|
|
|
11862
12394
|
//# sourceMappingURL=index.js.map
|