@nextclaw/kernel 0.6.0 → 0.6.2

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.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { n as getUnsignedUpdateManifest, r as serializeUnsignedUpdateManifest, t as UpdateManifestReader } from "./update-manifest.types-C0qPrjGQ.js";
2
2
  import { createRequire } from "node:module";
3
3
  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, sanitizeOutboundAssistantContent, saveConfig, summarizeSessionRequestTask, toExtensionConfigView, updateAgentProfile } from "@nextclaw/core";
4
- import { NcpEventType, sanitizeAssistantReplyTags } from "@nextclaw/ncp";
4
+ import { NcpEventType, normalizeAssistantText, sanitizeAssistantReplyTags } from "@nextclaw/ncp";
5
5
  import { LocalAssetStore, buildAssetContentPath, buildNcpUserContent, buildOpenAiFunctionTool, ncpMessageToOpenAiMessages, validateToolArgs } from "@nextclaw/ncp-agent-runtime";
6
6
  import { createHash, createHmac, randomBytes, randomUUID, scryptSync, timingSafeEqual } from "node:crypto";
7
7
  import { CHAT_SESSION_MATERIALIZATION_METADATA_KEY, EventBus, Ingress, eventKeys, ingressKeys, isRuntimeDefaultModelValue, normalizeRuntimeModelSelectionMode } from "@nextclaw/shared";
@@ -203,8 +203,18 @@ function toLegacyMessages(messages, options = {}) {
203
203
  //#region src/features/context-compaction/utils/context-compaction.utils.ts
204
204
  const NEXTCLAW_TIMELINE_KIND_METADATA_KEY = "nextclaw_timeline_kind";
205
205
  const CONTEXT_COMPACTION_TIMELINE_KIND = "context_compaction";
206
+ const CONTEXT_COMPACTION_PROJECTION_METADATA_KEY = "nextclaw_context_projection";
207
+ const CONTEXT_COMPACTION_PROJECTION_KIND = "compressed_context";
206
208
  function readCheckpointTimelineText(checkpoint) {
207
- return checkpoint.status === "compressing" ? "正在压缩较早上下文" : "较早上下文已自动压缩";
209
+ return checkpoint.status === "compressing" ? "Compressing earlier context" : "Earlier context was auto-compacted";
210
+ }
211
+ function buildCompressedContextSystemText(checkpoint) {
212
+ return [
213
+ "Authoritative compressed prior conversation context for this session.",
214
+ "Continue from this context and the latest user message. Do not restart onboarding or treat missing profile fields as a new-session trigger unless the compressed context says onboarding is the active user task.",
215
+ "",
216
+ checkpoint.summary
217
+ ].join("\n");
208
218
  }
209
219
  function readContextCompactionCheckpoint(message) {
210
220
  const metadata = message.metadata;
@@ -221,15 +231,19 @@ function buildContextCompactionSummaryMessage(params) {
221
231
  return {
222
232
  id: `${sessionId}:context-compaction-summary:${checkpoint.id}:${checkpoint.updatedAt}`,
223
233
  sessionId,
224
- role: "user",
234
+ role: "service",
225
235
  status: "final",
226
236
  timestamp: checkpoint.updatedAt,
227
237
  parts: [{
228
238
  type: "text",
229
- text: checkpoint.summary
230
- }]
239
+ text: buildCompressedContextSystemText(checkpoint)
240
+ }],
241
+ metadata: { [CONTEXT_COMPACTION_PROJECTION_METADATA_KEY]: CONTEXT_COMPACTION_PROJECTION_KIND }
231
242
  };
232
243
  }
244
+ function readCheckpointCoveredUntil(checkpoint) {
245
+ return checkpoint.coveredUntil ?? checkpoint.updatedAt;
246
+ }
233
247
  function createContextCompactionMessageId() {
234
248
  return `context-compaction-message-${randomUUID()}`;
235
249
  }
@@ -255,6 +269,9 @@ function buildContextCompactionTimelineNcpMessage(params) {
255
269
  function isContextCompactionTimelineMessage(message) {
256
270
  return message?.metadata?.[NEXTCLAW_TIMELINE_KIND_METADATA_KEY] === CONTEXT_COMPACTION_TIMELINE_KIND;
257
271
  }
272
+ function isContextCompactionProjectionMessage(message) {
273
+ return message?.metadata?.[CONTEXT_COMPACTION_PROJECTION_METADATA_KEY] === CONTEXT_COMPACTION_PROJECTION_KIND;
274
+ }
258
275
  function readLatestContextCompactionCheckpoint(sessionMessages) {
259
276
  return readLatestContextCompactionMarker(sessionMessages)?.checkpoint ?? null;
260
277
  }
@@ -264,10 +281,11 @@ function buildContextCompactionModelInput(params) {
264
281
  const regularMessages = sessionMessages.filter((message) => !readContextCompactionCheckpoint(message));
265
282
  if (!marker) return regularMessages.map((message) => structuredClone(message));
266
283
  const { checkpoint } = marker;
284
+ const coveredUntil = readCheckpointCoveredUntil(checkpoint);
267
285
  return [buildContextCompactionSummaryMessage({
268
286
  checkpoint,
269
287
  sessionId
270
- }), ...regularMessages.filter((message) => Date.parse(message.timestamp) > Date.parse(checkpoint.updatedAt)).sort((left, right) => Date.parse(left.timestamp) - Date.parse(right.timestamp))].map((message) => structuredClone(message));
288
+ }), ...regularMessages.filter((message) => Date.parse(message.timestamp) > Date.parse(coveredUntil)).sort((left, right) => Date.parse(left.timestamp) - Date.parse(right.timestamp))].map((message) => structuredClone(message));
271
289
  }
