@nextclaw/kernel 0.6.19 → 0.6.21
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 +43 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +546 -144
- package/dist/index.js.map +1 -1
- package/package.json +12 -12
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { APP_NAME, AgentRouteResolver, BUILTIN_MAIN_AGENT_ID, CLEAR_THINKING_TOK
|
|
|
5
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_INLINE_TOKENS_SCHEMA_VERSION, CHAT_PROJECT_TOKEN_KIND, CHAT_SESSION_MATERIALIZATION_METADATA_KEY, CHAT_WORKSPACE_DIRECTORY_TOKEN_KIND, CHAT_WORKSPACE_FILE_TOKEN_KIND, EventBus, Ingress, PANEL_APP_INLINE_HOST_CONTRACT, UI_CONTENT_PARAMS_HOST_CONTRACT, eventKeys, ingressKeys, isRuntimeDefaultModelValue, normalizeRuntimeModelSelectionMode, readInlineContentHeight, readUiContentParams } from "@nextclaw/shared";
|
|
8
|
+
import { CHAT_INLINE_TOKENS_METADATA_KEY, CHAT_INLINE_TOKENS_SCHEMA_VERSION, CHAT_PROJECT_TOKEN_KIND, CHAT_SESSION_MATERIALIZATION_METADATA_KEY, CHAT_WORKSPACE_DIRECTORY_TOKEN_KIND, CHAT_WORKSPACE_FILE_TOKEN_KIND, EventBus, INBOX_DELIVERY_SESSION_METADATA_KEY, Ingress, PANEL_APP_INLINE_HOST_CONTRACT, UI_CONTENT_PARAMS_HOST_CONTRACT, eventKeys, ingressKeys, isRuntimeDefaultModelValue, normalizeRuntimeModelSelectionMode, readInlineContentHeight, readUiContentParams } from "@nextclaw/shared";
|
|
9
9
|
import { catchError, filter, 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";
|
|
@@ -693,13 +693,13 @@ function createUnavailableAiExecutionMetadataEvent(params) {
|
|
|
693
693
|
}
|
|
694
694
|
//#endregion
|
|
695
695
|
//#region src/utils/agent-run-request.utils.ts
|
|
696
|
-
function readOptionalString$
|
|
696
|
+
function readOptionalString$12(value) {
|
|
697
697
|
if (typeof value !== "string") return;
|
|
698
698
|
return value.trim() || void 0;
|
|
699
699
|
}
|
|
700
700
|
function toAgentRunRequest(envelope) {
|
|
701
701
|
const metadata = envelope.metadata ?? {};
|
|
702
|
-
const peerId = readOptionalString$
|
|
702
|
+
const peerId = readOptionalString$12(envelope.peerId);
|
|
703
703
|
const requestMetadata = {
|
|
704
704
|
agentRuntimeId: metadata.agentRuntimeId,
|
|
705
705
|
agentId: metadata.agentId,
|
|
@@ -712,7 +712,7 @@ function toAgentRunRequest(envelope) {
|
|
|
712
712
|
thinkingEffort: metadata.thinkingEffort
|
|
713
713
|
};
|
|
714
714
|
if (Array.isArray(envelope.content)) {
|
|
715
|
-
const sessionId = readOptionalString$
|
|
715
|
+
const sessionId = readOptionalString$12(envelope.sessionId);
|
|
716
716
|
if (sessionId && peerId) throw new Error("agent-run.send cannot accept both sessionId and peerId.");
|
|
717
717
|
return {
|
|
718
718
|
...requestMetadata,
|
|
@@ -730,8 +730,8 @@ function toAgentRunRequest(envelope) {
|
|
|
730
730
|
}
|
|
731
731
|
const sourceMessage = envelope.message;
|
|
732
732
|
if (!sourceMessage) throw new Error("Invalid agent run send request.");
|
|
733
|
-
const envelopeSessionId = readOptionalString$
|
|
734
|
-
const messageSessionId = readOptionalString$
|
|
733
|
+
const envelopeSessionId = readOptionalString$12(envelope.sessionId);
|
|
734
|
+
const messageSessionId = readOptionalString$12(sourceMessage.sessionId);
|
|
735
735
|
const sessionId = envelopeSessionId ?? messageSessionId;
|
|
736
736
|
if (sessionId && peerId) throw new Error("agent-run.send cannot accept both sessionId and peerId.");
|
|
737
737
|
return {
|
|
@@ -792,7 +792,7 @@ function readSessionMaterialization(metadata) {
|
|
|
792
792
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
793
793
|
const materialization = value;
|
|
794
794
|
if (materialization.kind !== "child") throw new Error("session_materialization.kind must be \"child\".");
|
|
795
|
-
const parentSessionId = readOptionalString$
|
|
795
|
+
const parentSessionId = readOptionalString$12(materialization.parentSessionId);
|
|
796
796
|
if (!parentSessionId) throw new Error("session_materialization.parentSessionId is required.");
|
|
797
797
|
if (materialization.inheritContext !== true) throw new Error("session_materialization.inheritContext must be true.");
|
|
798
798
|
return {
|
|
@@ -2737,7 +2737,7 @@ function readString$5(value) {
|
|
|
2737
2737
|
function readRecord$1(value) {
|
|
2738
2738
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
2739
2739
|
}
|
|
2740
|
-
function readRequiredString$
|
|
2740
|
+
function readRequiredString$8(value, name) {
|
|
2741
2741
|
const trimmed = readString$5(value);
|
|
2742
2742
|
if (!trimmed) throw new Error(`${name} is required`);
|
|
2743
2743
|
return trimmed;
|
|
@@ -2768,9 +2768,9 @@ function readInboundAttachments(value) {
|
|
|
2768
2768
|
function toInboundMessage(value) {
|
|
2769
2769
|
const payload = readRecord$1(value);
|
|
2770
2770
|
return {
|
|
2771
|
-
channel: readRequiredString$
|
|
2772
|
-
chatId: readRequiredString$
|
|
2773
|
-
senderId: readRequiredString$
|
|
2771
|
+
channel: readRequiredString$8(payload.channelId, "channelId"),
|
|
2772
|
+
chatId: readRequiredString$8(payload.conversationId, "conversationId"),
|
|
2773
|
+
senderId: readRequiredString$8(payload.senderId, "senderId"),
|
|
2774
2774
|
content: readTextContent(payload.content),
|
|
2775
2775
|
timestamp: /* @__PURE__ */ new Date(),
|
|
2776
2776
|
attachments: readInboundAttachments(payload.attachments),
|
|
@@ -2792,7 +2792,7 @@ function normalizeAuthPollResult(value) {
|
|
|
2792
2792
|
if (!value) return null;
|
|
2793
2793
|
const record = readRecord$1(value);
|
|
2794
2794
|
return {
|
|
2795
|
-
channel: readRequiredString$
|
|
2795
|
+
channel: readRequiredString$8(record.channel, "channel"),
|
|
2796
2796
|
status: record.status,
|
|
2797
2797
|
message: readString$5(record.message),
|
|
2798
2798
|
nextPollMs: readOptionalNumber(record.nextPollMs),
|
|
@@ -2890,7 +2890,7 @@ var ExtensionRuntimeService = class {
|
|
|
2890
2890
|
if (running.length > 0) console.log(`✓ Extensions started: ${running.map((entry) => entry.manifest.id).join(", ")}`);
|
|
2891
2891
|
};
|
|
2892
2892
|
getExtensionProcessToken = (extensionId) => {
|
|
2893
|
-
const id = readRequiredString$
|
|
2893
|
+
const id = readRequiredString$8(extensionId, "extensionId");
|
|
2894
2894
|
const current = this.extensionTokens.get(id);
|
|
2895
2895
|
if (current) return current;
|
|
2896
2896
|
const token = randomUUID();
|
|
@@ -2953,7 +2953,7 @@ var ExtensionRuntimeService = class {
|
|
|
2953
2953
|
};
|
|
2954
2954
|
handleChannelConfigGet = (envelope, context) => {
|
|
2955
2955
|
this.assertAuthorized(envelope, context);
|
|
2956
|
-
const channelId = readRequiredString$
|
|
2956
|
+
const channelId = readRequiredString$8(readRecord$1(envelope.payload).channelId, "channelId");
|
|
2957
2957
|
return { config: this.options.getConfig().channels[channelId] ?? {} };
|
|
2958
2958
|
};
|
|
2959
2959
|
handleChannelMessageSubmit = async (envelope, context) => {
|
|
@@ -2968,9 +2968,9 @@ var ExtensionRuntimeService = class {
|
|
|
2968
2968
|
handleChannelCommandExecute = async (envelope, context) => {
|
|
2969
2969
|
this.assertAuthorized(envelope, context);
|
|
2970
2970
|
const payload = readRecord$1(envelope.payload);
|
|
2971
|
-
const channel = readRequiredString$
|
|
2972
|
-
const chatId = readRequiredString$
|
|
2973
|
-
const senderId = readRequiredString$
|
|
2971
|
+
const channel = readRequiredString$8(payload.channelId, "channelId");
|
|
2972
|
+
const chatId = readRequiredString$8(payload.conversationId, "conversationId");
|
|
2973
|
+
const senderId = readRequiredString$8(payload.senderId, "senderId");
|
|
2974
2974
|
const metadata = readRecord$1(payload.metadata);
|
|
2975
2975
|
const config = this.options.getConfig();
|
|
2976
2976
|
const registry = new CommandRegistry(config, this.options.sessionManager);
|
|
@@ -2997,7 +2997,7 @@ var ExtensionRuntimeService = class {
|
|
|
2997
2997
|
content: "",
|
|
2998
2998
|
ephemeral: true
|
|
2999
2999
|
};
|
|
3000
|
-
return await registry.execute(readRequiredString$
|
|
3000
|
+
return await registry.execute(readRequiredString$8(payload.commandName, "commandName"), readRecord$1(payload.args), {
|
|
3001
3001
|
channel,
|
|
3002
3002
|
chatId,
|
|
3003
3003
|
senderId,
|
|
@@ -3007,7 +3007,7 @@ var ExtensionRuntimeService = class {
|
|
|
3007
3007
|
handleExtensionResponse = (envelope, context) => {
|
|
3008
3008
|
this.assertAuthorized(envelope, context);
|
|
3009
3009
|
const payload = readRecord$1(envelope.payload);
|
|
3010
|
-
const requestId = readRequiredString$
|
|
3010
|
+
const requestId = readRequiredString$8(payload.requestId, "requestId");
|
|
3011
3011
|
const pending = this.pendingRequests.get(requestId);
|
|
3012
3012
|
if (!pending) return { accepted: false };
|
|
3013
3013
|
this.pendingRequests.delete(requestId);
|
|
@@ -3293,6 +3293,7 @@ var LlmProviderManager = class {
|
|
|
3293
3293
|
models: [],
|
|
3294
3294
|
modelConfig: {}
|
|
3295
3295
|
},
|
|
3296
|
+
apiKey: this.resolveProviderApiKey(input.providerName, input.apiKey),
|
|
3296
3297
|
apiBase: input.apiBase ?? null,
|
|
3297
3298
|
model: input.defaultModel
|
|
3298
3299
|
}).chat({
|
|
@@ -3315,6 +3316,7 @@ var LlmProviderManager = class {
|
|
|
3315
3316
|
providerId: route.providerId,
|
|
3316
3317
|
providerName: name,
|
|
3317
3318
|
provider,
|
|
3319
|
+
apiKey: this.resolveProviderApiKey(name, provider?.apiKey),
|
|
3318
3320
|
apiBase: provider?.apiBase ?? providerSpec?.defaultApiBase ?? null,
|
|
3319
3321
|
modelConfig: {
|
|
3320
3322
|
...specModelConfig,
|
|
@@ -3345,7 +3347,7 @@ var LlmProviderManager = class {
|
|
|
3345
3347
|
provider,
|
|
3346
3348
|
spec: providerType ? this.providerRegistry.findProviderByName(providerType) : void 0
|
|
3347
3349
|
};
|
|
3348
|
-
}).filter((entry) => Boolean(entry.name && entry.spec)).filter((entry) => entry.provider
|
|
3350
|
+
}).filter((entry) => Boolean(entry.name && entry.spec)).filter((entry) => entry.provider.enabled !== false && Boolean(this.resolveProviderApiKey(entry.name, entry.provider.apiKey))).filter((entry) => entry.spec.keywords.some((keyword) => modelLower.includes(keyword)));
|
|
3349
3351
|
if (keywordMatches.length === 1) {
|
|
3350
3352
|
const match = keywordMatches[0];
|
|
3351
3353
|
const providerId = match.providerId;
|
|
@@ -3363,7 +3365,7 @@ var LlmProviderManager = class {
|
|
|
3363
3365
|
model
|
|
3364
3366
|
};
|
|
3365
3367
|
const builtinNames = new Set(specs.map((spec) => spec.name));
|
|
3366
|
-
const enabledProviders = Object.entries(providers).filter(([, provider]) => provider.enabled !== false && Boolean(provider.apiKey));
|
|
3368
|
+
const enabledProviders = Object.entries(providers).filter(([providerId, provider]) => provider.enabled !== false && Boolean(this.resolveProviderApiKey(this.resolveProviderType(providerId, provider), provider.apiKey)));
|
|
3367
3369
|
const enabledBuiltin = enabledProviders.filter(([name]) => builtinNames.has(name));
|
|
3368
3370
|
if (enabledBuiltin.length === 1) {
|
|
3369
3371
|
const [name, provider] = enabledBuiltin[0];
|
|
@@ -3416,6 +3418,11 @@ var LlmProviderManager = class {
|
|
|
3416
3418
|
if (configuredType && this.providerRegistry.findProviderByName(configuredType)) return configuredType;
|
|
3417
3419
|
return this.providerRegistry.findProviderByName(providerId) ? providerId : null;
|
|
3418
3420
|
};
|
|
3421
|
+
resolveProviderApiKey = (providerName, configuredApiKey) => {
|
|
3422
|
+
const normalizedConfiguredKey = typeof configuredApiKey === "string" ? configuredApiKey.trim() : "";
|
|
3423
|
+
if (normalizedConfiguredKey) return normalizedConfiguredKey;
|
|
3424
|
+
return (providerName ? this.providerRegistry.findProviderByName(providerName)?.anonymousApiKey?.trim() : "") || null;
|
|
3425
|
+
};
|
|
3419
3426
|
rewriteModelForTemplate = (model, providerId, providerType) => {
|
|
3420
3427
|
const prefix = `${providerId}/`;
|
|
3421
3428
|
if (!model.startsWith(prefix)) return model;
|
|
@@ -3431,7 +3438,7 @@ var LlmProviderManager = class {
|
|
|
3431
3438
|
return rewritten;
|
|
3432
3439
|
};
|
|
3433
3440
|
getOrCreateProvider = (route) => {
|
|
3434
|
-
if (!route.
|
|
3441
|
+
if (!route.apiKey && !route.model.startsWith("bedrock/")) return this.missingProvider;
|
|
3435
3442
|
const cacheKey = this.buildCacheKey(route);
|
|
3436
3443
|
const cached = this.providerPool.get(cacheKey);
|
|
3437
3444
|
if (cached) return cached;
|
|
@@ -3441,7 +3448,7 @@ var LlmProviderManager = class {
|
|
|
3441
3448
|
};
|
|
3442
3449
|
createProvider = (route) => {
|
|
3443
3450
|
return new LiteLLMProvider({
|
|
3444
|
-
apiKey: route.
|
|
3451
|
+
apiKey: route.apiKey,
|
|
3445
3452
|
apiBase: route.apiBase,
|
|
3446
3453
|
defaultModel: route.model,
|
|
3447
3454
|
extraHeaders: route.provider?.extraHeaders ?? null,
|
|
@@ -3465,7 +3472,7 @@ var LlmProviderManager = class {
|
|
|
3465
3472
|
return [
|
|
3466
3473
|
route.providerName ?? "",
|
|
3467
3474
|
route.providerId ?? "",
|
|
3468
|
-
|
|
3475
|
+
route.apiKey ?? "",
|
|
3469
3476
|
route.apiBase ?? "",
|
|
3470
3477
|
routeProvider?.wireApi ?? "",
|
|
3471
3478
|
headersFingerprint(routeProvider?.extraHeaders ?? null)
|
|
@@ -3689,6 +3696,228 @@ var LlmUsageManager = class {
|
|
|
3689
3696
|
};
|
|
3690
3697
|
};
|
|
3691
3698
|
//#endregion
|
|
3699
|
+
//#region src/stores/inbox-delivery.store.ts
|
|
3700
|
+
const INBOX_DELIVERY_STORE_VERSION = 1;
|
|
3701
|
+
var InboxDeliveryStoreError = class extends Error {
|
|
3702
|
+
constructor(message) {
|
|
3703
|
+
super(message);
|
|
3704
|
+
this.name = "InboxDeliveryStoreError";
|
|
3705
|
+
}
|
|
3706
|
+
};
|
|
3707
|
+
var InboxDeliveryStore = class {
|
|
3708
|
+
constructor(storePath) {
|
|
3709
|
+
this.storePath = storePath;
|
|
3710
|
+
}
|
|
3711
|
+
list = async () => {
|
|
3712
|
+
try {
|
|
3713
|
+
return this.parseStoreFile(await readFile(this.storePath, "utf8")).deliveries;
|
|
3714
|
+
} catch (error) {
|
|
3715
|
+
if (this.isMissingFileError(error)) return [];
|
|
3716
|
+
if (error instanceof SyntaxError) throw new InboxDeliveryStoreError("inbox delivery store contains invalid JSON");
|
|
3717
|
+
throw error;
|
|
3718
|
+
}
|
|
3719
|
+
};
|
|
3720
|
+
save = async (deliveries) => {
|
|
3721
|
+
const tempPath = `${this.storePath}.${randomUUID()}.tmp`;
|
|
3722
|
+
const storeFile = {
|
|
3723
|
+
version: INBOX_DELIVERY_STORE_VERSION,
|
|
3724
|
+
deliveries: deliveries.map((delivery) => structuredClone(delivery))
|
|
3725
|
+
};
|
|
3726
|
+
await mkdir(dirname(this.storePath), { recursive: true });
|
|
3727
|
+
try {
|
|
3728
|
+
await writeFile(tempPath, `${JSON.stringify(storeFile, null, 2)}\n`, "utf8");
|
|
3729
|
+
await rename(tempPath, this.storePath);
|
|
3730
|
+
} catch (error) {
|
|
3731
|
+
await rm(tempPath, { force: true }).catch(() => void 0);
|
|
3732
|
+
throw error;
|
|
3733
|
+
}
|
|
3734
|
+
};
|
|
3735
|
+
parseStoreFile = (source) => {
|
|
3736
|
+
const value = JSON.parse(source);
|
|
3737
|
+
if (!this.isRecord(value) || value.version !== INBOX_DELIVERY_STORE_VERSION || !Array.isArray(value.deliveries) || !value.deliveries.every(this.isDelivery)) throw new InboxDeliveryStoreError("inbox delivery store has an unsupported structure");
|
|
3738
|
+
return {
|
|
3739
|
+
version: INBOX_DELIVERY_STORE_VERSION,
|
|
3740
|
+
deliveries: value.deliveries.map((delivery) => structuredClone(delivery))
|
|
3741
|
+
};
|
|
3742
|
+
};
|
|
3743
|
+
isDelivery = (value) => {
|
|
3744
|
+
if (!this.isRecord(value) || !this.isSource(value.source)) return false;
|
|
3745
|
+
return typeof value.id === "string" && typeof value.title === "string" && (value.summary === null || typeof value.summary === "string") && typeof value.content === "string" && (value.contentType === "markdown" || value.contentType === "html") && typeof value.createdAt === "string" && typeof value.updatedAt === "string" && this.isOptionalTimestamp(value.presentedAt) && this.isOptionalTimestamp(value.readAt) && this.isOptionalTimestamp(value.archivedAt) && (value.conversationSessionId === null || typeof value.conversationSessionId === "string");
|
|
3746
|
+
};
|
|
3747
|
+
isSource = (value) => this.isRecord(value) && value.kind === "agent" && this.isOptionalString(value.agentId) && this.isOptionalString(value.sessionId) && this.isOptionalString(value.toolCallId) && this.isOptionalString(value.filePath);
|
|
3748
|
+
isOptionalString = (value) => value === null || typeof value === "string";
|
|
3749
|
+
isOptionalTimestamp = (value) => this.isOptionalString(value);
|
|
3750
|
+
isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3751
|
+
isMissingFileError = (error) => typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
3752
|
+
};
|
|
3753
|
+
//#endregion
|
|
3754
|
+
//#region src/managers/inbox-delivery.manager.ts
|
|
3755
|
+
const MAX_TITLE_LENGTH = 160;
|
|
3756
|
+
const MAX_SUMMARY_LENGTH = 500;
|
|
3757
|
+
const MAX_INBOX_DELIVERY_CONTENT_LENGTH = 512 * 1024;
|
|
3758
|
+
var InboxDeliveryError = class extends Error {
|
|
3759
|
+
constructor(code, message) {
|
|
3760
|
+
super(message);
|
|
3761
|
+
this.code = code;
|
|
3762
|
+
this.name = "InboxDeliveryError";
|
|
3763
|
+
}
|
|
3764
|
+
};
|
|
3765
|
+
function isInboxDeliveryError(error) {
|
|
3766
|
+
return error instanceof InboxDeliveryError;
|
|
3767
|
+
}
|
|
3768
|
+
var InboxDeliveryManager = class {
|
|
3769
|
+
store;
|
|
3770
|
+
writeQueue = Promise.resolve();
|
|
3771
|
+
constructor(options) {
|
|
3772
|
+
this.options = options;
|
|
3773
|
+
this.store = new InboxDeliveryStore(options.storePath);
|
|
3774
|
+
}
|
|
3775
|
+
listDeliveries = async () => {
|
|
3776
|
+
await this.writeQueue;
|
|
3777
|
+
const deliveries = (await this.store.list()).sort((left, right) => right.createdAt.localeCompare(left.createdAt));
|
|
3778
|
+
return {
|
|
3779
|
+
deliveries,
|
|
3780
|
+
total: deliveries.length,
|
|
3781
|
+
unreadCount: deliveries.filter((delivery) => !delivery.readAt && !delivery.archivedAt).length,
|
|
3782
|
+
unpresentedCount: deliveries.filter((delivery) => !delivery.presentedAt && !delivery.readAt && !delivery.archivedAt).length
|
|
3783
|
+
};
|
|
3784
|
+
};
|
|
3785
|
+
getDelivery = async (deliveryId) => {
|
|
3786
|
+
await this.writeQueue;
|
|
3787
|
+
const delivery = (await this.store.list()).find(({ id }) => id === deliveryId);
|
|
3788
|
+
return delivery ? structuredClone(delivery) : null;
|
|
3789
|
+
};
|
|
3790
|
+
createDelivery = async (input) => await this.mutate(async () => {
|
|
3791
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3792
|
+
const delivery = {
|
|
3793
|
+
id: randomUUID(),
|
|
3794
|
+
title: this.normalizeRequiredText(input.title, "title", MAX_TITLE_LENGTH),
|
|
3795
|
+
summary: this.normalizeOptionalText(input.summary, "summary", MAX_SUMMARY_LENGTH),
|
|
3796
|
+
content: this.normalizeRequiredText(input.content, "content", MAX_INBOX_DELIVERY_CONTENT_LENGTH),
|
|
3797
|
+
contentType: input.contentType,
|
|
3798
|
+
source: structuredClone(input.source),
|
|
3799
|
+
createdAt: now,
|
|
3800
|
+
updatedAt: now,
|
|
3801
|
+
presentedAt: null,
|
|
3802
|
+
readAt: null,
|
|
3803
|
+
archivedAt: null,
|
|
3804
|
+
conversationSessionId: null
|
|
3805
|
+
};
|
|
3806
|
+
const deliveries = await this.store.list();
|
|
3807
|
+
await this.store.save([delivery, ...deliveries]);
|
|
3808
|
+
this.publishChange(delivery.id, "upsert");
|
|
3809
|
+
return structuredClone(delivery);
|
|
3810
|
+
});
|
|
3811
|
+
updateDeliveryState = async (deliveryId, action) => await this.mutate(async () => {
|
|
3812
|
+
const deliveries = await this.store.list();
|
|
3813
|
+
const index = deliveries.findIndex(({ id }) => id === deliveryId);
|
|
3814
|
+
if (index < 0) throw this.notFound(deliveryId);
|
|
3815
|
+
const current = deliveries[index];
|
|
3816
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3817
|
+
const next = this.applyStateAction(current, action, now);
|
|
3818
|
+
deliveries[index] = next;
|
|
3819
|
+
await this.store.save(deliveries);
|
|
3820
|
+
this.publishChange(deliveryId, "upsert");
|
|
3821
|
+
return structuredClone(next);
|
|
3822
|
+
});
|
|
3823
|
+
deleteDelivery = async (deliveryId) => await this.mutate(async () => {
|
|
3824
|
+
const deliveries = await this.store.list();
|
|
3825
|
+
const remaining = deliveries.filter(({ id }) => id !== deliveryId);
|
|
3826
|
+
if (remaining.length === deliveries.length) return false;
|
|
3827
|
+
await this.store.save(remaining);
|
|
3828
|
+
this.publishChange(deliveryId, "delete");
|
|
3829
|
+
return true;
|
|
3830
|
+
});
|
|
3831
|
+
continueInChat = async (deliveryId) => await this.mutate(async () => {
|
|
3832
|
+
const deliveries = await this.store.list();
|
|
3833
|
+
const index = deliveries.findIndex(({ id }) => id === deliveryId);
|
|
3834
|
+
if (index < 0) throw this.notFound(deliveryId);
|
|
3835
|
+
const current = deliveries[index];
|
|
3836
|
+
const existingSession = current.conversationSessionId ? await this.options.sessionManager.getSessionRecord(current.conversationSessionId) : null;
|
|
3837
|
+
let sessionId = current.conversationSessionId;
|
|
3838
|
+
let created = false;
|
|
3839
|
+
if (!sessionId || !existingSession) {
|
|
3840
|
+
sessionId = (await this.options.sessionManager.createSession({
|
|
3841
|
+
sourceSessionMetadata: {},
|
|
3842
|
+
metadataOverrides: { [INBOX_DELIVERY_SESSION_METADATA_KEY]: current.id },
|
|
3843
|
+
task: `Continue discussing inbox delivery: ${current.title}`,
|
|
3844
|
+
title: current.title,
|
|
3845
|
+
agentId: current.source.agentId ?? void 0
|
|
3846
|
+
})).sessionId;
|
|
3847
|
+
created = true;
|
|
3848
|
+
}
|
|
3849
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3850
|
+
const delivery = {
|
|
3851
|
+
...current,
|
|
3852
|
+
updatedAt: now,
|
|
3853
|
+
presentedAt: current.presentedAt ?? now,
|
|
3854
|
+
readAt: current.readAt ?? now,
|
|
3855
|
+
conversationSessionId: sessionId
|
|
3856
|
+
};
|
|
3857
|
+
deliveries[index] = delivery;
|
|
3858
|
+
await this.store.save(deliveries);
|
|
3859
|
+
this.publishChange(deliveryId, "upsert");
|
|
3860
|
+
return {
|
|
3861
|
+
delivery: structuredClone(delivery),
|
|
3862
|
+
sessionId,
|
|
3863
|
+
created
|
|
3864
|
+
};
|
|
3865
|
+
});
|
|
3866
|
+
applyStateAction = (delivery, action, now) => {
|
|
3867
|
+
switch (action) {
|
|
3868
|
+
case "present": return {
|
|
3869
|
+
...delivery,
|
|
3870
|
+
updatedAt: now,
|
|
3871
|
+
presentedAt: delivery.presentedAt ?? now
|
|
3872
|
+
};
|
|
3873
|
+
case "read": return {
|
|
3874
|
+
...delivery,
|
|
3875
|
+
updatedAt: now,
|
|
3876
|
+
presentedAt: delivery.presentedAt ?? now,
|
|
3877
|
+
readAt: delivery.readAt ?? now
|
|
3878
|
+
};
|
|
3879
|
+
case "mark_unread": return {
|
|
3880
|
+
...delivery,
|
|
3881
|
+
updatedAt: now,
|
|
3882
|
+
readAt: null
|
|
3883
|
+
};
|
|
3884
|
+
case "archive": return {
|
|
3885
|
+
...delivery,
|
|
3886
|
+
updatedAt: now,
|
|
3887
|
+
presentedAt: delivery.presentedAt ?? now,
|
|
3888
|
+
archivedAt: delivery.archivedAt ?? now
|
|
3889
|
+
};
|
|
3890
|
+
case "restore": return {
|
|
3891
|
+
...delivery,
|
|
3892
|
+
updatedAt: now,
|
|
3893
|
+
archivedAt: null
|
|
3894
|
+
};
|
|
3895
|
+
}
|
|
3896
|
+
};
|
|
3897
|
+
normalizeRequiredText = (value, field, maxLength) => {
|
|
3898
|
+
const normalized = value.trim();
|
|
3899
|
+
if (!normalized || normalized.length > maxLength) throw new InboxDeliveryError(field === "title" ? "INBOX_DELIVERY_INVALID_TITLE" : "INBOX_DELIVERY_INVALID_CONTENT", `${field} must contain between 1 and ${maxLength} characters`);
|
|
3900
|
+
return normalized;
|
|
3901
|
+
};
|
|
3902
|
+
normalizeOptionalText = (value, field, maxLength) => {
|
|
3903
|
+
const normalized = value?.trim() ?? "";
|
|
3904
|
+
if (normalized.length > maxLength) throw new InboxDeliveryError("INBOX_DELIVERY_INVALID_SUMMARY", `${field} must contain at most ${maxLength} characters`);
|
|
3905
|
+
return normalized || null;
|
|
3906
|
+
};
|
|
3907
|
+
notFound = (deliveryId) => new InboxDeliveryError("INBOX_DELIVERY_NOT_FOUND", `inbox delivery not found: ${deliveryId}`);
|
|
3908
|
+
publishChange = (deliveryId, operation) => {
|
|
3909
|
+
this.options.eventBus.emit(eventKeys.inboxDeliveryChanged, {
|
|
3910
|
+
deliveryId,
|
|
3911
|
+
operation
|
|
3912
|
+
}, { source: "inbox-delivery" });
|
|
3913
|
+
};
|
|
3914
|
+
mutate = (operation) => {
|
|
3915
|
+
const result = this.writeQueue.then(operation, operation);
|
|
3916
|
+
this.writeQueue = result.then(() => void 0, () => void 0);
|
|
3917
|
+
return result;
|
|
3918
|
+
};
|
|
3919
|
+
};
|
|
3920
|
+
//#endregion
|
|
3692
3921
|
//#region src/managers/mcp.manager.ts
|
|
3693
3922
|
var McpManager = class {
|
|
3694
3923
|
currentMcpConfig;
|
|
@@ -3743,11 +3972,11 @@ function createAgentPeerSessionIdentity(params) {
|
|
|
3743
3972
|
}
|
|
3744
3973
|
function resolveAgentPeerScope(params) {
|
|
3745
3974
|
const metadata = params.metadata ?? {};
|
|
3746
|
-
const explicitScope = readOptionalString$
|
|
3975
|
+
const explicitScope = readOptionalString$11(metadata["agent_peer_scope"]) ?? readOptionalString$11(metadata.agentPeerScope);
|
|
3747
3976
|
if (explicitScope) return explicitScope;
|
|
3748
|
-
return `agent:${readOptionalString$
|
|
3977
|
+
return `agent:${readOptionalString$11(params.agentId) ?? BUILTIN_MAIN_AGENT_ID}:${readOptionalString$11(params.channel) ?? readOptionalString$11(metadata.channel) ?? "agent-run"}:${readOptionalString$11(metadata.accountId) ?? readOptionalString$11(metadata.account_id) ?? "default"}`;
|
|
3749
3978
|
}
|
|
3750
|
-
function readOptionalString$
|
|
3979
|
+
function readOptionalString$11(value) {
|
|
3751
3980
|
if (typeof value !== "string") return;
|
|
3752
3981
|
return value.trim() || void 0;
|
|
3753
3982
|
}
|
|
@@ -4054,7 +4283,7 @@ function applyLimit(items, limit) {
|
|
|
4054
4283
|
if (!Number.isFinite(limit) || typeof limit !== "number" || limit <= 0) return items;
|
|
4055
4284
|
return items.slice(0, Math.trunc(limit));
|
|
4056
4285
|
}
|
|
4057
|
-
function readOptionalString$
|
|
4286
|
+
function readOptionalString$10(value) {
|
|
4058
4287
|
if (typeof value !== "string") return null;
|
|
4059
4288
|
const trimmed = value.trim();
|
|
4060
4289
|
return trimmed.length > 0 ? trimmed : null;
|
|
@@ -4107,7 +4336,7 @@ function mergeMetadataOverrides(metadata, overrides) {
|
|
|
4107
4336
|
}
|
|
4108
4337
|
function resolveSessionType(params) {
|
|
4109
4338
|
const { metadata, runtime, sessionType } = params;
|
|
4110
|
-
return readOptionalString$
|
|
4339
|
+
return readOptionalString$10(runtime) ?? readOptionalString$10(metadata.runtime) ?? readOptionalString$10(sessionType) ?? readOptionalString$10(metadata.session_type) ?? "native";
|
|
4111
4340
|
}
|
|
4112
4341
|
function applySessionOverrides(params) {
|
|
4113
4342
|
const { lifecycle, metadata, model, parentSessionId, projectRoot, requestId, sessionType, thinkingLevel, title } = params;
|
|
@@ -4117,15 +4346,15 @@ function applySessionOverrides(params) {
|
|
|
4117
4346
|
metadata[CHILD_SESSION_LIFECYCLE_METADATA_KEY] = lifecycle;
|
|
4118
4347
|
if (parentSessionId) metadata[CHILD_SESSION_PARENT_METADATA_KEY] = parentSessionId;
|
|
4119
4348
|
if (requestId) metadata[CHILD_SESSION_REQUEST_METADATA_KEY] = requestId;
|
|
4120
|
-
if (readOptionalString$
|
|
4349
|
+
if (readOptionalString$10(model)) {
|
|
4121
4350
|
metadata.model = model?.trim();
|
|
4122
4351
|
metadata.preferred_model = model?.trim();
|
|
4123
4352
|
}
|
|
4124
|
-
if (readOptionalString$
|
|
4353
|
+
if (readOptionalString$10(thinkingLevel)) {
|
|
4125
4354
|
metadata.thinking = thinkingLevel?.trim();
|
|
4126
4355
|
metadata.preferred_thinking = thinkingLevel?.trim();
|
|
4127
4356
|
}
|
|
4128
|
-
if (readOptionalString$
|
|
4357
|
+
if (readOptionalString$10(projectRoot)) metadata.project_root = projectRoot?.trim();
|
|
4129
4358
|
}
|
|
4130
4359
|
//#endregion
|
|
4131
4360
|
//#region src/utils/session-context-inheritance.utils.ts
|
|
@@ -4136,7 +4365,7 @@ function hasToolCall(message, toolCallId) {
|
|
|
4136
4365
|
return message.parts.some((part) => part.type === "tool-invocation" && part.toolCallId === toolCallId);
|
|
4137
4366
|
}
|
|
4138
4367
|
function findContextInheritanceAnchor(params) {
|
|
4139
|
-
const anchorToolCallId = readOptionalString$
|
|
4368
|
+
const anchorToolCallId = readOptionalString$10(params.anchorToolCallId);
|
|
4140
4369
|
if (!anchorToolCallId) return null;
|
|
4141
4370
|
const index = params.messages.findIndex((message) => hasToolCall(message, anchorToolCallId));
|
|
4142
4371
|
const message = index >= 0 ? params.messages[index] : void 0;
|
|
@@ -4176,7 +4405,7 @@ function createInheritedContextSnapshot(params) {
|
|
|
4176
4405
|
enabled: true,
|
|
4177
4406
|
sourceSessionId: sourceRecord.sessionId,
|
|
4178
4407
|
anchorKind: anchor ? "tool_call" : "latest_persisted",
|
|
4179
|
-
anchorToolCallId: readOptionalString$
|
|
4408
|
+
anchorToolCallId: readOptionalString$10(anchorToolCallId),
|
|
4180
4409
|
anchorMessageId: anchor?.message.id,
|
|
4181
4410
|
inheritedMessageCount: messages.length
|
|
4182
4411
|
}
|
|
@@ -4232,27 +4461,23 @@ function createProjection(sessionId, preview) {
|
|
|
4232
4461
|
preview
|
|
4233
4462
|
};
|
|
4234
4463
|
}
|
|
4235
|
-
function
|
|
4236
|
-
if (typeof error === "string" && error.trim()) return
|
|
4464
|
+
function readErrorDetail(error) {
|
|
4465
|
+
if (typeof error === "string" && error.trim()) return truncatePreviewText(error);
|
|
4237
4466
|
if (error && typeof error === "object" && "message" in error) {
|
|
4238
4467
|
const message = error.message;
|
|
4239
|
-
if (typeof message === "string" && message.trim()) return
|
|
4468
|
+
if (typeof message === "string" && message.trim()) return truncatePreviewText(message);
|
|
4240
4469
|
}
|
|
4241
|
-
return "Run failed";
|
|
4242
4470
|
}
|
|
4243
4471
|
function readToolCallId(value) {
|
|
4244
4472
|
if (typeof value !== "string") return null;
|
|
4245
4473
|
const trimmed = value.trim();
|
|
4246
4474
|
return trimmed.length > 0 ? trimmed : null;
|
|
4247
4475
|
}
|
|
4248
|
-
function formatToolDoneStatus(toolName) {
|
|
4249
|
-
return toolName ? `Tool call completed: ${toolName}` : "Tool call completed";
|
|
4250
|
-
}
|
|
4251
4476
|
function createSessionActivityPreviewFromNcpEvent(event, timestamp, options = {}) {
|
|
4252
4477
|
switch (event.type) {
|
|
4253
4478
|
case NcpEventType.RunStarted: return createProjection(readSessionId(event.payload.sessionId), {
|
|
4254
4479
|
state: "running",
|
|
4255
|
-
|
|
4480
|
+
statusKind: "thinking",
|
|
4256
4481
|
timestamp
|
|
4257
4482
|
});
|
|
4258
4483
|
case NcpEventType.RunFinished: return createProjection(readSessionId(event.payload.sessionId), {
|
|
@@ -4261,7 +4486,8 @@ function createSessionActivityPreviewFromNcpEvent(event, timestamp, options = {}
|
|
|
4261
4486
|
});
|
|
4262
4487
|
case NcpEventType.RunError: return createProjection(readSessionId(event.payload.sessionId), {
|
|
4263
4488
|
state: "failed",
|
|
4264
|
-
|
|
4489
|
+
statusKind: "run-failed",
|
|
4490
|
+
statusText: readErrorDetail(event.payload.error),
|
|
4265
4491
|
timestamp
|
|
4266
4492
|
});
|
|
4267
4493
|
case NcpEventType.MessageSent: {
|
|
@@ -4284,7 +4510,8 @@ function createSessionActivityPreviewFromNcpEvent(event, timestamp, options = {}
|
|
|
4284
4510
|
}
|
|
4285
4511
|
case NcpEventType.MessageFailed: return createProjection(readSessionId(event.payload.sessionId), {
|
|
4286
4512
|
state: "failed",
|
|
4287
|
-
|
|
4513
|
+
statusKind: "run-failed",
|
|
4514
|
+
statusText: readErrorDetail(event.payload.error),
|
|
4288
4515
|
timestamp
|
|
4289
4516
|
});
|
|
4290
4517
|
case NcpEventType.MessageAbort: return createProjection(readSessionId(event.payload.sessionId), {
|
|
@@ -4293,7 +4520,8 @@ function createSessionActivityPreviewFromNcpEvent(event, timestamp, options = {}
|
|
|
4293
4520
|
});
|
|
4294
4521
|
case NcpEventType.MessageToolCallStart: return createProjection(readSessionId(event.payload.sessionId), {
|
|
4295
4522
|
state: "running",
|
|
4296
|
-
|
|
4523
|
+
statusKind: "tool-running",
|
|
4524
|
+
statusText: event.payload.toolName,
|
|
4297
4525
|
timestamp
|
|
4298
4526
|
});
|
|
4299
4527
|
case NcpEventType.MessageToolCallEnd:
|
|
@@ -4302,7 +4530,8 @@ function createSessionActivityPreviewFromNcpEvent(event, timestamp, options = {}
|
|
|
4302
4530
|
const toolCallId = readToolCallId(event.payload.toolCallId);
|
|
4303
4531
|
return createProjection(sessionId, {
|
|
4304
4532
|
state: "running",
|
|
4305
|
-
|
|
4533
|
+
statusKind: "tool-completed",
|
|
4534
|
+
statusText: sessionId && toolCallId ? options.readToolName?.(sessionId, toolCallId) ?? void 0 : void 0,
|
|
4306
4535
|
timestamp
|
|
4307
4536
|
});
|
|
4308
4537
|
}
|
|
@@ -4319,10 +4548,17 @@ const SESSION_ACTIVITY_PREVIEW_STATES = new Set([
|
|
|
4319
4548
|
"cancelled",
|
|
4320
4549
|
"idle"
|
|
4321
4550
|
]);
|
|
4551
|
+
const SESSION_ACTIVITY_PREVIEW_STATUS_KINDS = new Set([
|
|
4552
|
+
"thinking",
|
|
4553
|
+
"tool-running",
|
|
4554
|
+
"tool-completed",
|
|
4555
|
+
"run-failed",
|
|
4556
|
+
"run-interrupted"
|
|
4557
|
+
]);
|
|
4322
4558
|
function isRecord$10(value) {
|
|
4323
4559
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
4324
4560
|
}
|
|
4325
|
-
function readOptionalString$
|
|
4561
|
+
function readOptionalString$9(value) {
|
|
4326
4562
|
if (typeof value !== "string") return;
|
|
4327
4563
|
const trimmed = value.trim();
|
|
4328
4564
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
@@ -4330,13 +4566,15 @@ function readOptionalString$8(value) {
|
|
|
4330
4566
|
function readSessionActivityPreviewMetadata(value) {
|
|
4331
4567
|
if (!isRecord$10(value)) return null;
|
|
4332
4568
|
const state = value.state;
|
|
4333
|
-
const timestamp = readOptionalString$
|
|
4569
|
+
const timestamp = readOptionalString$9(value.timestamp);
|
|
4334
4570
|
if (!SESSION_ACTIVITY_PREVIEW_STATES.has(state) || !timestamp) return null;
|
|
4571
|
+
const statusKind = readOptionalString$9(value.statusKind);
|
|
4335
4572
|
return {
|
|
4336
4573
|
state,
|
|
4337
4574
|
timestamp,
|
|
4338
|
-
|
|
4339
|
-
|
|
4575
|
+
statusKind: SESSION_ACTIVITY_PREVIEW_STATUS_KINDS.has(statusKind) ? statusKind : void 0,
|
|
4576
|
+
statusText: readOptionalString$9(value.statusText),
|
|
4577
|
+
replyText: readOptionalString$9(value.replyText)
|
|
4340
4578
|
};
|
|
4341
4579
|
}
|
|
4342
4580
|
function compareIsoTimestamp(left, right) {
|
|
@@ -4353,12 +4591,13 @@ function mergeSessionActivityPreview(current, incoming) {
|
|
|
4353
4591
|
return {
|
|
4354
4592
|
state: incoming.state,
|
|
4355
4593
|
timestamp: incoming.timestamp,
|
|
4356
|
-
|
|
4357
|
-
|
|
4594
|
+
statusKind: incoming.statusKind ?? (incoming.state === "completed" ? current?.statusKind : void 0),
|
|
4595
|
+
statusText: incoming.statusText ?? (incoming.state === "completed" ? current?.statusText : void 0),
|
|
4596
|
+
replyText: incoming.replyText ?? (incoming.state === "completed" ? current?.replyText : void 0)
|
|
4358
4597
|
};
|
|
4359
4598
|
}
|
|
4360
4599
|
function areSessionActivityPreviewsEqual(left, right) {
|
|
4361
|
-
return Boolean(left) && left?.state === right.state && left.timestamp === right.timestamp && left.statusText === right.statusText && left.replyText === right.replyText;
|
|
4600
|
+
return Boolean(left) && left?.state === right.state && left.timestamp === right.timestamp && left.statusKind === right.statusKind && left.statusText === right.statusText && left.replyText === right.replyText;
|
|
4362
4601
|
}
|
|
4363
4602
|
function writeSessionActivityPreviewMetadata(metadata, projection) {
|
|
4364
4603
|
const current = readSessionActivityPreviewMetadata(metadata?.[SESSION_ACTIVITY_PREVIEW_METADATA_KEY]);
|
|
@@ -4490,7 +4729,7 @@ var SessionWorkingDirResolver = class {
|
|
|
4490
4729
|
return this.resolveContext(params).effectiveWorkspace;
|
|
4491
4730
|
};
|
|
4492
4731
|
resolveContext = (params) => {
|
|
4493
|
-
const profile = this.agentManager.resolveAgentProfile(readOptionalString$
|
|
4732
|
+
const profile = this.agentManager.resolveAgentProfile(readOptionalString$10(params.agentId));
|
|
4494
4733
|
return resolveSessionProjectContext({
|
|
4495
4734
|
sessionMetadata: params.metadata,
|
|
4496
4735
|
workspace: profile.workspace
|
|
@@ -4546,9 +4785,9 @@ var SessionManager = class {
|
|
|
4546
4785
|
const { agentId: requestedAgentId, contextInheritance, metadataOverrides, model, parentSessionId: rawParentSessionId, projectRoot, requestId: rawRequestId, runtime, sessionId: requestedSessionId, sessionType: requestedSessionType, sourceSessionId, sourceSessionMetadata, task, thinkingLevel, title: requestedTitle } = params;
|
|
4547
4786
|
const sourceRecord = sourceSessionId ? await this.getSessionRecord(sourceSessionId) : null;
|
|
4548
4787
|
const metadata = cloneInheritedMetadata(sourceSessionMetadata);
|
|
4549
|
-
const title = readOptionalString$
|
|
4550
|
-
const parentSessionId = readOptionalString$
|
|
4551
|
-
const requestId = readOptionalString$
|
|
4788
|
+
const title = readOptionalString$10(requestedTitle) ?? summarizeTask(task);
|
|
4789
|
+
const parentSessionId = readOptionalString$10(rawParentSessionId);
|
|
4790
|
+
const requestId = readOptionalString$10(rawRequestId);
|
|
4552
4791
|
const sessionType = resolveSessionType({
|
|
4553
4792
|
runtime,
|
|
4554
4793
|
sessionType: requestedSessionType,
|
|
@@ -4574,8 +4813,8 @@ var SessionManager = class {
|
|
|
4574
4813
|
if (normalizedProjectRoot) nextMetadata.project_root = normalizedProjectRoot;
|
|
4575
4814
|
else delete nextMetadata.project_root;
|
|
4576
4815
|
}
|
|
4577
|
-
const agentId = readOptionalString$
|
|
4578
|
-
const sessionId = readOptionalString$
|
|
4816
|
+
const agentId = readOptionalString$10(requestedAgentId) ?? readOptionalString$10(sourceRecord?.agentId) ?? BUILTIN_MAIN_AGENT_ID;
|
|
4817
|
+
const sessionId = readOptionalString$10(requestedSessionId) ?? buildSessionId();
|
|
4579
4818
|
const inheritedContext = createSessionContextInheritance({
|
|
4580
4819
|
childSessionId: sessionId,
|
|
4581
4820
|
contextInheritance,
|
|
@@ -4670,7 +4909,7 @@ var SessionManager = class {
|
|
|
4670
4909
|
return await this.options.journalStore.getSession(normalizedSessionId);
|
|
4671
4910
|
};
|
|
4672
4911
|
listSessions = async (options) => {
|
|
4673
|
-
const peerId = readOptionalString$
|
|
4912
|
+
const peerId = readOptionalString$10(options?.peerId);
|
|
4674
4913
|
return applyLimit((await this.options.journalStore.listSessionSummaries()).filter((summary) => !peerId || summary.peerId === peerId).map(this.workingDirResolver.withWorkingDir), options?.limit);
|
|
4675
4914
|
};
|
|
4676
4915
|
listSessionMessages = async (sessionId, options) => {
|
|
@@ -4733,9 +4972,9 @@ var SessionManager = class {
|
|
|
4733
4972
|
};
|
|
4734
4973
|
createAgentRunSession = async (params) => {
|
|
4735
4974
|
const { agentId, agentRuntimeId: requestedAgentRuntimeId, channel, contextInheritance, metadata, model, parentSessionId: rawParentSessionId, peerId: rawPeerId, projectRoot, sessionId, sourceSessionId: rawSourceSessionId, sourceSessionMetadata: requestedSourceSessionMetadata, task, thinkingEffort } = params;
|
|
4736
|
-
const peerId = readOptionalString$
|
|
4737
|
-
const parentSessionId = readOptionalString$
|
|
4738
|
-
const sourceSessionId = readOptionalString$
|
|
4975
|
+
const peerId = readOptionalString$10(rawPeerId);
|
|
4976
|
+
const parentSessionId = readOptionalString$10(rawParentSessionId);
|
|
4977
|
+
const sourceSessionId = readOptionalString$10(rawSourceSessionId);
|
|
4739
4978
|
const sourceRecord = sourceSessionId ? await this.getSessionRecord(sourceSessionId) : null;
|
|
4740
4979
|
const sourceSessionMetadata = requestedSourceSessionMetadata ?? sourceRecord?.metadata ?? {};
|
|
4741
4980
|
const agentRuntimeId = requestedAgentRuntimeId ?? readAgentRuntimeId(sourceSessionMetadata) ?? "native";
|
|
@@ -4745,7 +4984,7 @@ var SessionManager = class {
|
|
|
4745
4984
|
metadata,
|
|
4746
4985
|
peerId
|
|
4747
4986
|
}) : void 0;
|
|
4748
|
-
const requestedSessionId = readOptionalString$
|
|
4987
|
+
const requestedSessionId = readOptionalString$10(sessionId);
|
|
4749
4988
|
const created = await this.createSession({
|
|
4750
4989
|
contextInheritance,
|
|
4751
4990
|
parentSessionId: parentSessionId ?? void 0,
|
|
@@ -5928,14 +6167,14 @@ function parsePanelAppFolderManifest(raw) {
|
|
|
5928
6167
|
throw new Error(`panel-app.json is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
5929
6168
|
}
|
|
5930
6169
|
if (!isRecord$6(parsed)) throw new Error("panel-app.json must contain an object.");
|
|
5931
|
-
const id = readOptionalString$
|
|
6170
|
+
const id = readOptionalString$8(parsed, "id");
|
|
5932
6171
|
if (id && !PANEL_APP_ID_PATTERN.test(id)) throw new Error("panel app id must be kebab-case.");
|
|
5933
6172
|
return {
|
|
5934
6173
|
id,
|
|
5935
|
-
title: readRequiredString$
|
|
5936
|
-
description: readOptionalString$
|
|
5937
|
-
icon: readOptionalString$
|
|
5938
|
-
entry: readRequiredString$
|
|
6174
|
+
title: readRequiredString$7(parsed, "title"),
|
|
6175
|
+
description: readOptionalString$8(parsed, "description"),
|
|
6176
|
+
icon: readOptionalString$8(parsed, "icon"),
|
|
6177
|
+
entry: readRequiredString$7(parsed, "entry"),
|
|
5939
6178
|
capabilities: readStringArray$1(parsed.capabilities, "capabilities"),
|
|
5940
6179
|
client: readOptionalBoolean$2(parsed, "client"),
|
|
5941
6180
|
serviceActions: readStringArray$1(parsed.actions, "actions")
|
|
@@ -5995,12 +6234,12 @@ function parseTokenList(content) {
|
|
|
5995
6234
|
if (!content) return [];
|
|
5996
6235
|
return [...new Set(content.split(/[,\s]+/).map((entry) => entry.trim()).filter(Boolean))];
|
|
5997
6236
|
}
|
|
5998
|
-
function readRequiredString$
|
|
5999
|
-
const value = readOptionalString$
|
|
6237
|
+
function readRequiredString$7(record, key) {
|
|
6238
|
+
const value = readOptionalString$8(record, key);
|
|
6000
6239
|
if (!value) throw new Error(`panel app ${key} is required.`);
|
|
6001
6240
|
return value;
|
|
6002
6241
|
}
|
|
6003
|
-
function readOptionalString$
|
|
6242
|
+
function readOptionalString$8(record, key) {
|
|
6004
6243
|
return typeof record[key] === "string" && record[key].trim() ? record[key].trim() : void 0;
|
|
6005
6244
|
}
|
|
6006
6245
|
function readOptionalBoolean$2(record, key) {
|
|
@@ -7147,17 +7386,17 @@ function parseServiceAppManifest(raw) {
|
|
|
7147
7386
|
throw new Error(`service-app.json is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
7148
7387
|
}
|
|
7149
7388
|
if (!isRecord$4(parsed)) throw new Error("service-app.json must contain an object.");
|
|
7150
|
-
const id = readRequiredString$
|
|
7389
|
+
const id = readRequiredString$6(parsed, "id");
|
|
7151
7390
|
if (!SERVICE_APP_ID_PATTERN.test(id)) throw new Error("service app id must be kebab-case.");
|
|
7152
|
-
const protocol = readOptionalString$
|
|
7391
|
+
const protocol = readOptionalString$7(parsed, "protocol") ?? "mcp";
|
|
7153
7392
|
if (protocol !== "mcp") throw new Error("service app protocol must be mcp.");
|
|
7154
7393
|
return {
|
|
7155
7394
|
id,
|
|
7156
|
-
title: readRequiredString$
|
|
7157
|
-
description: readOptionalString$
|
|
7395
|
+
title: readRequiredString$6(parsed, "title"),
|
|
7396
|
+
description: readOptionalString$7(parsed, "description"),
|
|
7158
7397
|
enabled: readOptionalBoolean$1(parsed, "enabled") ?? true,
|
|
7159
7398
|
protocol,
|
|
7160
|
-
command: readRequiredString$
|
|
7399
|
+
command: readRequiredString$6(parsed, "command"),
|
|
7161
7400
|
args: readStringArray(parsed.args, "args"),
|
|
7162
7401
|
actions: readManifestActions(parsed.actions)
|
|
7163
7402
|
};
|
|
@@ -7170,25 +7409,25 @@ function readManifestActions(value) {
|
|
|
7170
7409
|
for (const [name, action] of Object.entries(value)) {
|
|
7171
7410
|
if (!name.trim()) throw new Error("service app action name cannot be empty.");
|
|
7172
7411
|
if (!isRecord$4(action)) throw new Error(`service app action ${name} must be an object.`);
|
|
7173
|
-
const risk = readOptionalString$
|
|
7412
|
+
const risk = readOptionalString$7(action, "risk");
|
|
7174
7413
|
if (risk !== void 0 && !SERVICE_ACTION_RISKS.has(risk)) throw new Error(`service app action ${name} has invalid risk.`);
|
|
7175
7414
|
const inputSchema = action.inputSchema;
|
|
7176
7415
|
if (inputSchema !== void 0 && !isRecord$4(inputSchema)) throw new Error(`service app action ${name} inputSchema must be an object.`);
|
|
7177
7416
|
actions[name] = {
|
|
7178
7417
|
risk,
|
|
7179
|
-
title: readOptionalString$
|
|
7180
|
-
description: readOptionalString$
|
|
7418
|
+
title: readOptionalString$7(action, "title"),
|
|
7419
|
+
description: readOptionalString$7(action, "description"),
|
|
7181
7420
|
inputSchema
|
|
7182
7421
|
};
|
|
7183
7422
|
}
|
|
7184
7423
|
return actions;
|
|
7185
7424
|
}
|
|
7186
|
-
function readRequiredString$
|
|
7187
|
-
const value = readOptionalString$
|
|
7425
|
+
function readRequiredString$6(record, key) {
|
|
7426
|
+
const value = readOptionalString$7(record, key);
|
|
7188
7427
|
if (!value) throw new Error(`service app ${key} is required.`);
|
|
7189
7428
|
return value;
|
|
7190
7429
|
}
|
|
7191
|
-
function readOptionalString$
|
|
7430
|
+
function readOptionalString$7(record, key) {
|
|
7192
7431
|
return typeof record[key] === "string" && record[key].trim() ? record[key].trim() : void 0;
|
|
7193
7432
|
}
|
|
7194
7433
|
function readOptionalBoolean$1(record, key) {
|
|
@@ -8018,9 +8257,10 @@ function deduplicateNcpAgentSessionTailMessages(messages) {
|
|
|
8018
8257
|
}
|
|
8019
8258
|
//#endregion
|
|
8020
8259
|
//#region src/stores/ncp-agent-session-message-projection.store.ts
|
|
8021
|
-
const PROJECTION_VERSION =
|
|
8260
|
+
const PROJECTION_VERSION = 2;
|
|
8022
8261
|
const PROJECTION_ROOT_DIRECTORY = ".message-projections";
|
|
8023
8262
|
var NcpAgentSessionMessageProjectionStore = class {
|
|
8263
|
+
messageOrdinals = /* @__PURE__ */ new Map();
|
|
8024
8264
|
constructor(journalDir, source) {
|
|
8025
8265
|
this.journalDir = journalDir;
|
|
8026
8266
|
this.source = source;
|
|
@@ -8028,7 +8268,7 @@ var NcpAgentSessionMessageProjectionStore = class {
|
|
|
8028
8268
|
readMeta = async (sessionId) => {
|
|
8029
8269
|
try {
|
|
8030
8270
|
const parsed = JSON.parse(await readFile(this.metaPath(sessionId), "utf-8"));
|
|
8031
|
-
if (parsed.version !== PROJECTION_VERSION || parsed.sessionId !== sessionId || !Number.isSafeInteger(parsed.total) || !Number.isSafeInteger(parsed.projectedJournalOffset) || !Number.isSafeInteger(parsed.dataBytes) || parsed.
|
|
8271
|
+
if (parsed.version !== PROJECTION_VERSION || parsed.sessionId !== sessionId || !Number.isSafeInteger(parsed.total) || !Number.isSafeInteger(parsed.projectedJournalOffset) || !Number.isSafeInteger(parsed.dataBytes) || parsed.contextWindow !== null && !isRecord$11(parsed.contextWindow)) return null;
|
|
8032
8272
|
const meta = parsed;
|
|
8033
8273
|
const [dataStat, offsetsStat] = await Promise.all([stat(this.dataPath(sessionId)), stat(this.offsetsPath(sessionId))]);
|
|
8034
8274
|
if (dataStat.size !== meta.dataBytes || offsetsStat.size !== meta.total * 42 || meta.total < 0 || meta.projectedJournalOffset < 0 || meta.dataBytes < 0) return null;
|
|
@@ -8038,7 +8278,8 @@ var NcpAgentSessionMessageProjectionStore = class {
|
|
|
8038
8278
|
}
|
|
8039
8279
|
};
|
|
8040
8280
|
rebuild = async (params) => {
|
|
8041
|
-
const { contextWindow, messages, projectedJournalOffset, sessionId } = params;
|
|
8281
|
+
const { contextWindow, messages: sourceMessages, projectedJournalOffset, sessionId } = params;
|
|
8282
|
+
const messages = deduplicateNcpAgentSessionTailMessages(sourceMessages);
|
|
8042
8283
|
const projectionPath = this.projectionPath(sessionId);
|
|
8043
8284
|
const projectionRoot = dirname(projectionPath);
|
|
8044
8285
|
await mkdir(projectionRoot, { recursive: true });
|
|
@@ -8069,7 +8310,6 @@ var NcpAgentSessionMessageProjectionStore = class {
|
|
|
8069
8310
|
version: PROJECTION_VERSION,
|
|
8070
8311
|
sessionId,
|
|
8071
8312
|
total: messages.length,
|
|
8072
|
-
lastMessageId: messages.at(-1)?.id ?? null,
|
|
8073
8313
|
projectedJournalOffset,
|
|
8074
8314
|
dataBytes,
|
|
8075
8315
|
contextWindow: contextWindow ? structuredClone(contextWindow) : null
|
|
@@ -8080,6 +8320,7 @@ var NcpAgentSessionMessageProjectionStore = class {
|
|
|
8080
8320
|
force: true
|
|
8081
8321
|
});
|
|
8082
8322
|
await rename(temporaryPath, projectionPath);
|
|
8323
|
+
this.messageOrdinals.set(sessionId, new Map(messages.map((message, index) => [message.id, index + 1])));
|
|
8083
8324
|
} catch (error) {
|
|
8084
8325
|
await rm(temporaryPath, {
|
|
8085
8326
|
recursive: true,
|
|
@@ -8093,6 +8334,7 @@ var NcpAgentSessionMessageProjectionStore = class {
|
|
|
8093
8334
|
const meta = await this.readMeta(sessionId);
|
|
8094
8335
|
if (!meta) return false;
|
|
8095
8336
|
const messages = deduplicateNcpAgentSessionTailMessages(sourceMessages);
|
|
8337
|
+
const messageOrdinals = await this.readMessageOrdinals(sessionId, meta);
|
|
8096
8338
|
const dataFile = await open(this.dataPath(sessionId), "r+");
|
|
8097
8339
|
const offsetsFile = await open(this.offsetsPath(sessionId), "r+");
|
|
8098
8340
|
try {
|
|
@@ -8105,13 +8347,14 @@ var NcpAgentSessionMessageProjectionStore = class {
|
|
|
8105
8347
|
const serializedLocation = Buffer.from(serializeNcpAgentSessionMessageLocation(location), "utf-8");
|
|
8106
8348
|
await dataFile.write(serialized, 0, serialized.length, meta.dataBytes);
|
|
8107
8349
|
meta.dataBytes += serialized.length;
|
|
8108
|
-
|
|
8109
|
-
|
|
8350
|
+
const ordinal = messageOrdinals.get(message.id);
|
|
8351
|
+
if (ordinal) {
|
|
8352
|
+
await offsetsFile.write(serializedLocation, 0, 42, (ordinal - 1) * 42);
|
|
8110
8353
|
continue;
|
|
8111
8354
|
}
|
|
8112
8355
|
await offsetsFile.write(serializedLocation, 0, 42, meta.total * 42);
|
|
8113
8356
|
meta.total += 1;
|
|
8114
|
-
|
|
8357
|
+
messageOrdinals.set(message.id, meta.total);
|
|
8115
8358
|
}
|
|
8116
8359
|
await Promise.all([dataFile.sync(), offsetsFile.sync()]);
|
|
8117
8360
|
} finally {
|
|
@@ -8159,7 +8402,8 @@ var NcpAgentSessionMessageProjectionStore = class {
|
|
|
8159
8402
|
if (!meta) return null;
|
|
8160
8403
|
const uniqueTailMessages = deduplicateNcpAgentSessionTailMessages(tailMessages ?? []);
|
|
8161
8404
|
const tailById = new Map(uniqueTailMessages.map((message) => [message.id, message]));
|
|
8162
|
-
const
|
|
8405
|
+
const messageOrdinals = await this.readMessageOrdinals(sessionId, meta);
|
|
8406
|
+
const additionalTailMessages = uniqueTailMessages.filter((message) => !messageOrdinals.has(message.id));
|
|
8163
8407
|
const limit = Number.isFinite(requestedLimit) ? Math.min(200, Math.max(1, Math.trunc(requestedLimit))) : 80;
|
|
8164
8408
|
const boundary = cursor ? decodeNcpAgentSessionMessageCursor(cursor, meta.total + 1) : meta.total + 1;
|
|
8165
8409
|
const includeTail = !cursor;
|
|
@@ -8193,11 +8437,20 @@ var NcpAgentSessionMessageProjectionStore = class {
|
|
|
8193
8437
|
}
|
|
8194
8438
|
};
|
|
8195
8439
|
delete = async (sessionId) => {
|
|
8440
|
+
this.messageOrdinals.delete(sessionId);
|
|
8196
8441
|
await rm(this.projectionPath(sessionId), {
|
|
8197
8442
|
recursive: true,
|
|
8198
8443
|
force: true
|
|
8199
8444
|
});
|
|
8200
8445
|
};
|
|
8446
|
+
readMessageOrdinals = async (sessionId, meta) => {
|
|
8447
|
+
const cached = this.messageOrdinals.get(sessionId);
|
|
8448
|
+
if (cached) return cached;
|
|
8449
|
+
const messages = meta.total > 0 ? await this.readMessages(sessionId, 1, meta.total) : [];
|
|
8450
|
+
const ordinals = new Map(messages.map((message, index) => [message.id, index + 1]));
|
|
8451
|
+
this.messageOrdinals.set(sessionId, ordinals);
|
|
8452
|
+
return ordinals;
|
|
8453
|
+
};
|
|
8201
8454
|
readMessages = async (sessionId, startOrdinal, endOrdinal) => {
|
|
8202
8455
|
const count = endOrdinal - startOrdinal + 1;
|
|
8203
8456
|
const indexBuffer = Buffer.alloc(count * 42);
|
|
@@ -9206,13 +9459,13 @@ var ProviderManagerNcpLLMApi = class {
|
|
|
9206
9459
|
};
|
|
9207
9460
|
//#endregion
|
|
9208
9461
|
//#region src/features/native-runtime/tools/ncp-asset.tools.ts
|
|
9209
|
-
function readOptionalString$
|
|
9462
|
+
function readOptionalString$6(value) {
|
|
9210
9463
|
if (typeof value !== "string") return null;
|
|
9211
9464
|
const trimmed = value.trim();
|
|
9212
9465
|
return trimmed.length > 0 ? trimmed : null;
|
|
9213
9466
|
}
|
|
9214
9467
|
function readOptionalBase64Bytes(value) {
|
|
9215
|
-
const base64 = readOptionalString$
|
|
9468
|
+
const base64 = readOptionalString$6(value);
|
|
9216
9469
|
if (!base64) return null;
|
|
9217
9470
|
try {
|
|
9218
9471
|
return Buffer.from(base64, "base64");
|
|
@@ -9263,18 +9516,18 @@ var AssetPutTool = class {
|
|
|
9263
9516
|
this.contentBasePath = contentBasePath;
|
|
9264
9517
|
}
|
|
9265
9518
|
validateArgs = (args) => {
|
|
9266
|
-
const path = readOptionalString$
|
|
9267
|
-
const bytesBase64 = readOptionalString$
|
|
9268
|
-
const fileName = readOptionalString$
|
|
9519
|
+
const path = readOptionalString$6(args.path);
|
|
9520
|
+
const bytesBase64 = readOptionalString$6(args.bytesBase64);
|
|
9521
|
+
const fileName = readOptionalString$6(args.fileName);
|
|
9269
9522
|
if (path && bytesBase64) return ["Provide either path, or bytesBase64 + fileName, not both."];
|
|
9270
9523
|
if (path) return [];
|
|
9271
9524
|
if (bytesBase64) return fileName ? [] : ["fileName is required when using bytesBase64."];
|
|
9272
9525
|
return ["Provide either path, or bytesBase64 + fileName."];
|
|
9273
9526
|
};
|
|
9274
9527
|
execute = async (args) => {
|
|
9275
|
-
const path = readOptionalString$
|
|
9276
|
-
const fileName = readOptionalString$
|
|
9277
|
-
const mimeType = readOptionalString$
|
|
9528
|
+
const path = readOptionalString$6(args?.path);
|
|
9529
|
+
const fileName = readOptionalString$6(args?.fileName);
|
|
9530
|
+
const mimeType = readOptionalString$6(args?.mimeType);
|
|
9278
9531
|
const bytes = readOptionalBase64Bytes(args?.bytesBase64);
|
|
9279
9532
|
if (path) return {
|
|
9280
9533
|
ok: true,
|
|
@@ -9317,8 +9570,8 @@ var AssetExportTool = class {
|
|
|
9317
9570
|
this.assetStore = assetStore;
|
|
9318
9571
|
}
|
|
9319
9572
|
execute = async (args) => {
|
|
9320
|
-
const assetUri = readOptionalString$
|
|
9321
|
-
const targetPath = readOptionalString$
|
|
9573
|
+
const assetUri = readOptionalString$6(args?.assetUri);
|
|
9574
|
+
const targetPath = readOptionalString$6(args?.targetPath);
|
|
9322
9575
|
if (!assetUri || !targetPath) throw new Error("asset_export requires assetUri and targetPath.");
|
|
9323
9576
|
return {
|
|
9324
9577
|
ok: true,
|
|
@@ -9344,7 +9597,7 @@ var AssetStatTool = class {
|
|
|
9344
9597
|
this.contentBasePath = contentBasePath;
|
|
9345
9598
|
}
|
|
9346
9599
|
execute = async (args) => {
|
|
9347
|
-
const assetUri = readOptionalString$
|
|
9600
|
+
const assetUri = readOptionalString$6(args?.assetUri);
|
|
9348
9601
|
if (!assetUri) throw new Error("asset_stat requires assetUri.");
|
|
9349
9602
|
const record = await this.assetStore.statRecord(assetUri);
|
|
9350
9603
|
if (!record) return {
|
|
@@ -9967,6 +10220,30 @@ var CurrentSessionContextProvider = class {
|
|
|
9967
10220
|
};
|
|
9968
10221
|
};
|
|
9969
10222
|
//#endregion
|
|
10223
|
+
//#region src/contributions/context-provider/providers/inbox-delivery-context.provider.ts
|
|
10224
|
+
var InboxDeliveryContextProvider = class {
|
|
10225
|
+
constructor(deliveryManager, sessionManager) {
|
|
10226
|
+
this.deliveryManager = deliveryManager;
|
|
10227
|
+
this.sessionManager = sessionManager;
|
|
10228
|
+
}
|
|
10229
|
+
provide = async (request) => {
|
|
10230
|
+
if (!request.sessionId) return [];
|
|
10231
|
+
const rawDeliveryId = (await this.sessionManager.getSessionRecord(request.sessionId))?.metadata?.[INBOX_DELIVERY_SESSION_METADATA_KEY];
|
|
10232
|
+
if (typeof rawDeliveryId !== "string" || !rawDeliveryId.trim()) return [];
|
|
10233
|
+
const delivery = await this.deliveryManager.getDelivery(rawDeliveryId);
|
|
10234
|
+
if (!delivery) return [];
|
|
10235
|
+
const lines = [
|
|
10236
|
+
"## Inbox Delivery Context",
|
|
10237
|
+
"This chat was opened from a durable inbox delivery. Treat the following content as the shared subject for this conversation.",
|
|
10238
|
+
`Delivery ID: ${delivery.id}`,
|
|
10239
|
+
`Title: ${delivery.title}`
|
|
10240
|
+
];
|
|
10241
|
+
if (delivery.summary) lines.push(`Summary: ${delivery.summary}`);
|
|
10242
|
+
lines.push("", "### Delivered content", delivery.content);
|
|
10243
|
+
return [lines.join("\n")];
|
|
10244
|
+
};
|
|
10245
|
+
};
|
|
10246
|
+
//#endregion
|
|
9970
10247
|
//#region src/contributions/context-provider/providers/execution-policy-context.provider.ts
|
|
9971
10248
|
function normalizeModel(model) {
|
|
9972
10249
|
return model?.trim().toLowerCase() ?? "";
|
|
@@ -10081,7 +10358,7 @@ const createMessagingContextProvider = () => staticBlock([
|
|
|
10081
10358
|
"- For `action=send`, include `message` plus an explicit `to/chatId` whenever the destination is another channel or another conversation.",
|
|
10082
10359
|
"- Omitting `to/chatId` only replies to the current conversation; if you set `channel` to a different channel than the current session, `to/chatId` is required.",
|
|
10083
10360
|
"- If multiple channels are configured, pass `channel`.",
|
|
10084
|
-
"- If you use `message` (`action=send`) to deliver your user-visible reply, respond with ONLY
|
|
10361
|
+
"- If you use `message` (`action=send`) to deliver your user-visible reply, respond with ONLY <noreply/> (avoid duplicate replies)."
|
|
10085
10362
|
]);
|
|
10086
10363
|
const createMemoryRecallContextProvider = () => staticBlock([
|
|
10087
10364
|
"## Memory Recall",
|
|
@@ -10091,7 +10368,7 @@ const createMemoryRecallContextProvider = () => staticBlock([
|
|
|
10091
10368
|
const createSilentRepliesContextProvider = () => staticBlock([
|
|
10092
10369
|
"## Silent Replies",
|
|
10093
10370
|
`Silent marker token: ${SILENT_REPLY_TOKEN}`,
|
|
10094
|
-
"When you have nothing to say, respond with EXACTLY
|
|
10371
|
+
"When you have nothing to say, respond with EXACTLY <noreply/>",
|
|
10095
10372
|
"",
|
|
10096
10373
|
"⚠️ Rules:",
|
|
10097
10374
|
"- It must be your ENTIRE message — nothing else",
|
|
@@ -10099,8 +10376,7 @@ const createSilentRepliesContextProvider = () => staticBlock([
|
|
|
10099
10376
|
"- Never wrap it in markdown or code blocks",
|
|
10100
10377
|
"",
|
|
10101
10378
|
"❌ Wrong: \"Here's help... <noreply/>\"",
|
|
10102
|
-
"
|
|
10103
|
-
"✅ Right: \"\\n\\n<noreply/>\""
|
|
10379
|
+
"✅ Right: \"<noreply/>\""
|
|
10104
10380
|
]);
|
|
10105
10381
|
const createRuntimeContextProvider = () => staticBlock([
|
|
10106
10382
|
"## Runtime",
|
|
@@ -10783,6 +11059,7 @@ var ContextProviderContribution = class {
|
|
|
10783
11059
|
new SkillsContextProvider(context),
|
|
10784
11060
|
createSessionOrchestrationContextProvider(),
|
|
10785
11061
|
new ExecutionPolicyContextProvider(context),
|
|
11062
|
+
new InboxDeliveryContextProvider(this.kernel.inboxDeliveryManager, this.kernel.sessionManager),
|
|
10786
11063
|
new CurrentSessionContextProvider(context),
|
|
10787
11064
|
new ReplyFormatContextProvider()
|
|
10788
11065
|
]) this.cleanups.push(this.kernel.contextProviderManager.register(provider));
|
|
@@ -11127,11 +11404,11 @@ var MessagingToolProvider = class {
|
|
|
11127
11404
|
};
|
|
11128
11405
|
//#endregion
|
|
11129
11406
|
//#region src/tools/project.tools.ts
|
|
11130
|
-
function readRequiredString$
|
|
11407
|
+
function readRequiredString$5(value, key) {
|
|
11131
11408
|
if (typeof value !== "string" || !value.trim()) throw new Error(`${key} must be a non-empty string.`);
|
|
11132
11409
|
return value.trim();
|
|
11133
11410
|
}
|
|
11134
|
-
function readOptionalString$
|
|
11411
|
+
function readOptionalString$5(value) {
|
|
11135
11412
|
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
11136
11413
|
}
|
|
11137
11414
|
var ProjectsListTool = class {
|
|
@@ -11182,9 +11459,9 @@ var ProjectsCreateTool = class {
|
|
|
11182
11459
|
}
|
|
11183
11460
|
execute = async (args) => {
|
|
11184
11461
|
const params = normalizeToolParams(args);
|
|
11185
|
-
const name = readRequiredString$
|
|
11186
|
-
const rootPath = readOptionalString$
|
|
11187
|
-
const template = readOptionalString$
|
|
11462
|
+
const name = readRequiredString$5(params.name, "name");
|
|
11463
|
+
const rootPath = readOptionalString$5(params.rootPath);
|
|
11464
|
+
const template = readOptionalString$5(params.template);
|
|
11188
11465
|
return JSON.stringify(await this.projects.createProject({
|
|
11189
11466
|
name,
|
|
11190
11467
|
...rootPath ? { rootPath } : {},
|
|
@@ -11335,12 +11612,12 @@ var SessionsHistoryTool = class {
|
|
|
11335
11612
|
};
|
|
11336
11613
|
//#endregion
|
|
11337
11614
|
//#region src/tools/session-request.tools.ts
|
|
11338
|
-
function readRequiredString$
|
|
11615
|
+
function readRequiredString$4(params, key) {
|
|
11339
11616
|
const value = params[key];
|
|
11340
11617
|
if (typeof value !== "string" || value.trim().length === 0) throw new Error(`${key} must be a non-empty string.`);
|
|
11341
11618
|
return value.trim();
|
|
11342
11619
|
}
|
|
11343
|
-
function readOptionalString$
|
|
11620
|
+
function readOptionalString$4(params, key) {
|
|
11344
11621
|
const value = params[key];
|
|
11345
11622
|
if (typeof value !== "string") return;
|
|
11346
11623
|
const trimmed = value.trim();
|
|
@@ -11394,16 +11671,16 @@ var SessionRequestTool = class {
|
|
|
11394
11671
|
const params = normalizeToolParams(args);
|
|
11395
11672
|
const target = params.target;
|
|
11396
11673
|
if (!target || typeof target !== "object" || Array.isArray(target)) throw new Error("target must be an object.");
|
|
11397
|
-
const task = readRequiredString$
|
|
11398
|
-
const notifyMode = readOptionalString$
|
|
11674
|
+
const task = readRequiredString$4(params, "task");
|
|
11675
|
+
const notifyMode = readOptionalString$4(params, "notify")?.toLowerCase();
|
|
11399
11676
|
if (notifyMode !== "none" && notifyMode !== "final_reply") throw new Error("notify must be \"none\" or \"final_reply\".");
|
|
11400
11677
|
return this.manager.requestSession({
|
|
11401
11678
|
sourceSessionId: this.sourceSessionId,
|
|
11402
11679
|
sourceToolCallId: context?.toolCallId,
|
|
11403
11680
|
updateToolCallResult: context?.updateToolCallResult,
|
|
11404
|
-
targetSessionId: readRequiredString$
|
|
11681
|
+
targetSessionId: readRequiredString$4(target, "session_id"),
|
|
11405
11682
|
task,
|
|
11406
|
-
title: readOptionalString$
|
|
11683
|
+
title: readOptionalString$4(params, "title"),
|
|
11407
11684
|
notify: notifyMode,
|
|
11408
11685
|
handoffDepth: this.handoffDepth
|
|
11409
11686
|
});
|
|
@@ -11474,23 +11751,23 @@ var SessionSearchTool = class {
|
|
|
11474
11751
|
};
|
|
11475
11752
|
//#endregion
|
|
11476
11753
|
//#region src/tools/session-spawn.tools.ts
|
|
11477
|
-
function readRequiredString$
|
|
11754
|
+
function readRequiredString$3(value, key) {
|
|
11478
11755
|
if (typeof value !== "string" || value.trim().length === 0) throw new Error(`${key} must be a non-empty string.`);
|
|
11479
11756
|
return value.trim();
|
|
11480
11757
|
}
|
|
11481
|
-
function readOptionalString$
|
|
11758
|
+
function readOptionalString$3(value) {
|
|
11482
11759
|
if (typeof value !== "string") return;
|
|
11483
11760
|
const trimmed = value.trim();
|
|
11484
11761
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
11485
11762
|
}
|
|
11486
11763
|
function readSpawnScope(value) {
|
|
11487
|
-
const normalized = readOptionalString$
|
|
11764
|
+
const normalized = readOptionalString$3(value)?.toLowerCase();
|
|
11488
11765
|
if (!normalized || normalized === "standalone") return "standalone";
|
|
11489
11766
|
if (normalized === "child") return "child";
|
|
11490
11767
|
throw new Error("scope must be \"standalone\" or \"child\".");
|
|
11491
11768
|
}
|
|
11492
11769
|
function readSpawnNotify(value) {
|
|
11493
|
-
const notifyMode = readOptionalString$
|
|
11770
|
+
const notifyMode = readOptionalString$3(value)?.toLowerCase();
|
|
11494
11771
|
if (!notifyMode && typeof value === "undefined") return;
|
|
11495
11772
|
if (notifyMode === "none" || notifyMode === "final_reply") return notifyMode;
|
|
11496
11773
|
throw new Error("notify must be \"none\" or \"final_reply\".");
|
|
@@ -11558,7 +11835,7 @@ var SessionSpawnTool = class {
|
|
|
11558
11835
|
};
|
|
11559
11836
|
execute = async (args, context) => {
|
|
11560
11837
|
const { agentId: rawAgentId, model: rawModel, notify: rawNotify, runtime: rawRuntime, scope: rawScope, task: rawTask, title: rawTitle, inheritContext: rawInheritContext } = normalizeToolParams(args);
|
|
11561
|
-
const task = readRequiredString$
|
|
11838
|
+
const task = readRequiredString$3(rawTask, "task");
|
|
11562
11839
|
const scope = readSpawnScope(rawScope);
|
|
11563
11840
|
const notify = readSpawnNotify(rawNotify);
|
|
11564
11841
|
const inheritContext = readInheritContext(rawInheritContext);
|
|
@@ -11571,10 +11848,10 @@ var SessionSpawnTool = class {
|
|
|
11571
11848
|
updateToolCallResult: context?.updateToolCallResult,
|
|
11572
11849
|
sourceSessionMetadata: this.sourceSessionMetadata,
|
|
11573
11850
|
task,
|
|
11574
|
-
title: readOptionalString$
|
|
11575
|
-
agentId: readOptionalString$
|
|
11576
|
-
model: readOptionalString$
|
|
11577
|
-
runtime: readOptionalString$
|
|
11851
|
+
title: readOptionalString$3(rawTitle),
|
|
11852
|
+
agentId: readOptionalString$3(rawAgentId),
|
|
11853
|
+
model: readOptionalString$3(rawModel),
|
|
11854
|
+
runtime: readOptionalString$3(rawRuntime),
|
|
11578
11855
|
contextInheritance,
|
|
11579
11856
|
handoffDepth: this.handoffDepth,
|
|
11580
11857
|
parentSessionId,
|
|
@@ -11583,11 +11860,11 @@ var SessionSpawnTool = class {
|
|
|
11583
11860
|
const session = await this.sessionManager.createSession({
|
|
11584
11861
|
sourceSessionId: this.sourceSessionId,
|
|
11585
11862
|
task,
|
|
11586
|
-
title: readOptionalString$
|
|
11863
|
+
title: readOptionalString$3(rawTitle),
|
|
11587
11864
|
sourceSessionMetadata: this.sourceSessionMetadata,
|
|
11588
|
-
agentId: readOptionalString$
|
|
11589
|
-
model: readOptionalString$
|
|
11590
|
-
runtime: readOptionalString$
|
|
11865
|
+
agentId: readOptionalString$3(rawAgentId),
|
|
11866
|
+
model: readOptionalString$3(rawModel),
|
|
11867
|
+
runtime: readOptionalString$3(rawRuntime),
|
|
11591
11868
|
contextInheritance,
|
|
11592
11869
|
parentSessionId
|
|
11593
11870
|
});
|
|
@@ -11611,7 +11888,7 @@ var SessionSpawnTool = class {
|
|
|
11611
11888
|
};
|
|
11612
11889
|
//#endregion
|
|
11613
11890
|
//#region src/tools/session-update.tools.ts
|
|
11614
|
-
function readRequiredString$
|
|
11891
|
+
function readRequiredString$2(value, key) {
|
|
11615
11892
|
if (typeof value !== "string" || !value.trim()) throw new Error(`${key} must be a non-empty string.`);
|
|
11616
11893
|
return value.trim();
|
|
11617
11894
|
}
|
|
@@ -11642,10 +11919,10 @@ var SessionsUpdateTool = class {
|
|
|
11642
11919
|
}
|
|
11643
11920
|
execute = async (args) => {
|
|
11644
11921
|
const params = normalizeToolParams(args);
|
|
11645
|
-
const sessionKey = readRequiredString$
|
|
11922
|
+
const sessionKey = readRequiredString$2(params.sessionKey, "sessionKey");
|
|
11646
11923
|
const patch = {};
|
|
11647
|
-
if (Object.prototype.hasOwnProperty.call(params, "label")) patch.label = readRequiredString$
|
|
11648
|
-
if (Object.prototype.hasOwnProperty.call(params, "projectRoot")) patch.projectRoot = readRequiredString$
|
|
11924
|
+
if (Object.prototype.hasOwnProperty.call(params, "label")) patch.label = readRequiredString$2(params.label, "label");
|
|
11925
|
+
if (Object.prototype.hasOwnProperty.call(params, "projectRoot")) patch.projectRoot = readRequiredString$2(params.projectRoot, "projectRoot");
|
|
11649
11926
|
if (patch.label === void 0 && patch.projectRoot === void 0) throw new Error("label or projectRoot is required.");
|
|
11650
11927
|
const session = await this.sessions.patchSessionSettings(sessionKey, patch);
|
|
11651
11928
|
if (!session) throw new Error(`Session not found: ${sessionKey}`);
|
|
@@ -11701,11 +11978,11 @@ const FILE_VIEWERS = [
|
|
|
11701
11978
|
"source",
|
|
11702
11979
|
"rendered"
|
|
11703
11980
|
];
|
|
11704
|
-
function readRequiredString(value, key) {
|
|
11981
|
+
function readRequiredString$1(value, key) {
|
|
11705
11982
|
if (typeof value !== "string" || value.trim().length === 0) throw new Error(`${key} must be a non-empty string.`);
|
|
11706
11983
|
return value.trim();
|
|
11707
11984
|
}
|
|
11708
|
-
function readOptionalString$
|
|
11985
|
+
function readOptionalString$2(value) {
|
|
11709
11986
|
if (typeof value !== "string") return;
|
|
11710
11987
|
return value.trim() || void 0;
|
|
11711
11988
|
}
|
|
@@ -11715,14 +11992,14 @@ function readOptionalPositiveInteger(value, key) {
|
|
|
11715
11992
|
return value;
|
|
11716
11993
|
}
|
|
11717
11994
|
function readOptionalEnum(value, key, allowed) {
|
|
11718
|
-
const normalized = readOptionalString$
|
|
11995
|
+
const normalized = readOptionalString$2(value);
|
|
11719
11996
|
if (!normalized) return;
|
|
11720
11997
|
if (allowed.includes(normalized)) return normalized;
|
|
11721
11998
|
const expected = allowed.map((item) => `"${item}"`).join(", ");
|
|
11722
11999
|
throw new Error(`${key} must be ${expected}.`);
|
|
11723
12000
|
}
|
|
11724
12001
|
function readUrl(value) {
|
|
11725
|
-
const url = readRequiredString(value, "url");
|
|
12002
|
+
const url = readRequiredString$1(value, "url");
|
|
11726
12003
|
let parsed;
|
|
11727
12004
|
try {
|
|
11728
12005
|
parsed = new URL(url);
|
|
@@ -11734,13 +12011,13 @@ function readUrl(value) {
|
|
|
11734
12011
|
}
|
|
11735
12012
|
function readCommonRequestFields(params, allowedPurposes) {
|
|
11736
12013
|
return {
|
|
11737
|
-
title: readOptionalString$
|
|
12014
|
+
title: readOptionalString$2(params.title),
|
|
11738
12015
|
purpose: readOptionalEnum(params.purpose, "purpose", allowedPurposes)
|
|
11739
12016
|
};
|
|
11740
12017
|
}
|
|
11741
12018
|
function normalizeShowFileArgs(args) {
|
|
11742
12019
|
const params = normalizeToolParams(args);
|
|
11743
|
-
const path = readRequiredString(params.path, "path");
|
|
12020
|
+
const path = readRequiredString$1(params.path, "path");
|
|
11744
12021
|
const viewer = readOptionalEnum(params.viewer, "viewer", FILE_VIEWERS) ?? "auto";
|
|
11745
12022
|
const contentParams = readUiContentParams(params.params);
|
|
11746
12023
|
if (contentParams && (viewer === "source" || !/\.html?$/i.test(path))) throw new Error("params are supported only for rendered HTML file previews.");
|
|
@@ -11770,14 +12047,14 @@ function normalizeShowUrlArgs(args) {
|
|
|
11770
12047
|
}
|
|
11771
12048
|
function normalizeShowPanelAppArgs(args) {
|
|
11772
12049
|
const params = normalizeToolParams(args);
|
|
11773
|
-
const path = readOptionalString$
|
|
12050
|
+
const path = readOptionalString$2(params.path);
|
|
11774
12051
|
const contentParams = readUiContentParams(params.params);
|
|
11775
12052
|
if (path && !isAbsolute(path)) throw new Error("path must be an absolute path.");
|
|
11776
12053
|
return {
|
|
11777
12054
|
target: {
|
|
11778
12055
|
type: "panel_app",
|
|
11779
12056
|
payload: {
|
|
11780
|
-
appId: readRequiredString(params.appId, "appId"),
|
|
12057
|
+
appId: readRequiredString$1(params.appId, "appId"),
|
|
11781
12058
|
path,
|
|
11782
12059
|
params: contentParams
|
|
11783
12060
|
}
|
|
@@ -11791,7 +12068,7 @@ function summarizeTarget(target) {
|
|
|
11791
12068
|
return target.payload.appId;
|
|
11792
12069
|
}
|
|
11793
12070
|
function createShowContentEventPayload(request, context) {
|
|
11794
|
-
const toolCallId = readOptionalString$
|
|
12071
|
+
const toolCallId = readOptionalString$2(context?.toolCallId);
|
|
11795
12072
|
return {
|
|
11796
12073
|
id: toolCallId ? `tool:${toolCallId}:show-content` : `show-content:${request.target.type}:${summarizeTarget(request.target)}`,
|
|
11797
12074
|
toolCallId,
|
|
@@ -11941,6 +12218,119 @@ var ShowContentToolProvider = class {
|
|
|
11941
12218
|
provide = () => createShowContentTools(this.eventBus);
|
|
11942
12219
|
};
|
|
11943
12220
|
//#endregion
|
|
12221
|
+
//#region src/tools/inbox-delivery.tools.ts
|
|
12222
|
+
function readRequiredString(value, key) {
|
|
12223
|
+
if (typeof value !== "string" || value.trim().length === 0) throw new Error(`${key} must be a non-empty string.`);
|
|
12224
|
+
return value.trim();
|
|
12225
|
+
}
|
|
12226
|
+
function readOptionalString$1(value) {
|
|
12227
|
+
if (typeof value !== "string") return null;
|
|
12228
|
+
return value.trim() || null;
|
|
12229
|
+
}
|
|
12230
|
+
function readContentType(value) {
|
|
12231
|
+
if (value === void 0 || value === null) return null;
|
|
12232
|
+
if (value !== "markdown" && value !== "html") throw new Error("contentType must be markdown or html.");
|
|
12233
|
+
return value;
|
|
12234
|
+
}
|
|
12235
|
+
function normalizeRequest(args) {
|
|
12236
|
+
const params = normalizeToolParams(args);
|
|
12237
|
+
const content = readOptionalString$1(params.content);
|
|
12238
|
+
const filePath = readOptionalString$1(params.filePath);
|
|
12239
|
+
if (Boolean(content) === Boolean(filePath)) throw new Error("exactly one of content or filePath must be provided.");
|
|
12240
|
+
if (filePath && !isAbsolute(filePath)) throw new Error("filePath must be an absolute path.");
|
|
12241
|
+
const requestedContentType = readContentType(params.contentType);
|
|
12242
|
+
return {
|
|
12243
|
+
title: readRequiredString(params.title, "title"),
|
|
12244
|
+
summary: readOptionalString$1(params.summary),
|
|
12245
|
+
content,
|
|
12246
|
+
contentType: requestedContentType ?? (filePath && [".htm", ".html"].includes(extname(filePath).toLowerCase()) ? "html" : "markdown"),
|
|
12247
|
+
filePath
|
|
12248
|
+
};
|
|
12249
|
+
}
|
|
12250
|
+
var DeliverToInboxTool = class {
|
|
12251
|
+
name = "deliver_to_inbox";
|
|
12252
|
+
description = "Deliver a durable Markdown or static HTML report, recommendation, or article to the user's NextClaw inbox. Use content for direct text or filePath to snapshot a local UTF-8 text file. Set contentType for direct HTML; .html and .htm files are detected automatically. The user can read it later and continue in a new chat.";
|
|
12253
|
+
parameters = {
|
|
12254
|
+
type: "object",
|
|
12255
|
+
properties: {
|
|
12256
|
+
title: {
|
|
12257
|
+
type: "string",
|
|
12258
|
+
description: "Concise user-facing title, at most 160 characters."
|
|
12259
|
+
},
|
|
12260
|
+
summary: {
|
|
12261
|
+
type: "string",
|
|
12262
|
+
description: "Optional one-paragraph summary, at most 500 characters."
|
|
12263
|
+
},
|
|
12264
|
+
content: {
|
|
12265
|
+
type: "string",
|
|
12266
|
+
description: "Markdown or static HTML content. Provide exactly one of content or filePath."
|
|
12267
|
+
},
|
|
12268
|
+
contentType: {
|
|
12269
|
+
type: "string",
|
|
12270
|
+
enum: ["markdown", "html"],
|
|
12271
|
+
description: "Content format. Defaults to HTML for .html/.htm files and Markdown otherwise."
|
|
12272
|
+
},
|
|
12273
|
+
filePath: {
|
|
12274
|
+
type: "string",
|
|
12275
|
+
description: "Absolute path to a UTF-8 Markdown, HTML, or text file to snapshot."
|
|
12276
|
+
}
|
|
12277
|
+
},
|
|
12278
|
+
required: ["title"],
|
|
12279
|
+
additionalProperties: false
|
|
12280
|
+
};
|
|
12281
|
+
constructor(manager, source) {
|
|
12282
|
+
this.manager = manager;
|
|
12283
|
+
this.source = source;
|
|
12284
|
+
}
|
|
12285
|
+
execute = async (args, context) => {
|
|
12286
|
+
const request = normalizeRequest(args);
|
|
12287
|
+
const content = request.content ?? await this.readFileContent(request.filePath);
|
|
12288
|
+
const delivery = await this.manager.createDelivery({
|
|
12289
|
+
title: request.title,
|
|
12290
|
+
summary: request.summary,
|
|
12291
|
+
content,
|
|
12292
|
+
contentType: request.contentType,
|
|
12293
|
+
source: {
|
|
12294
|
+
kind: "agent",
|
|
12295
|
+
agentId: this.source.agentId,
|
|
12296
|
+
sessionId: this.source.sessionId,
|
|
12297
|
+
toolCallId: readOptionalString$1(context?.toolCallId),
|
|
12298
|
+
filePath: request.filePath
|
|
12299
|
+
}
|
|
12300
|
+
});
|
|
12301
|
+
return {
|
|
12302
|
+
ok: true,
|
|
12303
|
+
deliveryId: delivery.id,
|
|
12304
|
+
title: delivery.title
|
|
12305
|
+
};
|
|
12306
|
+
};
|
|
12307
|
+
readFileContent = async (filePath) => {
|
|
12308
|
+
const file = await stat(filePath);
|
|
12309
|
+
if (!file.isFile()) throw new Error("filePath must point to a regular file.");
|
|
12310
|
+
if (file.size > 524288) throw new Error(`filePath must be at most ${MAX_INBOX_DELIVERY_CONTENT_LENGTH} bytes.`);
|
|
12311
|
+
try {
|
|
12312
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(await readFile(filePath));
|
|
12313
|
+
} catch (error) {
|
|
12314
|
+
if (error instanceof TypeError) throw new Error("filePath must contain valid UTF-8 text.");
|
|
12315
|
+
throw error;
|
|
12316
|
+
}
|
|
12317
|
+
};
|
|
12318
|
+
};
|
|
12319
|
+
function createInboxDeliveryTools(manager, source) {
|
|
12320
|
+
return [new DeliverToInboxTool(manager, source)];
|
|
12321
|
+
}
|
|
12322
|
+
//#endregion
|
|
12323
|
+
//#region src/contributions/tool-provider/providers/inbox-delivery-tool.provider.ts
|
|
12324
|
+
var InboxDeliveryToolProvider = class {
|
|
12325
|
+
constructor(manager) {
|
|
12326
|
+
this.manager = manager;
|
|
12327
|
+
}
|
|
12328
|
+
provide = (request) => createInboxDeliveryTools(this.manager, {
|
|
12329
|
+
agentId: request.agentId ?? null,
|
|
12330
|
+
sessionId: request.sessionId ?? null
|
|
12331
|
+
});
|
|
12332
|
+
};
|
|
12333
|
+
//#endregion
|
|
11944
12334
|
//#region src/contributions/tool-provider/providers/structured-result-tool.provider.ts
|
|
11945
12335
|
var StructuredResultToolProvider = class {
|
|
11946
12336
|
provide = (request) => {
|
|
@@ -12015,6 +12405,7 @@ var ToolProviderContribution = class {
|
|
|
12015
12405
|
return [
|
|
12016
12406
|
new StructuredResultToolProvider(),
|
|
12017
12407
|
new ShowContentToolProvider(this.kernel.eventBus),
|
|
12408
|
+
new InboxDeliveryToolProvider(this.kernel.inboxDeliveryManager),
|
|
12018
12409
|
new CoreToolProvider(runContextService, this.kernel.getGatewayController),
|
|
12019
12410
|
new MessagingToolProvider(runContextService, this.kernel.channels, this.kernel.automation, this.kernel.extensions),
|
|
12020
12411
|
new ProjectToolProvider(this.kernel.projectManager),
|
|
@@ -12046,6 +12437,11 @@ function resolveKernelProjectStorePath(options) {
|
|
|
12046
12437
|
if (homeDir) return resolve(expandHome(homeDir), "projects", "projects.json");
|
|
12047
12438
|
return resolve(getDataDir(), "projects", "projects.json");
|
|
12048
12439
|
}
|
|
12440
|
+
function resolveKernelInboxDeliveryStorePath(options) {
|
|
12441
|
+
const homeDir = options.homeDir?.trim();
|
|
12442
|
+
if (homeDir) return resolve(expandHome(homeDir), "inbox", "deliveries.json");
|
|
12443
|
+
return resolve(getDataDir(), "inbox", "deliveries.json");
|
|
12444
|
+
}
|
|
12049
12445
|
var NextclawKernelControlManager = class {
|
|
12050
12446
|
runtimeControl = null;
|
|
12051
12447
|
installRuntimeControl = (runtimeControl) => {
|
|
@@ -12074,6 +12470,7 @@ var NextclawKernel = class {
|
|
|
12074
12470
|
assetStore;
|
|
12075
12471
|
mcpManager;
|
|
12076
12472
|
sessionManager;
|
|
12473
|
+
inboxDeliveryManager;
|
|
12077
12474
|
panelAppManager;
|
|
12078
12475
|
preferenceManager;
|
|
12079
12476
|
projectManager;
|
|
@@ -12122,6 +12519,11 @@ var NextclawKernel = class {
|
|
|
12122
12519
|
projectManager: this.projectManager,
|
|
12123
12520
|
sessionSearch: this.sessionSearch
|
|
12124
12521
|
});
|
|
12522
|
+
this.inboxDeliveryManager = new InboxDeliveryManager({
|
|
12523
|
+
eventBus: this.eventBus,
|
|
12524
|
+
sessionManager: this.sessionManager,
|
|
12525
|
+
storePath: resolveKernelInboxDeliveryStorePath(options)
|
|
12526
|
+
});
|
|
12125
12527
|
this.panelAppManager = new PanelAppManager({
|
|
12126
12528
|
configManager: this.configManager,
|
|
12127
12529
|
eventBus: this.eventBus,
|
|
@@ -12760,6 +13162,6 @@ function resolveLegacyEventType(message) {
|
|
|
12760
13162
|
return `message.${role || "other"}`;
|
|
12761
13163
|
}
|
|
12762
13164
|
//#endregion
|
|
12763
|
-
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, SessionContextCompactionError, SessionContextCompactionManager, 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, getUiContentParamsBootstrapScript, getUnsignedUpdateManifest, hasLlmUsageTelemetry, injectUiContentParamsBootstrap, isContextCompactionProjectionMessage, isContextCompactionTimelineMessage, isContextWindowSnapshot, isPanelAppAgentCapability, isPanelAppError, isPreferenceError, isProjectError, isReplyCapableChannel, isServiceAppError, isSessionContextCompactionError, 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 };
|
|
13165
|
+
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, InboxDeliveryError, InboxDeliveryManager, LlmProviderManager, LlmUsageManager, LlmUsageStore, MAX_INBOX_DELIVERY_CONTENT_LENGTH, 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, SessionContextCompactionError, SessionContextCompactionManager, 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, getUiContentParamsBootstrapScript, getUnsignedUpdateManifest, hasLlmUsageTelemetry, injectUiContentParamsBootstrap, isContextCompactionProjectionMessage, isContextCompactionTimelineMessage, isContextWindowSnapshot, isInboxDeliveryError, isPanelAppAgentCapability, isPanelAppError, isPreferenceError, isProjectError, isReplyCapableChannel, isServiceAppError, isSessionContextCompactionError, 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 };
|
|
12764
13166
|
|
|
12765
13167
|
//# sourceMappingURL=index.js.map
|