@nextclaw/kernel 0.1.6 → 0.1.7
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 +1 -0
- package/dist/index.js +179 -72
- package/package.json +14 -14
package/dist/index.d.ts
CHANGED
|
@@ -888,6 +888,7 @@ declare class NextclawNcpToolRegistry implements NcpToolRegistry {
|
|
|
888
888
|
private buildToolExecutionContext;
|
|
889
889
|
private registerDefaultTools;
|
|
890
890
|
private registerMessagingTools;
|
|
891
|
+
private resolveMessageChannels;
|
|
891
892
|
private registerExtensionTools;
|
|
892
893
|
private registerTool;
|
|
893
894
|
private registerAdditionalTools;
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { n as getUnsignedUpdateManifest, r as serializeUnsignedUpdateManifest, t
|
|
|
2
2
|
import { AgentRouteResolver, CONTEXT_COMPACTION_METADATA_KEY, ChannelManager, ChannelManager as ChannelManager$1, CommandRegistry, ContextBuilder, ContextCompactionService, ContextWindowBudgetService, CronService, CronTool, DEFAULT_SESSION_SEARCH_LIMIT, DisposableStore, EditFileTool, ExecTool, ExtensionToolAdapter, GatewayTool, InputBudgetPruner, LLMProvider, ListDirTool, LiteLLMProvider, MAX_SESSION_SEARCH_LIMIT, MemoryGetTool, MemorySearchTool, MessageBus, MessageTool, ProviderRegistry, ReadFileTool, RequestedSkillsMetadataReader, SessionManager, SessionRequestManager, SessionSearchManager, SessionsHistoryTool, SessionsListTool, Tool, ToolRegistry, WebFetchTool, WebSearchTool, WriteFileTool, buildCompressingCompactionCheckpoint, buildContextWindowSnapshot, buildMinimalSystemExecutionPrompt, buildReloadPlan, buildToolCatalogEntries, createAssistantStreamDeltaControlMessage, createAssistantStreamResetControlMessage, createToolExecutionContext, createTypingStopControlMessage, diffConfigPaths, ensureDir, expandHome, findEffectiveAgentProfile, getConfigPath, getDataDir, getSessionsPath, getWorkspacePath, loadConfig, parseAgentScopedSessionKey, parseThinkingLevel, readCompressedContextCompactionCheckpoint, readParentSessionId, readSessionProjectRoot, resolveConfigSecrets, resolveDefaultAgentProfileId, resolveProviderRuntime, resolveSessionWorkspacePath, resolveThinkingLevel, toDisposable } from "@nextclaw/core";
|
|
3
3
|
import { EventBus, Ingress, createAppEventKey, createTypedKey, eventKeys } from "@nextclaw/shared";
|
|
4
4
|
import { DefaultNcpAgentRuntime, LocalAssetStore, buildAssetContentPath, buildNcpUserContent, buildOpenAiFunctionTool } from "@nextclaw/ncp-agent-runtime";
|
|
5
|
-
import { NcpEventType, readAssistantReasoningNormalizationMode, readAssistantReasoningNormalizationModeFromMetadata, sanitizeAssistantReplyTags, writeAssistantReasoningNormalizationModeToMetadata } from "@nextclaw/ncp";
|
|
5
|
+
import { NcpEventType, consumeNcpRunHandle, createNcpRunHandle, readAssistantReasoningNormalizationMode, readAssistantReasoningNormalizationModeFromMetadata, sanitizeAssistantReplyTags, writeAssistantReasoningNormalizationModeToMetadata } from "@nextclaw/ncp";
|
|
6
6
|
import { DefaultNcpAgentBackend, DefaultNcpAgentConversationStateManager, createAgentClientFromServer } from "@nextclaw/ncp-toolkit";
|
|
7
7
|
import { basename, delimiter, dirname, join, resolve } from "node:path";
|
|
8
8
|
import { access, appendFile, mkdir, readFile, readdir, unlink, writeFile } from "node:fs/promises";
|
|
@@ -2611,7 +2611,7 @@ var NextclawNcpToolRegistry = class {
|
|
|
2611
2611
|
registerMessagingTools = (context) => {
|
|
2612
2612
|
const { channel, chatId, metadata } = context;
|
|
2613
2613
|
const accountId = readMetadataAccountId(metadata, {});
|
|
2614
|
-
const messageTool = new MessageTool((message) => this.options.bus.publishOutbound(message));
|
|
2614
|
+
const messageTool = new MessageTool((message) => this.options.bus.publishOutbound(message), { resolveChannels: this.resolveMessageChannels });
|
|
2615
2615
|
messageTool.setContext(channel, chatId, accountId ?? null);
|
|
2616
2616
|
this.registerTool(messageTool);
|
|
2617
2617
|
if (this.options.cronService) {
|
|
@@ -2620,6 +2620,10 @@ var NextclawNcpToolRegistry = class {
|
|
|
2620
2620
|
this.registerTool(cronTool);
|
|
2621
2621
|
}
|
|
2622
2622
|
};
|
|
2623
|
+
resolveMessageChannels = () => {
|
|
2624
|
+
const channels = (this.options.getExtensionRegistry?.())?.channels ?? [];
|
|
2625
|
+
return [...new Set(channels.map((registration) => registration.channel.id.trim()).filter(Boolean))].sort();
|
|
2626
|
+
};
|
|
2623
2627
|
registerExtensionTools = (context) => {
|
|
2624
2628
|
const extensionRegistry = this.options.getExtensionRegistry?.();
|
|
2625
2629
|
if (!extensionRegistry || extensionRegistry.tools.length === 0) return;
|
|
@@ -3383,35 +3387,39 @@ var AgentRuntimeManager = class {
|
|
|
3383
3387
|
}
|
|
3384
3388
|
};
|
|
3385
3389
|
};
|
|
3386
|
-
createMaterializingAgentClientEndpoint = (backend) =>
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3390
|
+
createMaterializingAgentClientEndpoint = (backend) => {
|
|
3391
|
+
const send = async (envelope) => {
|
|
3392
|
+
const requestEnvelope = this.materializeAgentSendEnvelope(envelope);
|
|
3393
|
+
return await consumeNcpRunHandle(backend.send(requestEnvelope), createNcpRunHandle(requestEnvelope));
|
|
3394
|
+
};
|
|
3395
|
+
return {
|
|
3396
|
+
get manifest() {
|
|
3397
|
+
return backend.manifest;
|
|
3398
|
+
},
|
|
3399
|
+
start: backend.start,
|
|
3400
|
+
stop: backend.stop,
|
|
3401
|
+
subscribe: backend.subscribe,
|
|
3402
|
+
stream: async (payload) => {
|
|
3403
|
+
await consumeAgentEvents(backend.stream(payload));
|
|
3404
|
+
},
|
|
3405
|
+
abort: backend.abort,
|
|
3406
|
+
send,
|
|
3407
|
+
emit: async (event) => {
|
|
3408
|
+
switch (event.type) {
|
|
3409
|
+
case NcpEventType.MessageRequest:
|
|
3410
|
+
await send(event.payload);
|
|
3411
|
+
return;
|
|
3412
|
+
case NcpEventType.MessageStreamRequest:
|
|
3413
|
+
await consumeAgentEvents(backend.stream(event.payload));
|
|
3414
|
+
return;
|
|
3415
|
+
case NcpEventType.MessageAbort:
|
|
3416
|
+
await backend.abort(event.payload);
|
|
3417
|
+
return;
|
|
3418
|
+
default: await backend.emit(event);
|
|
3419
|
+
}
|
|
3412
3420
|
}
|
|
3413
|
-
}
|
|
3414
|
-
}
|
|
3421
|
+
};
|
|
3422
|
+
};
|
|
3415
3423
|
warmDerivedCapabilities = async () => {
|
|
3416
3424
|
this.assertNotDisposed();
|
|
3417
3425
|
this.warmupPromise ??= this.runDerivedCapabilityWarmup();
|
|
@@ -4349,21 +4357,6 @@ var NcpAgentLegacySessionStore = class {
|
|
|
4349
4357
|
metadata: structuredClone(session.metadata)
|
|
4350
4358
|
};
|
|
4351
4359
|
};
|
|
4352
|
-
getSessionSummary = (sessionId) => {
|
|
4353
|
-
const session = this.getSession(sessionId);
|
|
4354
|
-
if (!session) return null;
|
|
4355
|
-
const lastMessageAt = session.messages.at(-1)?.timestamp;
|
|
4356
|
-
return {
|
|
4357
|
-
sessionId: session.sessionId,
|
|
4358
|
-
...session.agentId ? { agentId: session.agentId } : {},
|
|
4359
|
-
messageCount: session.messages.length,
|
|
4360
|
-
createdAt: session.createdAt,
|
|
4361
|
-
updatedAt: session.updatedAt,
|
|
4362
|
-
...lastMessageAt ? { lastMessageAt } : {},
|
|
4363
|
-
status: "idle",
|
|
4364
|
-
metadata: session.metadata
|
|
4365
|
-
};
|
|
4366
|
-
};
|
|
4367
4360
|
listSessionMessages = (sessionId) => this.getSession(sessionId)?.messages ?? [];
|
|
4368
4361
|
listSessionSummaries = () => this.sessionManager.listSessions().map((record) => ({
|
|
4369
4362
|
sessionId: record.key,
|
|
@@ -4429,7 +4422,6 @@ var NcpAgentSessionStoreAdapter = class {
|
|
|
4429
4422
|
};
|
|
4430
4423
|
}
|
|
4431
4424
|
getSession = async (sessionId) => await this.options.journalStore?.getSession(sessionId) ?? this.legacyStore.getSession(sessionId);
|
|
4432
|
-
getSessionSummary = async (sessionId) => await this.options.journalStore?.getSessionSummary(sessionId) ?? this.legacyStore.getSessionSummary(sessionId);
|
|
4433
4425
|
listSessionMessages = async (sessionId) => {
|
|
4434
4426
|
const journalStore = this.options.journalStore;
|
|
4435
4427
|
return journalStore && await journalStore.hasSession(sessionId) ? await journalStore.listSessionMessages(sessionId) : this.legacyStore.listSessionMessages(sessionId);
|
|
@@ -4561,10 +4553,19 @@ function upsertNcpAgentSessionSummaryEvent(params) {
|
|
|
4561
4553
|
}
|
|
4562
4554
|
async function replayNcpAgentSessionEvents(events) {
|
|
4563
4555
|
const stateManager = new DefaultNcpAgentConversationStateManager();
|
|
4564
|
-
for (const event of events) await stateManager.dispatch(
|
|
4556
|
+
for (const event of events) await stateManager.dispatch(createReplayEvent(event));
|
|
4565
4557
|
const snapshot = stateManager.getSnapshot();
|
|
4566
4558
|
return [...snapshot.messages.map((message) => structuredClone(message)), ...snapshot.streamingMessage ? [structuredClone(snapshot.streamingMessage)] : []];
|
|
4567
4559
|
}
|
|
4560
|
+
function createReplayEvent(event) {
|
|
4561
|
+
const replayEvent = structuredClone(event);
|
|
4562
|
+
if (replayEvent.type === NcpEventType.MessageCompleted) return {
|
|
4563
|
+
type: NcpEventType.MessageSent,
|
|
4564
|
+
payload: replayEvent.payload
|
|
4565
|
+
};
|
|
4566
|
+
if (replayEvent.type === NcpEventType.MessageSent && replayEvent.payload.message.role === "assistant" && (replayEvent.payload.message.status === "pending" || replayEvent.payload.message.status === "streaming")) replayEvent.payload.message.status = "final";
|
|
4567
|
+
return replayEvent;
|
|
4568
|
+
}
|
|
4568
4569
|
function readNcpSessionSummaryActivityAt(summary) {
|
|
4569
4570
|
return summary.lastMessageAt ?? summary.createdAt ?? summary.updatedAt;
|
|
4570
4571
|
}
|
|
@@ -4602,19 +4603,14 @@ function readSummaryLabelFromEvent(event) {
|
|
|
4602
4603
|
if (message?.role !== "user") return null;
|
|
4603
4604
|
return resolveAutoSessionLabel([message]);
|
|
4604
4605
|
}
|
|
4605
|
-
function createCompletedMessageEvent(event) {
|
|
4606
|
-
return {
|
|
4607
|
-
type: NcpEventType.MessageSent,
|
|
4608
|
-
payload: {
|
|
4609
|
-
sessionId: event.payload.sessionId,
|
|
4610
|
-
message: structuredClone(event.payload.message),
|
|
4611
|
-
...event.payload.correlationId ? { correlationId: event.payload.correlationId } : {},
|
|
4612
|
-
metadata: event.payload.metadata
|
|
4613
|
-
}
|
|
4614
|
-
};
|
|
4615
|
-
}
|
|
4616
4606
|
//#endregion
|
|
4617
4607
|
//#region src/stores/ncp-agent-session-journal.store.ts
|
|
4608
|
+
function serializeJournalEntry(entry) {
|
|
4609
|
+
const serialized = JSON.stringify(entry);
|
|
4610
|
+
if (!serialized) throw new Error("ncp agent session journal entry serialization produced empty output");
|
|
4611
|
+
if (!isRecord$1(JSON.parse(serialized))) throw new Error("ncp agent session journal entry serialization produced a non-object entry");
|
|
4612
|
+
return serialized;
|
|
4613
|
+
}
|
|
4618
4614
|
var NcpAgentSessionJournalStore = class {
|
|
4619
4615
|
sessions = /* @__PURE__ */ new Map();
|
|
4620
4616
|
nextSeqBySession = /* @__PURE__ */ new Map();
|
|
@@ -4646,14 +4642,6 @@ var NcpAgentSessionJournalStore = class {
|
|
|
4646
4642
|
this.sessions.set(normalizedSessionId, loaded);
|
|
4647
4643
|
return structuredClone(loaded.record);
|
|
4648
4644
|
};
|
|
4649
|
-
getSessionSummary = async (sessionId) => {
|
|
4650
|
-
const normalizedSessionId = normalizeNcpSessionId(sessionId);
|
|
4651
|
-
if (!normalizedSessionId) return null;
|
|
4652
|
-
const indexed = (await this.loadSummaryIndex()).get(normalizedSessionId);
|
|
4653
|
-
if (indexed) return structuredClone(indexed);
|
|
4654
|
-
const record = await this.getSession(normalizedSessionId);
|
|
4655
|
-
return record ? createNcpAgentSessionSummary(record) : null;
|
|
4656
|
-
};
|
|
4657
4645
|
listSessionSummaries = async () => {
|
|
4658
4646
|
return [...(await this.loadSummaryIndex()).values()].map((summary) => structuredClone(summary)).sort((left, right) => readNcpSessionSummaryActivityAt(right).localeCompare(readNcpSessionSummaryActivityAt(left)));
|
|
4659
4647
|
};
|
|
@@ -4682,7 +4670,7 @@ var NcpAgentSessionJournalStore = class {
|
|
|
4682
4670
|
}
|
|
4683
4671
|
}
|
|
4684
4672
|
}))];
|
|
4685
|
-
await writeFile(this.sessionPath(sessionId), `${entries.map(
|
|
4673
|
+
await writeFile(this.sessionPath(sessionId), `${entries.map(serializeJournalEntry).join("\n")}\n`, "utf-8");
|
|
4686
4674
|
const nextSeq = nextRecord.messages.length + 1;
|
|
4687
4675
|
this.sessions.set(sessionId, {
|
|
4688
4676
|
record: nextRecord,
|
|
@@ -4716,7 +4704,7 @@ var NcpAgentSessionJournalStore = class {
|
|
|
4716
4704
|
const hasJournal = Boolean(existing) || this.nextSeqBySession.has(sessionId);
|
|
4717
4705
|
const nextSeq = this.nextSeqBySession.get(sessionId) ?? existing?.nextSeq ?? 1;
|
|
4718
4706
|
const path = this.sessionPath(sessionId);
|
|
4719
|
-
if (!hasJournal) await
|
|
4707
|
+
if (!hasJournal) await this.appendJournalEntry(path, createNcpAgentSessionJournalMetadataEntry(session));
|
|
4720
4708
|
const entry = {
|
|
4721
4709
|
_type: "event",
|
|
4722
4710
|
version: 1,
|
|
@@ -4724,7 +4712,7 @@ var NcpAgentSessionJournalStore = class {
|
|
|
4724
4712
|
timestamp: updatedAt,
|
|
4725
4713
|
event: structuredClone(event)
|
|
4726
4714
|
};
|
|
4727
|
-
await
|
|
4715
|
+
await this.appendJournalEntry(path, entry);
|
|
4728
4716
|
this.nextSeqBySession.set(sessionId, nextSeq + 1);
|
|
4729
4717
|
this.sessions.delete(sessionId);
|
|
4730
4718
|
await this.upsertSummaryIndexForEvent({
|
|
@@ -4763,9 +4751,15 @@ var NcpAgentSessionJournalStore = class {
|
|
|
4763
4751
|
let updatedAt = createdAt;
|
|
4764
4752
|
let nextSeq = 1;
|
|
4765
4753
|
const events = [];
|
|
4766
|
-
for (const line of raw.split("\n")) {
|
|
4754
|
+
for (const [index, line] of raw.split("\n").entries()) {
|
|
4767
4755
|
if (!line.trim()) continue;
|
|
4768
|
-
|
|
4756
|
+
let parsed;
|
|
4757
|
+
try {
|
|
4758
|
+
parsed = JSON.parse(line);
|
|
4759
|
+
} catch (error) {
|
|
4760
|
+
console.warn(`[ncp-agent-session-journal] skipped corrupted journal line ${index + 1}: ${error instanceof Error ? error.message : String(error)}`);
|
|
4761
|
+
continue;
|
|
4762
|
+
}
|
|
4769
4763
|
if (!isRecord$1(parsed)) continue;
|
|
4770
4764
|
if (parsed._type === "metadata") {
|
|
4771
4765
|
metadata = isRecord$1(parsed.metadata) ? structuredClone(parsed.metadata) : {};
|
|
@@ -4790,6 +4784,9 @@ var NcpAgentSessionJournalStore = class {
|
|
|
4790
4784
|
events
|
|
4791
4785
|
};
|
|
4792
4786
|
};
|
|
4787
|
+
appendJournalEntry = async (path, entry) => {
|
|
4788
|
+
await appendFile(path, `${serializeJournalEntry(entry)}\n`, "utf-8");
|
|
4789
|
+
};
|
|
4793
4790
|
loadSummaryIndex = async () => {
|
|
4794
4791
|
if (this.summaryIndex) return this.summaryIndex;
|
|
4795
4792
|
try {
|
|
@@ -4858,6 +4855,116 @@ var NcpAgentSessionJournalStore = class {
|
|
|
4858
4855
|
indexPath = () => resolve(this.journalDir, NCP_AGENT_SESSION_JOURNAL_INDEX_FILE);
|
|
4859
4856
|
};
|
|
4860
4857
|
//#endregion
|
|
4858
|
+
//#region src/contributions/session-context-window/index.ts
|
|
4859
|
+
const STREAM_REFRESH_DELAY_MS = 1500;
|
|
4860
|
+
function formatBackgroundError$1(error) {
|
|
4861
|
+
if (error instanceof Error) return error.stack ?? error.message;
|
|
4862
|
+
return String(error);
|
|
4863
|
+
}
|
|
4864
|
+
function readEventSessionId(event) {
|
|
4865
|
+
const payload = "payload" in event ? event.payload : null;
|
|
4866
|
+
if (!payload || typeof payload !== "object") return null;
|
|
4867
|
+
return "sessionId" in payload && typeof payload.sessionId === "string" ? payload.sessionId.trim() || null : null;
|
|
4868
|
+
}
|
|
4869
|
+
function isContextWindow(value) {
|
|
4870
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
4871
|
+
}
|
|
4872
|
+
function createSignature(value) {
|
|
4873
|
+
return JSON.stringify(value);
|
|
4874
|
+
}
|
|
4875
|
+
function shouldRefreshDuringStream(event) {
|
|
4876
|
+
switch (event.type) {
|
|
4877
|
+
case NcpEventType.MessageTextDelta:
|
|
4878
|
+
case NcpEventType.MessageReasoningDelta:
|
|
4879
|
+
case NcpEventType.MessageToolCallArgsDelta:
|
|
4880
|
+
case NcpEventType.MessageToolCallResult: return true;
|
|
4881
|
+
default: return false;
|
|
4882
|
+
}
|
|
4883
|
+
}
|
|
4884
|
+
function shouldRefreshImmediately(event) {
|
|
4885
|
+
switch (event.type) {
|
|
4886
|
+
case NcpEventType.MessageCompleted:
|
|
4887
|
+
case NcpEventType.MessageFailed:
|
|
4888
|
+
case NcpEventType.MessageAbort:
|
|
4889
|
+
case NcpEventType.RunFinished:
|
|
4890
|
+
case NcpEventType.RunError: return true;
|
|
4891
|
+
default: return false;
|
|
4892
|
+
}
|
|
4893
|
+
}
|
|
4894
|
+
var SessionContextWindowContribution = class {
|
|
4895
|
+
unsubscribeNcpEvent = null;
|
|
4896
|
+
stopped = true;
|
|
4897
|
+
pendingTimers = /* @__PURE__ */ new Map();
|
|
4898
|
+
lastPublishedSignatureBySession = /* @__PURE__ */ new Map();
|
|
4899
|
+
constructor(kernel) {
|
|
4900
|
+
this.kernel = kernel;
|
|
4901
|
+
}
|
|
4902
|
+
start = () => {
|
|
4903
|
+
if (this.unsubscribeNcpEvent) return;
|
|
4904
|
+
this.stopped = false;
|
|
4905
|
+
this.unsubscribeNcpEvent = this.kernel.eventBus.on(eventKeys.ncpEvent, this.handleNcpEvent);
|
|
4906
|
+
};
|
|
4907
|
+
dispose = () => {
|
|
4908
|
+
this.unsubscribeNcpEvent?.();
|
|
4909
|
+
this.unsubscribeNcpEvent = null;
|
|
4910
|
+
this.stopped = true;
|
|
4911
|
+
for (const timer of this.pendingTimers.values()) clearTimeout(timer);
|
|
4912
|
+
this.pendingTimers.clear();
|
|
4913
|
+
this.lastPublishedSignatureBySession.clear();
|
|
4914
|
+
};
|
|
4915
|
+
handleNcpEvent = (event) => {
|
|
4916
|
+
const sessionId = readEventSessionId(event);
|
|
4917
|
+
if (!sessionId) return;
|
|
4918
|
+
if (event.type === NcpEventType.ContextWindowUpdated) {
|
|
4919
|
+
this.rememberPublishedContextWindow(sessionId, event.payload.contextWindow);
|
|
4920
|
+
return;
|
|
4921
|
+
}
|
|
4922
|
+
if (shouldRefreshImmediately(event)) {
|
|
4923
|
+
this.refreshNow(sessionId);
|
|
4924
|
+
return;
|
|
4925
|
+
}
|
|
4926
|
+
if (shouldRefreshDuringStream(event)) this.refreshSoon(sessionId);
|
|
4927
|
+
};
|
|
4928
|
+
refreshSoon = (sessionId) => {
|
|
4929
|
+
if (this.pendingTimers.has(sessionId)) return;
|
|
4930
|
+
const timer = setTimeout(() => {
|
|
4931
|
+
this.pendingTimers.delete(sessionId);
|
|
4932
|
+
this.refreshNow(sessionId);
|
|
4933
|
+
}, STREAM_REFRESH_DELAY_MS);
|
|
4934
|
+
this.pendingTimers.set(sessionId, timer);
|
|
4935
|
+
};
|
|
4936
|
+
refreshNow = (sessionId) => {
|
|
4937
|
+
const timer = this.pendingTimers.get(sessionId);
|
|
4938
|
+
if (timer) {
|
|
4939
|
+
clearTimeout(timer);
|
|
4940
|
+
this.pendingTimers.delete(sessionId);
|
|
4941
|
+
}
|
|
4942
|
+
this.publishContextWindow(sessionId).catch((error) => {
|
|
4943
|
+
console.error(`[session-context-window] failed to refresh ${sessionId}: ${formatBackgroundError$1(error)}`);
|
|
4944
|
+
});
|
|
4945
|
+
};
|
|
4946
|
+
publishContextWindow = async (sessionId) => {
|
|
4947
|
+
if (this.stopped) return;
|
|
4948
|
+
const contextWindow = (await this.kernel.ncpSessionApi.getSession(sessionId))?.contextWindow;
|
|
4949
|
+
if (!isContextWindow(contextWindow) || this.stopped) return;
|
|
4950
|
+
const endpoint = this.kernel.agentRuntimeManager.currentHandle?.agentClientEndpoint;
|
|
4951
|
+
if (!endpoint) return;
|
|
4952
|
+
const signature = createSignature(contextWindow);
|
|
4953
|
+
if (this.lastPublishedSignatureBySession.get(sessionId) === signature) return;
|
|
4954
|
+
this.lastPublishedSignatureBySession.set(sessionId, signature);
|
|
4955
|
+
await endpoint.emit({
|
|
4956
|
+
type: NcpEventType.ContextWindowUpdated,
|
|
4957
|
+
payload: {
|
|
4958
|
+
sessionId,
|
|
4959
|
+
contextWindow
|
|
4960
|
+
}
|
|
4961
|
+
});
|
|
4962
|
+
};
|
|
4963
|
+
rememberPublishedContextWindow = (sessionId, contextWindow) => {
|
|
4964
|
+
this.lastPublishedSignatureBySession.set(sessionId, createSignature(contextWindow));
|
|
4965
|
+
};
|
|
4966
|
+
};
|
|
4967
|
+
//#endregion
|
|
4861
4968
|
//#region src/contributions/session-activity-preview/utils/session-activity-preview-ncp-event.utils.ts
|
|
4862
4969
|
const PREVIEW_TEXT_MAX_LENGTH = 160;
|
|
4863
4970
|
function readSessionId(value) {
|
|
@@ -5159,7 +5266,7 @@ var NextclawKernel = class {
|
|
|
5159
5266
|
sessionRequester: this.sessionRequests,
|
|
5160
5267
|
resolveLearningLoopConfig: () => readLearningLoopRuntimeConfig(this.configManager.loadConfig())
|
|
5161
5268
|
});
|
|
5162
|
-
this.contributions = [new SessionActivityPreviewContribution(this)];
|
|
5269
|
+
this.contributions = [new SessionActivityPreviewContribution(this), new SessionContextWindowContribution(this)];
|
|
5163
5270
|
}
|
|
5164
5271
|
start = async () => {
|
|
5165
5272
|
this.ncpSessionApi.start();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextclaw/kernel",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "NextClaw product kernel skeleton for agents, tasks, sessions, context, tools, skills, providers, automation, and channels.",
|
|
6
6
|
"type": "module",
|
|
@@ -20,19 +20,19 @@
|
|
|
20
20
|
"dist"
|
|
21
21
|
],
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@nextclaw/core": "0.12.
|
|
24
|
-
"@nextclaw/
|
|
25
|
-
"@nextclaw/
|
|
26
|
-
"@nextclaw/ncp-
|
|
27
|
-
"@nextclaw/
|
|
28
|
-
"@nextclaw/ncp-toolkit": "0.5.
|
|
29
|
-
"@nextclaw/nextclaw-
|
|
30
|
-
"@nextclaw/
|
|
31
|
-
"@nextclaw/
|
|
32
|
-
"@nextclaw/
|
|
33
|
-
"@nextclaw/
|
|
34
|
-
"@nextclaw/
|
|
35
|
-
"@nextclaw/ncp-
|
|
23
|
+
"@nextclaw/core": "0.12.18",
|
|
24
|
+
"@nextclaw/ncp-http-agent-server": "0.3.23",
|
|
25
|
+
"@nextclaw/mcp": "0.1.83",
|
|
26
|
+
"@nextclaw/ncp-agent-runtime": "0.3.21",
|
|
27
|
+
"@nextclaw/ncp-mcp": "0.1.85",
|
|
28
|
+
"@nextclaw/ncp-toolkit": "0.5.16",
|
|
29
|
+
"@nextclaw/nextclaw-hermes-acp-bridge": "0.1.10",
|
|
30
|
+
"@nextclaw/nextclaw-ncp-runtime-stdio-client": "0.1.11",
|
|
31
|
+
"@nextclaw/ncp": "0.5.11",
|
|
32
|
+
"@nextclaw/openclaw-compat": "1.0.18",
|
|
33
|
+
"@nextclaw/runtime": "0.2.50",
|
|
34
|
+
"@nextclaw/shared": "0.1.5",
|
|
35
|
+
"@nextclaw/nextclaw-ncp-runtime-http-client": "0.1.10"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/node": "^20.17.6",
|