272
290
  function readContextWindowEventSessionId(event) {
273
291
  const payload = "payload" in event ? event.payload : null;
@@ -311,6 +329,17 @@ function shouldRefreshContextWindowImmediately(event) {
311
329
  //#region src/features/context-compaction/services/context-compaction-preflight.service.ts
312
330
  const SUMMARY_MAX_TOKENS = 4e3;
313
331
  const SUMMARY_SOURCE_MAX_CHARS = 12e4;
332
+ const SUMMARY_SOURCE_HEAD_MESSAGES = 2;
333
+ const SUMMARY_SOURCE_TAIL_MESSAGES = 8;
334
+ const SUMMARY_SOURCE_STRING_HEAD_CHARS = 6e3;
335
+ const SUMMARY_SOURCE_STRING_TAIL_CHARS = 6e3;
336
+ function buildContextBlockMessage(contextBlocks = []) {
337
+ const contextContent = contextBlocks.map((block) => block.trim()).filter(Boolean).join("\n\n");
338
+ return contextContent ? [{
339
+ role: "system",
340
+ content: contextContent
341
+ }] : [];
342
+ }
314
343
  function mergeInputMessages(params) {
315
344
  const messages = params.sessionMessages.map((message) => structuredClone(message));
316
345
  const seen = new Set(messages.map((message) => message.id));
@@ -320,10 +349,47 @@ function mergeInputMessages(params) {
320
349
  }
321
350
  return messages;
322
351
  }
352
+ function toCompactionSourceMessage(message) {
353
+ return {
354
+ role: message.role,
355
+ content: message.content,
356
+ timestamp: message.timestamp,
357
+ ncp_message_id: message.ncp_message_id
358
+ };
359
+ }
323
360
  function stringifyCompactionSource(messages) {
324
- const json = JSON.stringify(messages, null, 2);
361
+ const sourceMessages = messages.map(toCompactionSourceMessage);
362
+ const json = JSON.stringify(sourceMessages, null, 2);
325
363
  if (json.length <= SUMMARY_SOURCE_MAX_CHARS) return json;
326
- return `${json.slice(0, SUMMARY_SOURCE_MAX_CHARS).trimEnd()}\n[truncated_source]`;
364
+ const tailStart = Math.max(SUMMARY_SOURCE_HEAD_MESSAGES, sourceMessages.length - SUMMARY_SOURCE_TAIL_MESSAGES);
365
+ const compactedMessages = [
366
+ ...sourceMessages.slice(0, SUMMARY_SOURCE_HEAD_MESSAGES),
367
+ ...tailStart > SUMMARY_SOURCE_HEAD_MESSAGES ? [{
368
+ role: "system",
369
+ content: `[${tailStart - SUMMARY_SOURCE_HEAD_MESSAGES} middle messages omitted from compaction source]`
370
+ }] : [],
371
+ ...sourceMessages.slice(tailStart)
372
+ ];
373
+ const compactedJson = JSON.stringify(compactedMessages, (_key, value) => truncateSummarySourceString(value), 2);
374
+ if (compactedJson.length <= SUMMARY_SOURCE_MAX_CHARS) return compactedJson;
375
+ const marker = "\n[truncated_compaction_source_middle]\n";
376
+ const headChars = Math.floor((SUMMARY_SOURCE_MAX_CHARS - 38) / 2);
377
+ const tailChars = SUMMARY_SOURCE_MAX_CHARS - 38 - headChars;
378
+ return `${compactedJson.slice(0, headChars).trimEnd()}${marker}${compactedJson.slice(-tailChars).trimStart()}`;
379
+ }
380
+ function truncateSummarySourceString(value) {
381
+ if (typeof value === "string") {
382
+ if (value.length <= SUMMARY_SOURCE_STRING_HEAD_CHARS + SUMMARY_SOURCE_STRING_TAIL_CHARS) return value;
383
+ return [
384
+ value.slice(0, SUMMARY_SOURCE_STRING_HEAD_CHARS).trimEnd(),
385
+ `[${value.length - SUMMARY_SOURCE_STRING_HEAD_CHARS - SUMMARY_SOURCE_STRING_TAIL_CHARS} chars omitted]`,
386
+ value.slice(-SUMMARY_SOURCE_STRING_TAIL_CHARS).trimStart()
387
+ ].join("\n");
388
+ }
389
+ return value;
390
+ }
391
+ function normalizeCompactionSummary(content) {
392
+ return normalizeAssistantText(content, "think-tags").text.trim();
327
393
  }
328
394
  function buildContextWindowSnapshotFromBudget(params) {
329
395
  const { budget, checkpoint, totalContextTokens } = params;
@@ -347,7 +413,7 @@ var ContextCompactionPreflightService = class {
347
413
  this.providerManager = providerManager;
348
414
  }
349
415
  preview = (params) => {
350
- const { requestMetadata, sessionId, sessionMessages, storedAgentId, storedMetadata } = params;
416
+ const { contextBlocks = [], requestMetadata, sessionId, sessionMessages, storedAgentId, storedMetadata } = params;
351
417
  const profile = this.resolveCompactionProfile({
352
418
  requestMetadata,
353
419
  storedAgentId
@@ -357,9 +423,10 @@ var ContextCompactionPreflightService = class {
357
423
  sessionId,
358
424
  sessionMessages
359
425
  }) : sessionMessages.filter((message) => !isContextCompactionTimelineMessage(message));
426
+ const messages = [...buildContextBlockMessage(contextBlocks), ...toLegacyMessages(projectedMessages)];
360
427
  return buildContextWindowSnapshotFromBudget({
361
428
  budget: this.contextWindowBudgetService.evaluate({
362
- messages: toLegacyMessages(projectedMessages),
429
+ messages,
363
430
  contextTokens: profile.contextTokens,
364
431
  reservedContextTokens: profile.reservedContextTokens
365
432
  }),
@@ -368,7 +435,7 @@ var ContextCompactionPreflightService = class {
368
435
  });
369
436
  };
370
437
  begin = (params) => {
371
- const { inputMessages, requestMetadata, sessionId, sessionMessages, storedAgentId, storedMetadata } = params;
438
+ const { contextBlocks = [], inputMessages, requestMetadata, sessionId, sessionMessages, storedAgentId, storedMetadata } = params;
372
439
  const profile = this.resolveCompactionProfile({
373
440
  requestMetadata,
374
441
  storedAgentId
@@ -379,10 +446,11 @@ var ContextCompactionPreflightService = class {
379
446
  sessionMessages
380
447
  });
381
448
  const existingCheckpoint = readCompressedContextCompactionCheckpoint(storedMetadata[CONTEXT_COMPACTION_METADATA_KEY]) ?? readLatestContextCompactionCheckpoint(ncpMessages);
382
- const messages = toLegacyMessages(existingCheckpoint ? buildContextCompactionModelInput({
449
+ const projectedMessages = existingCheckpoint ? buildContextCompactionModelInput({
383
450
  sessionId,
384
451
  sessionMessages: ncpMessages
385
- }) : ncpMessages.filter((message) => !isContextCompactionTimelineMessage(message)));
452
+ }) : ncpMessages.filter((message) => !isContextCompactionTimelineMessage(message));
453
+ const messages = [...buildContextBlockMessage(contextBlocks), ...toLegacyMessages(projectedMessages)];
386
454
  const budget = this.contextWindowBudgetService.evaluate({
387
455
  messages,
388
456
  contextTokens,
@@ -468,7 +536,7 @@ var ContextCompactionPreflightService = class {
468
536
  generateSummary = async (params) => {
469
537
  if (!this.providerManager) throw new Error("context compaction summary generation requires a provider manager");
470
538
  const { messages, model } = params;
471
- const summary = (await this.providerManager.chat({
539
+ const response = await this.providerManager.chat({
472
540
  model,
473
541
  maxTokens: SUMMARY_MAX_TOKENS,
474
542
  messages: [{
@@ -476,7 +544,10 @@ var ContextCompactionPreflightService = class {
476
544
  content: [
477
545
  "You are NextClaw's context compactor for a coding agent session.",
478
546
  "Create a complete compressed working context that will replace all prior conversation messages in a future model request.",
479
- "The model will not receive a raw recent-message tail, so preserve the latest user intent and recent turns with high fidelity inside the summary.",
547
+ "Only the latest current input may remain raw, so preserve the active task, latest user intent, latest assistant response, and recent turns with high fidelity inside the summary.",
548
+ "Always include a 'Continuation Contract' section that states what the next assistant response should remember and how it should continue the session.",
549
+ "Do not turn missing user profile, assistant nickname, or onboarding fields into blockers unless onboarding is the active user task in the latest turns.",
550
+ "If the latest user message is a short greeting, preserve the prior active task and last assistant stance so the next response does not restart as a fresh session.",
480
551
  "Preserve user goals, explicit instructions, decisions, files touched or inspected, code changes, commands run, test results, failures, blockers, current task state, and exact next steps.",
481
552
  "Do not invent facts. If something is uncertain, mark it as uncertain.",
482
553
  "Return Markdown only. Start with '# Compressed Working Context'."
@@ -486,12 +557,14 @@ var ContextCompactionPreflightService = class {
486
557
  content: [
487
558
  "Compress these runtime messages into a reusable working context.",
488
559
  "Include a 'Recent High-Fidelity Context' section for the latest important user/assistant turns.",
560
+ "Include a 'Continuation Contract' section after the recent context.",
489
561
  "",
490
562
  "Messages JSON:",
491
563
  stringifyCompactionSource(messages)
492
564
  ].join("\n")
493
565
  }]
494
- })).content?.trim();
566
+ });
567
+ const summary = response.content ? normalizeCompactionSummary(response.content) : "";
495
568
  if (!summary) throw new Error("context compaction summary is empty");
496
569
  return summary;
497
570
  };
@@ -535,6 +608,7 @@ var AgentRunContextCompactionManager = class {
535
608
  }
536
609
  runPreflight = async (input) => {
537
610
  const beginResult = this.preflightService.begin({
611
+ contextBlocks: input.contextBlocks,
538
612
  inputMessages: [],
539
613
  requestMetadata: input.metadata,
540
614
  sessionId: input.sessionId,
@@ -561,6 +635,37 @@ var AgentRunContextCompactionManager = class {
561
635
  };
562
636
  };
563
637
  //#endregion
638
+ //#region src/utils/agent-run-execution-metadata.utils.ts
639
+ const AGENT_RUN_EXECUTION_METADATA = {
640
+ contractVersion: 1,
641
+ modelProtocol: "ncp-agent-run",
642
+ terminalContracts: [
643
+ "chat.finish_reason",
644
+ "responses.response.completed",
645
+ "ncp.run.finished-or-error-or-abort"
646
+ ],
647
+ retryPolicy: {
648
+ requestMaxAttempts: 3,
649
+ streamMaxAttemptsBeforeVisibleOutput: 3,
650
+ scope: "transport-or-missing-terminal-before-visible-output",
651
+ runtimeStreamRetry: {
652
+ attemptLimit: null,
653
+ backoffFactor: 2,
654
+ initialDelayMs: 2e3,
655
+ maxDelayMsWithoutHeaders: 3e4,
656
+ partialAttemptDisposition: "retain-visible-parts",
657
+ scope: "retryable-model-stream-failure",
658
+ statusFields: [
659
+ "attempt",
660
+ "message",
661
+ "action",
662
+ "next"
663
+ ],
664
+ statusMetadataType: "retry"
665
+ }
666
+ }
667
+ };
668
+ //#endregion
564
669
  //#region src/managers/agent-run-request.manager.ts
565
670
  function toAgentRunRequest(envelope) {
566
671
  const metadata = envelope.metadata ?? {};
@@ -712,7 +817,8 @@ function attachRunSpecMetadata(params) {
712
817
  thinkingEffort: spec.thinkingEffort,
713
818
  projectRoot: request.projectRoot ?? session.projectRoot ?? null,
714
819
  workingDir: session.workingDir ?? null,
715
- correlationId: spec.correlationId ?? null
820
+ correlationId: spec.correlationId ?? null,
821
+ execution: structuredClone(AGENT_RUN_EXECUTION_METADATA)
716
822
  };
717
823
  return {
718
824
  ...message,
@@ -748,7 +854,12 @@ var AgentRunRequestManager = class {
748
854
  };
749
855
  handleAbortRequest = async (envelope) => {
750
856
  if (!envelope.payload?.sessionId) throw new Error("Invalid agent run abort request.");
751
- await this.abort({ sessionId: envelope.payload.sessionId });
857
+ await this.abort({
858
+ sessionId: envelope.payload.sessionId,
859
+ runId: envelope.payload.runId,
860
+ correlationId: envelope.payload.correlationId,
861
+ reason: envelope.payload.reason
862
+ });
752
863
  };
753
864
  handleSessionMessageRequest = async (envelope) => {
754
865
  if (!envelope.payload) throw new Error("Invalid agent run session message request.");
@@ -895,7 +1006,7 @@ var AgentRunRequestManager = class {
895
1006
  });
896
1007
  };
897
1008
  abort = async (request) => {
898
- this.sessionRunManager.getSessionRun(request.sessionId)?.abortRun(request.runId);
1009
+ this.sessionRunManager.getSessionRun(request.sessionId)?.abortRun(request.runId, request.reason);
899
1010
  };
900
1011
  };
901
1012
  //#endregion
@@ -3887,12 +3998,12 @@ function createProjection(sessionId, preview) {
3887
3998
  };
3888
3999
  }
3889
4000
  function formatErrorStatus(error) {
3890
- if (typeof error === "string" && error.trim()) return `运行出错:${truncatePreviewText(error)}`;
4001
+ if (typeof error === "string" && error.trim()) return `Run failed: ${truncatePreviewText(error)}`;
3891
4002
  if (error && typeof error === "object" && "message" in error) {
3892
4003
  const message = error.message;
3893
- if (typeof message === "string" && message.trim()) return `运行出错:${truncatePreviewText(message)}`;
4004
+ if (typeof message === "string" && message.trim()) return `Run failed: ${truncatePreviewText(message)}`;
3894
4005
  }
3895
- return "运行出错";
4006
+ return "Run failed";
3896
4007
  }
3897
4008
  function readToolCallId(value) {
3898
4009
  if (typeof value !== "string") return null;
@@ -3900,13 +4011,13 @@ function readToolCallId(value) {
3900
4011
  return trimmed.length > 0 ? trimmed : null;
3901
4012
  }
3902
4013
  function formatToolDoneStatus(toolName) {
3903
- return toolName ? `工具调用完成:${toolName}` : "工具调用完成";
4014
+ return toolName ? `Tool call completed: ${toolName}` : "Tool call completed";
3904
4015
  }
3905
4016
  function createSessionActivityPreviewFromNcpEvent(event, timestamp, options = {}) {
3906
4017
  switch (event.type) {
3907
4018
  case NcpEventType.RunStarted: return createProjection(readSessionId(event.payload.sessionId), {
3908
4019
  state: "running",
3909
- statusText: "正在思考",
4020
+ statusText: "Thinking",
3910
4021
  timestamp
3911
4022
  });
3912
4023
  case NcpEventType.RunFinished: return createProjection(readSessionId(event.payload.sessionId), {
@@ -3941,9 +4052,13 @@ function createSessionActivityPreviewFromNcpEvent(event, timestamp, options = {}
3941
4052
  statusText: formatErrorStatus(event.payload.error),
3942
4053
  timestamp
3943
4054
  });
4055
+ case NcpEventType.MessageAbort: return createProjection(readSessionId(event.payload.sessionId), {
4056
+ state: "cancelled",
4057
+ timestamp
4058
+ });
3944
4059
  case NcpEventType.MessageToolCallStart: return createProjection(readSessionId(event.payload.sessionId), {
3945
4060
  state: "running",
3946
- statusText: `正在调用工具:${event.payload.toolName}`,
4061
+ statusText: `Calling tool: ${event.payload.toolName}`,
3947
4062
  timestamp
3948
4063
  });
3949
4064
  case NcpEventType.MessageToolCallEnd:
@@ -3966,6 +4081,7 @@ const SESSION_ACTIVITY_PREVIEW_STATES = new Set([
3966
4081
  "running",
3967
4082
  "completed",
3968
4083
  "failed",
4084
+ "cancelled",
3969
4085
  "idle"
3970
4086
  ]);
3971
4087
  function isRecord$9(value) {
@@ -4053,7 +4169,7 @@ var SessionActivityPreviewEventService = class {
4053
4169
  };
4054
4170
  readToolName = (sessionId, toolCallId) => this.toolNames.get(this.createToolNameKey(sessionId, toolCallId)) ?? null;
4055
4171
  clearFinishedRunToolNames = (event) => {
4056
- if (event.type !== NcpEventType.RunFinished && event.type !== NcpEventType.RunError) return;
4172
+ if (event.type !== NcpEventType.RunFinished && event.type !== NcpEventType.RunError && event.type !== NcpEventType.MessageAbort) return;
4057
4173
  const sessionId = event.payload.sessionId;
4058
4174
  for (const key of this.toolNames.keys()) if (key.startsWith(`${sessionId}:`)) this.toolNames.delete(key);
4059
4175
  };
@@ -6718,11 +6834,11 @@ var SessionRun = class {
6718
6834
  signal: controller.signal
6719
6835
  };
6720
6836
  };
6721
- abortRun = (runId) => {
6837
+ abortRun = (runId, reason) => {
6722
6838
  if (!this.activeRunId || !this.activeRunController) return false;
6723
6839
  if (runId && this.activeRunId !== runId) return false;
6724
6840
  const wasRunning = this.isRunning();
6725
- this.activeRunController.abort();
6841
+ this.activeRunController.abort(reason);
6726
6842
  this.activeRunController = null;
6727
6843
  this.activeRunId = null;
6728
6844
  this.emitStatusChangeIfNeeded(wasRunning);
@@ -6731,7 +6847,11 @@ var SessionRun = class {
6731
6847
  isRunning = () => this.activeRunId !== null;
6732
6848
  dispose = () => {
6733
6849
  const wasRunning = this.isRunning();
6734
- this.activeRunController?.abort();
6850
+ this.activeRunController?.abort({
6851
+ code: "abort-error",
6852
+ message: "Session run owner was disposed; the current run was cancelled.",
6853
+ details: { source: "session-run-manager" }
6854
+ });
6735
6855
  this.activeRunController = null;
6736
6856
  this.activeRunId = null;
6737
6857
  this.emitStatusChangeIfNeeded(wasRunning);
@@ -8392,7 +8512,61 @@ var AgentRunModelInputBudgeter = class {
8392
8512
  };
8393
8513
  };
8394
8514
  //#endregion
8515
+ //#region src/utils/agent-onboarding-context.utils.ts
8516
+ const ALWAYS_SKIPPED_COMPACTED_BOOTSTRAP_FILES = new Set(["BOOT.MD", "BOOTSTRAP.MD"]);
8517
+ function normalizeBootstrapFilename(filename) {
8518
+ return filename.trim().toUpperCase();
8519
+ }
8520
+ function shouldSkipCompactedSessionBootstrapFile(filename, content) {
8521
+ const normalized = normalizeBootstrapFilename(filename);
8522
+ if (ALWAYS_SKIPPED_COMPACTED_BOOTSTRAP_FILES.has(normalized)) return true;
8523
+ if (normalized === "IDENTITY.MD") return /Fill this in during your first conversation/i.test(content);
8524
+ if (normalized === "USER.MD") return /Learn about the person you are helping/i.test(content);
8525
+ return false;
8526
+ }
8527
+ function stripCompactedSessionOnboardingSections(block) {
8528
+ const lines = block.split("\n");
8529
+ const output = [];
8530
+ let index = 0;
8531
+ while (index < lines.length) {
8532
+ const line = lines[index] ?? "";
8533
+ const heading = line.match(/^##\s+(.+?)\s*$/);
8534
+ if (!heading) {
8535
+ output.push(line);
8536
+ index += 1;
8537
+ continue;
8538
+ }
8539
+ const sectionLines = [line];
8540
+ index += 1;
8541
+ while (index < lines.length && !/^##\s+/.test(lines[index] ?? "")) {
8542
+ sectionLines.push(lines[index] ?? "");
8543
+ index += 1;
8544
+ }
8545
+ if (shouldSkipCompactedSessionBootstrapFile(heading[1] ?? "", sectionLines.join("\n"))) continue;
8546
+ output.push(...sectionLines);
8547
+ }
8548
+ return output.join("\n").trim();
8549
+ }
8550
+ //#endregion
8395
8551
  //#region src/services/agent-run-model-input-builder.service.ts
8552
+ function readSystemContent(messages) {
8553
+ return messages.filter((message) => message.role === "system").map((message) => message.content.trim()).filter(Boolean);
8554
+ }
8555
+ function partitionProjectedMessages(messages) {
8556
+ const compressedContextBlocks = [];
8557
+ const conversationMessages = [];
8558
+ for (const message of messages) {
8559
+ if (!isContextCompactionProjectionMessage(message)) {
8560
+ conversationMessages.push(message);
8561
+ continue;
8562
+ }
8563
+ compressedContextBlocks.push(...readSystemContent(ncpMessageToOpenAiMessages(message)));
8564
+ }
8565
+ return {
8566
+ compressedContextBlocks,
8567
+ conversationMessages
8568
+ };
8569
+ }
8396
8570
  var AgentRunModelInputBuilder = class {
8397
8571
  constructor(messageProjector, modelInputBudgeter, assetStore = null) {
8398
8572
  this.messageProjector = messageProjector;
@@ -8400,15 +8574,17 @@ var AgentRunModelInputBuilder = class {
8400
8574
  this.assetStore = assetStore;
8401
8575
  }
8402
8576
  build = async (request) => {
8403
- const contextContent = request.contextBlocks.map((block) => block.trim()).filter(Boolean).join("\n\n");
8577
+ const { compressedContextBlocks, conversationMessages: projectedConversationMessages } = partitionProjectedMessages(this.messageProjector.project({
8578
+ sessionId: request.sessionId,
8579
+ messages: request.messages
8580
+ }));
8581
+ const contextBlocks = compressedContextBlocks.length > 0 ? request.contextBlocks.map(stripCompactedSessionOnboardingSections) : request.contextBlocks;
8582
+ const contextContent = [...compressedContextBlocks, ...contextBlocks].map((block) => block.trim()).filter(Boolean).join("\n\n");
8404
8583
  const contextMessages = contextContent ? [{
8405
8584
  role: "system",
8406
8585
  content: contextContent
8407
8586
  }] : [];
8408
- const conversationMessages = this.messageProjector.project({
8409
- sessionId: request.sessionId,
8410
- messages: request.messages
8411
- }).flatMap((message) => ncpMessageToOpenAiMessages(message, { assetStore: this.assetStore }));
8587
+ const conversationMessages = projectedConversationMessages.flatMap((message) => ncpMessageToOpenAiMessages(message, { assetStore: this.assetStore }));
8412
8588
  const pruned = await this.modelInputBudgeter.prune({
8413
8589
  spec: request.spec,
8414
8590
  messages: [...contextMessages, ...conversationMessages]
@@ -8440,22 +8616,28 @@ var NcpAgentRuntimeWrapper = class {
8440
8616
  const { sessionRun, tools } = options;
8441
8617
  this.currentTools = tools.map(this.toOpenAiTool);
8442
8618
  const messages = sessionRun.inbox.drain();
8443
- for (const event of this.toMessageSentEvents(messages, spec, sessionRun.sessionId)) yield await this.applyEvent(sessionRun, event);
8444
- const input = {
8445
- sessionId: sessionRun.sessionId,
8446
- runId: spec.runId,
8447
- messages,
8448
- correlationId: spec.correlationId,
8449
- metadata: this.buildMetadata(options.session, spec),
8450
- executionContext: { cwd: options.session.workingDir }
8451
- };
8452
- for await (const event of this.getRuntime().run(input, { signal: options.signal })) yield await this.applyEvent(sessionRun, event);
8453
- this.currentTools = [];
8619
+ try {
8620
+ for (const event of this.toMessageSentEvents(messages, spec, sessionRun.sessionId)) yield await this.applyEvent(sessionRun, event);
8621
+ const input = {
8622
+ sessionId: sessionRun.sessionId,
8623
+ runId: spec.runId,
8624
+ messages,
8625
+ correlationId: spec.correlationId,
8626
+ metadata: this.buildMetadata(options.session, spec),
8627
+ executionContext: { cwd: options.session.workingDir }
8628
+ };
8629
+ for await (const event of this.getRuntime().run(input, { signal: options.signal })) yield await this.applyEvent(sessionRun, event);
8630
+ } finally {
8631
+ this.currentTools = [];
8632
+ }
8454
8633
  };
8455
8634
  dispose = async () => {
8635
+ await this.disposeRuntimeInstance();
8636
+ this.currentTools = [];
8637
+ };
8638
+ disposeRuntimeInstance = async () => {
8456
8639
  if (this.runtime && "dispose" in this.runtime && typeof this.runtime.dispose === "function") await this.runtime.dispose();
8457
8640
  this.runtime = null;
8458
- this.currentTools = [];
8459
8641
  };
8460
8642
  getRuntime = () => {
8461
8643
  if (!this.runtime) this.runtime = this.params.createRuntime({
@@ -8522,10 +8704,11 @@ var AgentRunRuntimeContribution = class {
8522
8704
  createRuntime: () => new DefaultNcpAgentRuntime({
8523
8705
  llmApi: new ProviderManagerNcpLLMApi(this.kernel.llmProviders),
8524
8706
  modelInputBuilder: this.modelInputBuilder,
8525
- runPreflight: async ({ spec, sessionRun }) => {
8707
+ runPreflight: async ({ contextBlocks, spec, sessionRun }) => {
8526
8708
  const session = await this.kernel.sessionManager.getAgentRunSession(sessionRun.sessionId);
8527
8709
  return await this.kernel.contextCompactionManager.runPreflight({
8528
8710
  agentId: spec.agentId,
8711
+ contextBlocks,
8529
8712
  messages: sessionRun.getSnapshot().messages,
8530
8713
  metadata: session.metadata,
8531
8714
  sessionId: sessionRun.sessionId
@@ -8570,11 +8753,13 @@ var AgentBootstrapContextProvider = class {
8570
8753
  provide = async (request) => {
8571
8754
  const { contextConfig, projectContext, runContext } = await this.context.resolve(request);
8572
8755
  const budget = this.createReadBudget(contextConfig.bootstrap);
8756
+ const compactedSession = this.hasCompressedContext(runContext.sessionMetadata);
8573
8757
  const agentBootstrapRoot = projectContext.projectBootstrapRoot ?? projectContext.effectiveWorkspace;
8574
8758
  const projectBootstrap = this.loadBootstrapFiles({
8575
8759
  root: agentBootstrapRoot,
8576
8760
  config: contextConfig.bootstrap,
8577
8761
  sessionKey: runContext.sessionKey,
8762
+ compactedSession,
8578
8763
  budget
8579
8764
  });
8580
8765
  const hasDistinctHostWorkspace = projectContext.hostWorkspace !== agentBootstrapRoot;
@@ -8582,6 +8767,7 @@ var AgentBootstrapContextProvider = class {
8582
8767
  root: projectContext.hostWorkspace,
8583
8768
  config: contextConfig.bootstrap,
8584
8769
  sessionKey: runContext.sessionKey,
8770
+ compactedSession,
8585
8771
  budget
8586
8772
  }) : "";
8587
8773
  const hasSoulFile = /##\s+SOUL\.md\b/i.test(`${projectBootstrap}\n${workspaceBootstrap}`);
@@ -8615,14 +8801,15 @@ var AgentBootstrapContextProvider = class {
8615
8801
  return lines.join("\n");
8616
8802
  };
8617
8803
  loadBootstrapFiles = (params) => {
8618
- const { budget, config, root, sessionKey } = params;
8804
+ const { budget, compactedSession, config, root, sessionKey } = params;
8619
8805
  const parts = [];
8620
- const fileList = this.selectBootstrapFiles(config, sessionKey);
8806
+ const fileList = this.selectBootstrapFiles(config, sessionKey, compactedSession);
8621
8807
  for (const filename of fileList) {
8622
8808
  const filePath = join(root, filename);
8623
8809
  if (!existsSync(filePath)) continue;
8624
8810
  const raw = readFileSync(filePath, "utf-8").trim();
8625
8811
  if (!raw) continue;
8812
+ if (compactedSession && shouldSkipCompactedSessionBootstrapFile(filename, raw)) continue;
8626
8813
  const perFileLimit = config.perFileChars > 0 ? config.perFileChars : raw.length;
8627
8814
  const allowed = Math.min(perFileLimit, budget.remaining);
8628
8815
  if (allowed <= 0) break;
@@ -8634,11 +8821,13 @@ var AgentBootstrapContextProvider = class {
8634
8821
  return parts.join("\n\n");
8635
8822
  };
8636
8823
  createReadBudget = (config) => ({ remaining: config.totalChars > 0 ? config.totalChars : Number.POSITIVE_INFINITY });
8637
- selectBootstrapFiles = (config, sessionKey) => {
8638
- if (!sessionKey) return config.files;
8824
+ selectBootstrapFiles = (config, sessionKey, compactedSession = false) => {
8825
+ if (!sessionKey) return this.filterCompactedSessionFiles(config.files, compactedSession);
8639
8826
  if (sessionKey.startsWith("cron:") || sessionKey.startsWith("subagent:")) return config.minimalFiles;
8640
- return config.files;
8827
+ return this.filterCompactedSessionFiles(config.files, compactedSession);
8641
8828
  };
8829
+ filterCompactedSessionFiles = (files, compactedSession) => compactedSession ? files.filter((filename) => !shouldSkipCompactedSessionBootstrapFile(filename, "")) : [...files];
8830
+ hasCompressedContext = (metadata) => Boolean(readCompressedContextCompactionCheckpoint(metadata?.[CONTEXT_COMPACTION_METADATA_KEY]));
8642
8831
  };
8643
8832
  //#endregion
8644
8833
  //#region src/contributions/context-provider/providers/current-session-context.provider.ts
@@ -8720,7 +8909,7 @@ const createInlineInteractiveSurfaceContextProvider = () => staticBlock([
8720
8909
  "Do not make every UI an inline card. Choose inline only when the intended result is a compact, immediately usable card or short interaction; use the side panel for normal Panel Apps, long reading, rich editing, file browsing, large tables, multi-page workflows, or sustained workspaces.",
8721
8910
  "Inline Panel App display is Markdown-only: in the final reply, output a `nextclaw-inline` fenced JSON block so the display remains message content.",
8722
8911
  "`show_panel_app` is side-panel only. Never call `show_panel_app` for inline display, including when the user asks which Panel Apps are suitable for inline display or says \"show/display them inline\".",
8723
- "For ordinary local HTML files or page prototypes, call `show_file` with `path` and `viewer=\"rendered\"`; use `viewer=\"source\"` when the user needs to inspect source text. Do not convert a plain HTML file into a Panel App just to preview it.",
8912
+ "For ordinary local HTML files or page prototypes, call `show_file` with `path` and `viewer=\"rendered\"`; use `viewer=\"source\"` when the user needs to inspect source text. Markdown file links open source by default; append `?viewer=rendered` only when the link itself should open the rendered HTML view. Do not convert a plain HTML file into a Panel App just to preview it.",
8724
8913
  "A Panel Card must be designed card-first: prefer a landscape composition where width carries the main information and the card is wider than it is tall; collapse to one column only in narrow containers. Core value must be visible in the first 220-420px, with no horizontal scrolling, no reliance on document-level internal scrolling, compact controls, at most one primary action, clear loading/empty/error states, and an obvious expand path for details.",
8725
8914
  "Typical Panel Card fits: weather cards, calculators, timers, checklists, pickers, compact forms, previews, and small dashboards. If the UI needs more space than a card, use the side panel instead. Inline hosts may pass `nextclawDisplayMode=card` and `nextclawPlacement=inline`; use those hints to render a compact card layout instead of a full page."
8726
8915
  ]);
@@ -8877,7 +9066,7 @@ var ProjectContextProvider = class {
8877
9066
  //#endregion
8878
9067
  //#region src/contributions/context-provider/providers/reply-format-context.provider.ts
8879
9068
  var ReplyFormatContextProvider = class {
8880
- provide = (_request) => ["## Reply Formatting Contract\nGoal: openable files in user-visible replies must be clickable, and inert inline display declarations are only for content that should appear as part of the reply.\nFile links: use Markdown links only, with a plain text label and an openable href: [MEMORY.md](MEMORY.md), [file](packages/example/file.ts), [notes.md](/Users/example/Documents/notes.md). Use project-relative hrefs for files under the active/session project root, and absolute hrefs for local files outside it.\nInline display: when the final reply should include a non-clickable inline display placeholder, output a fenced `nextclaw-inline` JSON block:\n```nextclaw-inline\n{\"target\":{\"type\":\"panel_app\",\"payload\":{\"appId\":\"timer\"}},\"title\":\"Timer\"}\n```\nSupported targets are `panel_app`, `json`, `file`, and `url`. Prefer `panel_app` for inline Panel App display; use `file` and `url` only as non-clickable placeholders when a clickable link is not intended; use `json` for inert JSON snapshots.\nIt is display-only: no opening, executing, or tool action. Never call `show_panel_app` for inline display; `show_panel_app` is only for immediately opening a Panel App outside the final reply in the side panel. Use Markdown links for clickable resources and show_file/show_url/show_panel_app tools only when you want the UI to immediately show or run content outside the final reply.\nForbidden forms: bare file names or paths, inline-code file names, bold-only file names, code-styled link labels, code blocks for file references, action semantics inside `nextclaw-inline`, tool calls for inline display, and unlinked comma-separated file lists.\nExamples: bad `MEMORY.md` -> good [MEMORY.md](MEMORY.md); bad `memory/` -> good [memory/](memory/); bad `2026-03-07.md` / `feishu-notes.md` -> good [2026-03-07.md](memory/2026-03-07.md) / [feishu-notes.md](memory/feishu-notes.md).\nSelf-check before sending: scan the final visible reply for local file names or paths. If every concrete file cannot be linked or intentionally represented by `nextclaw-inline`, remove the exact names and summarize instead."];
9069
+ provide = (_request) => ["## Reply Formatting Contract\nGoal: openable files in user-visible replies must be clickable, and inert inline display declarations are only for content that should appear as part of the reply.\nFile links: use Markdown links only, with a plain text label and an openable href: [MEMORY.md](MEMORY.md), [file](packages/example/file.ts), [notes.md](/Users/example/Documents/notes.md). Use project-relative hrefs for files under the active/session project root, and absolute hrefs for local files outside it. File links open source by default; use a viewer query such as [preview.html](preview.html?viewer=rendered) only when the link should open the rendered HTML view.\nInline display: when the final reply should include a non-clickable inline display placeholder, output a fenced `nextclaw-inline` JSON block:\n```nextclaw-inline\n{\"target\":{\"type\":\"panel_app\",\"payload\":{\"appId\":\"timer\"}},\"title\":\"Timer\"}\n```\nSupported targets are `panel_app`, `json`, `file`, and `url`. Prefer `panel_app` for inline Panel App display; use `file` and `url` only as non-clickable placeholders when a clickable link is not intended; use `json` for inert JSON snapshots.\nIt is display-only: no opening, executing, or tool action. Never call `show_panel_app` for inline display; `show_panel_app` is only for immediately opening a Panel App outside the final reply in the side panel. Use Markdown links for clickable resources and show_file/show_url/show_panel_app tools only when you want the UI to immediately show or run content outside the final reply.\nForbidden forms: bare file names or paths, inline-code file names, bold-only file names, code-styled link labels, code blocks for file references, action semantics inside `nextclaw-inline`, tool calls for inline display, and unlinked comma-separated file lists.\nExamples: bad `MEMORY.md` -> good [MEMORY.md](MEMORY.md); bad `memory/` -> good [memory/](memory/); bad `2026-03-07.md` / `feishu-notes.md` -> good [2026-03-07.md](memory/2026-03-07.md) / [feishu-notes.md](memory/feishu-notes.md).\nSelf-check before sending: scan the final visible reply for local file names or paths. If every concrete file cannot be linked or intentionally represented by `nextclaw-inline`, remove the exact names and summarize instead."];
8881
9070
  };
8882
9071
  //#endregion
8883
9072
  //#region src/contributions/context-provider/providers/skills-context.provider.ts
@@ -9993,7 +10182,7 @@ function normalizeShowFileArgs(args) {
9993
10182
  path: readRequiredString(params.path, "path"),
9994
10183
  line: readOptionalPositiveInteger(params.line, "line"),
9995
10184
  column: readOptionalPositiveInteger(params.column, "column"),
9996
- viewer: readOptionalEnum(params.viewer, "viewer", FILE_VIEWERS)
10185
+ viewer: readOptionalEnum(params.viewer, "viewer", FILE_VIEWERS) ?? "source"
9997
10186
  }
9998
10187
  },
9999
10188
  ...readCommonRequestFields(params, FILE_PURPOSES)
@@ -10062,7 +10251,7 @@ var ShowContentDisplayTool = class {
10062
10251
  const SHOW_CONTENT_TOOL_SPECS = [
10063
10252
  {
10064
10253
  name: "show_file",
10065
- description: "Show a local file in the current chat UI. Use viewer=\"rendered\" for rendered HTML/page previews and viewer=\"source\" for source text.",
10254
+ description: "Show a local file in the current chat UI. Defaults to source text. Use viewer=\"rendered\" for rendered HTML/page previews and viewer=\"source\" for source text.",
10066
10255
  parameters: {
10067
10256
  type: "object",
10068
10257
  properties: {
@@ -10967,6 +11156,6 @@ function resolveLegacyEventType(message) {
10967
11156
  return `message.${role || "other"}`;
10968
11157
  }
10969
11158
  //#endregion
10970
- export { AccessManager, AgentManager, AgentRunClient, AutomationManager, BuiltinNarpRuntimeProviderService, 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, PanelAppAssetTokenService, PanelAppError, PanelAppManager, PreferenceError, PreferenceManager, ProviderManagerNcpLLMApi, SERVICE_APP_MANIFEST_FILE_NAME, ServiceAppError, ServiceAppManager, SessionManager, SessionRequestManager, SkillManager, UpdateManifestReader, buildAgentRunSendPayload, buildContextCompactionModelInput, buildContextCompactionTimelineNcpMessage, buildLlmUsageSummary, buildLocalizedTextMap, buildNextclawNcpRunContext, buildServiceActionId, createAgentRuntimeSessionRequestDispatcher, createAssetTools, createContextCompactionMessageId, createContextWindowSignature, createLlmUsageRecord, describeAgentRuntimeSessionTypes, dispatchAgentRuntimeSessionRequest, dispatchChannelReplyRoute, dispatchPromptOverNcp, getServiceActionName, getServiceAppManifestPath, getUnsignedUpdateManifest, hasLlmUsageTelemetry, isContextCompactionTimelineMessage, isContextWindowSnapshot, isPanelAppAgentCapability, isPanelAppError, isPreferenceError, isReplyCapableChannel, isServiceAppError, listExtensionChannelIds, listServiceAppManifestActions, mergeServiceAppRuntimeActions, normalizeAgentRuntimeSessionTypeIcon, normalizeLlmUsageModel, normalizeOptionalString, parseServiceAppManifest, parseSkillFrontmatter, readContextWindowEventSessionId, readLatestContextCompactionCheckpoint, readLearningLoopRuntimeConfig, readMetadataModel, readMetadataThinking, readServiceAppManifest, resolveAgentRuntimeEntries, resolveChannelReplyRoute, resolveEffectiveModel, resolveLegacyEventType, resolveSessionChannelContext, runGatewayInboundLoop, sanitizeLlmUsage, serializeUnsignedUpdateManifest, shouldRefreshContextWindowDuringStream, shouldRefreshContextWindowImmediately, stripSkillFrontmatter, syncSessionThinkingPreference, toNcpMessages, waitForAgentRuntimeSessionReply };
11159
+ export { 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, PanelAppAssetTokenService, PanelAppError, PanelAppManager, PreferenceError, PreferenceManager, ProviderManagerNcpLLMApi, SERVICE_APP_MANIFEST_FILE_NAME, ServiceAppError, ServiceAppManager, SessionManager, SessionRequestManager, SkillManager, UpdateManifestReader, buildAgentRunSendPayload, buildContextCompactionModelInput, buildContextCompactionTimelineNcpMessage, buildLlmUsageSummary, buildLocalizedTextMap, buildNextclawNcpRunContext, buildServiceActionId, createAgentRuntimeSessionRequestDispatcher, createAssetTools, createContextCompactionMessageId, createContextWindowSignature, createLlmUsageRecord, describeAgentRuntimeSessionTypes, dispatchAgentRuntimeSessionRequest, dispatchChannelReplyRoute, dispatchPromptOverNcp, getServiceActionName, getServiceAppManifestPath, getUnsignedUpdateManifest, hasLlmUsageTelemetry, isContextCompactionProjectionMessage, isContextCompactionTimelineMessage, isContextWindowSnapshot, isPanelAppAgentCapability, isPanelAppError, isPreferenceError, isReplyCapableChannel, isServiceAppError, listExtensionChannelIds, listServiceAppManifestActions, mergeServiceAppRuntimeActions, normalizeAgentRuntimeSessionTypeIcon, normalizeLlmUsageModel, normalizeOptionalString, parseServiceAppManifest, parseSkillFrontmatter, readContextWindowEventSessionId, readLatestContextCompactionCheckpoint, readLearningLoopRuntimeConfig, readMetadataModel, readMetadataThinking, readServiceAppManifest, resolveAgentRuntimeEntries, resolveChannelReplyRoute, resolveEffectiveModel, resolveLegacyEventType, resolveSessionChannelContext, runGatewayInboundLoop, sanitizeLlmUsage, serializeUnsignedUpdateManifest, shouldRefreshContextWindowDuringStream, shouldRefreshContextWindowImmediately, stripSkillFrontmatter, syncSessionThinkingPreference, toNcpMessages, waitForAgentRuntimeSessionReply };
10971
11160
 
10972
11161
  //# sourceMappingURL=index.js.map