@nextclaw/kernel 0.9.0 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +83 -20
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +337 -85
- package/dist/index.js.map +1 -1
- package/package.json +14 -14
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AUTOMATIC_UPDATE_CHECK_INTERVAL_MS, getAutomaticUpdateCheckDelay, resolveAutomaticUpdateCheckIntervalMs } from "./utils/automatic-update-check.utils.js";
|
|
2
2
|
import { n as getUnsignedUpdateManifest, r as serializeUnsignedUpdateManifest, t as UpdateManifestReader } from "./update-manifest.types-C0qPrjGQ.js";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
|
-
import { APP_NAME, AgentRouteResolver, BUILTIN_MAIN_AGENT_ID, CLEAR_THINKING_TOKENS, CONTEXT_COMPACTION_METADATA_KEY, ConfigSchema, ContextCompactionService, ContextWindowBudgetService, CronService, CronTool, DEFAULT_PANELS_DIR, DEFAULT_SERVICE_APPS_DIR, DEFAULT_SESSION_SEARCH_LIMIT, DEFAULT_WORKSPACE_REPOSITORY_IDENTITY_RESOLVER, DIAGNOSTIC_CORRELATION_METADATA_KEY, DiagnosticRuntime, EditFileTool, ExecTool, ExtensionChannelAdapter, GatewayTool, InputBudgetPruner, LLMProvider, ListDirTool, LiteLLMProvider, MAX_SESSION_SEARCH_LIMIT, MemoryGetTool, MemorySearchTool, MemoryStore, MessageBus, MessageTool, ProviderModelDiscoveryService, ProviderRegistry, ReadFileTool, RequestedSkillsMetadataReader, SILENT_REPLY_TOKEN, SessionProjectContextResolver, SessionSearchService, SkillsLoader, THINKING_LEVELS, ViewImageTool, WebFetchTool, WebSearchTool, WriteFileTool, buildCompressingCompactionCheckpoint, buildConfigSchema, buildContextWindowSnapshot, buildReloadPlan, buildSessionRequestToolResult, buildToolCatalogEntries, createAgentProfile, createAssistantStreamDeltaControlMessage, createAssistantStreamResetControlMessage, createCompletedSessionRequest, createFailedSessionRequest, createRunningSessionRequest, createRuntimeChildEnv, createTypingStopControlMessage, diffConfigPaths, ensureDir, estimateInputTokens, evaluateSilentReply, expandHome, findEffectiveAgentProfile, getConfigPath, getDataDir, getDataPath, getSessionsPath, getWorkspacePath, getWorkspacePathFromConfig, isNextclawControlMessage, loadConfig, mergeExtensionConfigView, modelSupportsVision, normalizeAgentProfileId, normalizeInlineSecretRefs, normalizeModelThinkingCapability, normalizeProviderModelConfig, normalizeToolParams, parseAgentScopedSessionKey, parseThinkingLevel, readCompressedContextCompactionCheckpoint, readOptionalString, readParentSessionId, readSessionProjectRoot, redactConfigObject, removeAgentProfile, resolveConfigSecrets, resolveDefaultAgentProfileId, resolveEffectiveAgentProfiles, resolveNextclawSelfManageGuidePaths, resolveProviderRuntime, resolveSessionProjectContext, resolveSessionWorkspacePath, resolveThinkingLevel, safeFilename, sanitizeOutboundAssistantContent, saveConfig, summarizeSessionRequestTask, toExtensionConfigView, updateAgentProfile } from "@nextclaw/core";
|
|
4
|
+
import { APP_NAME, AgentRouteResolver, BUILTIN_MAIN_AGENT_ID, CLEAR_THINKING_TOKENS, CONTEXT_COMPACTION_METADATA_KEY, ConfigSchema, ContextCompactionService, ContextWindowBudgetService, CronService, CronTool, DEFAULT_PANELS_DIR, DEFAULT_SERVICE_APPS_DIR, DEFAULT_SESSION_SEARCH_LIMIT, DEFAULT_WORKSPACE_REPOSITORY_IDENTITY_RESOLVER, DIAGNOSTIC_CORRELATION_METADATA_KEY, DiagnosticRuntime, EditFileTool, ExecTool, ExtensionChannelAdapter, GatewayTool, InputBudgetPruner, LLMProvider, ListDirTool, LiteLLMProvider, MAX_SESSION_SEARCH_LIMIT, MemoryGetTool, MemorySearchTool, MemoryStore, MessageBus, MessageTool, ProviderModelDiscoveryService, ProviderRegistry, ReadFileTool, RequestedSkillsMetadataReader, SILENT_REPLY_TOKEN, SessionProjectContextResolver, SessionSearchService, SkillsLoader, THINKING_LEVELS, ViewImageTool, WebFetchTool, WebSearchTool, WriteFileTool, buildCompressingCompactionCheckpoint, buildConfigSchema, buildContextWindowSnapshot, buildReloadPlan, buildSessionRequestToolResult, buildToolCatalogEntries, createAgentProfile, createAssistantStreamDeltaControlMessage, createAssistantStreamResetControlMessage, createCompletedSessionRequest, createFailedSessionRequest, createRunningSessionRequest, createRuntimeChildEnv, createTypingStopControlMessage, diffConfigPaths, ensureDir, estimateInputTokens, evaluateSilentReply, expandHome, findEffectiveAgentProfile, getConfigPath, getDataDir, getDataPath, getSessionsPath, getWorkspacePath, getWorkspacePathFromConfig, isNextclawControlMessage, loadConfig, mergeExtensionConfigView, modelSupportsVision, normalizeAgentProfileId, normalizeInlineSecretRefs, normalizeModelThinkingCapability, normalizeProviderModelConfig, normalizeToolParams, parseAgentScopedSessionKey, parseThinkingLevel, readCompressedContextCompactionCheckpoint, readOptionalString, readParentSessionId, readSessionProjectRoot, redactConfigObject, removeAgentProfile, resolveConfigSecrets, resolveDefaultAgentProfileId, resolveEffectiveAgentProfiles, resolveNextclawSelfManageGuidePaths, resolveProviderRuntime, resolveRuntimeCommandLaunch, resolveSessionProjectContext, resolveSessionWorkspacePath, resolveThinkingLevel, safeFilename, sanitizeOutboundAssistantContent, saveConfig, summarizeSessionRequestTask, toExtensionConfigView, updateAgentProfile } from "@nextclaw/core";
|
|
5
5
|
import { NCP_AI_EXECUTION_METADATA_KEY, NCP_INTERNAL_VISIBILITY_METADATA_KEY, NcpEventType, createUnavailableNcpAiExecutionMetadata, isHiddenNcpMessage, normalizeAssistantText, readNcpAiExecutionMetadata, sanitizeAssistantReplyTags } from "@nextclaw/ncp";
|
|
6
6
|
import { CHAT_CONTINUATION_TARGET_MESSAGE_METADATA_KEY, CHAT_CONVERSATION_EXCERPT_TOKEN_KIND, CHAT_INLINE_TOKENS_METADATA_KEY, CHAT_INLINE_TOKENS_SCHEMA_VERSION, CHAT_PROJECT_TOKEN_KIND, CHAT_SESSION_MATERIALIZATION_METADATA_KEY, CHAT_SYSTEM_OBJECT_TOKEN_KIND, CHAT_UI_RESOURCE_TOKEN_KIND, CHAT_WORKSPACE_DIRECTORY_TOKEN_KIND, CHAT_WORKSPACE_EXCERPT_TOKEN_KIND, CHAT_WORKSPACE_FILE_TOKEN_KIND, EventBus, Ingress, PANEL_APP_INLINE_HOST_CONTRACT, PANEL_APP_SCROLL_RESTORATION_CONTRACT, SYSTEM_OBJECT_REFERENCE_DEFAULT_LIMIT, SYSTEM_OBJECT_REFERENCE_MAX_LIMIT, SYSTEM_OBJECT_TYPE_CRON_JOB, SYSTEM_OBJECT_TYPE_INBOX_DELIVERY, UI_CONTENT_PARAMS_HOST_CONTRACT, classifyDiagnosticError, createSystemObjectReferenceUri, eventKeys, ingressKeys, isRuntimeDefaultModelValue, isSilentReplyNcpMessage, normalizeRuntimeModelSelectionMode, parseSystemObjectReferenceUri, readChatUiResourceReference, readInlineContentHeight, readSystemObjectResolvedReference, readUiContentParams } from "@nextclaw/shared";
|
|
7
7
|
import { LocalAssetStore, buildAssetContentPath, buildNcpUserContent, buildOpenAiFunctionTool, isTextLikeAsset, ncpMessageToOpenAiMessages, validateToolArgs } from "@nextclaw/ncp-agent-runtime";
|
|
@@ -10,7 +10,7 @@ import { catchError, filter, from, lastValueFrom, tap } from "rxjs";
|
|
|
10
10
|
import { appendFileSync, chmodSync, constants, createReadStream, existsSync, mkdirSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
11
11
|
import path, { basename, delimiter, dirname, extname, isAbsolute, join, normalize, relative, resolve, sep } from "node:path";
|
|
12
12
|
import { access, appendFile, mkdir, mkdtemp, open, readFile, readdir, realpath, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
|
|
13
|
-
import { AppHomeService, AppInstallationService, AppInstanceInventoryService, AppInstanceStorageService, AppManifestService, AppRegistryService, AppServiceLaunchService, FileLockService, isAppComponentManifestBundle } from "@nextclaw/app-runtime";
|
|
13
|
+
import { AppHomeService, AppInstallationService, AppInstanceInventoryService, AppInstanceStorageService, AppManifestService, AppPlatformTargetService, AppRegistryService, AppServiceLaunchService, FileLockService, isAppComponentManifestBundle } from "@nextclaw/app-runtime";
|
|
14
14
|
import { execFileSync, spawn } from "node:child_process";
|
|
15
15
|
import { fileURLToPath } from "node:url";
|
|
16
16
|
import { BUILTIN_PROVIDER_PLUGINS } from "@nextclaw/runtime";
|
|
@@ -1441,6 +1441,93 @@ var AgentRunSessionCommandManager = class {
|
|
|
1441
1441
|
};
|
|
1442
1442
|
};
|
|
1443
1443
|
//#endregion
|
|
1444
|
+
//#region src/services/agent-run-input-delivery.service.ts
|
|
1445
|
+
/** Resolves public pending-input actions while SessionRun remains the state owner. */
|
|
1446
|
+
var AgentRunInputDeliveryService = class {
|
|
1447
|
+
constructor(agentRuntimeManager, sessionManager, sessionRunManager, publishQueueUpdated) {
|
|
1448
|
+
this.agentRuntimeManager = agentRuntimeManager;
|
|
1449
|
+
this.sessionManager = sessionManager;
|
|
1450
|
+
this.sessionRunManager = sessionRunManager;
|
|
1451
|
+
this.publishQueueUpdated = publishQueueUpdated;
|
|
1452
|
+
}
|
|
1453
|
+
listQueuedInputs = (sessionId) => {
|
|
1454
|
+
return this.sessionRunManager.getSessionRun(sessionId)?.listQueuedRequests().map(this.toQueuedInput) ?? [];
|
|
1455
|
+
};
|
|
1456
|
+
removeQueuedInput = (sessionId, queuedInputId) => {
|
|
1457
|
+
const removed = this.sessionRunManager.getSessionRun(sessionId)?.removeQueuedRequest(queuedInputId) ?? null;
|
|
1458
|
+
if (!removed) return null;
|
|
1459
|
+
this.publishQueueUpdated(sessionId);
|
|
1460
|
+
return this.toQueuedInput(removed);
|
|
1461
|
+
};
|
|
1462
|
+
listPendingInputs = (sessionId) => {
|
|
1463
|
+
return this.sessionRunManager.getSessionRun(sessionId)?.listPendingRequests().map((request) => ({
|
|
1464
|
+
...this.toQueuedInput(request),
|
|
1465
|
+
placement: request.placement,
|
|
1466
|
+
intendedRunId: request.intendedRunId
|
|
1467
|
+
})) ?? [];
|
|
1468
|
+
};
|
|
1469
|
+
steerQueuedInput = async (sessionId, queuedInputId) => {
|
|
1470
|
+
const sessionRun = this.sessionRunManager.getSessionRun(sessionId);
|
|
1471
|
+
if (!sessionRun?.getActiveRunId()) return {
|
|
1472
|
+
ok: false,
|
|
1473
|
+
reason: "unavailable"
|
|
1474
|
+
};
|
|
1475
|
+
if (!sessionRun.listQueuedRequests().some(({ id }) => id === queuedInputId)) return {
|
|
1476
|
+
ok: false,
|
|
1477
|
+
reason: "not-found"
|
|
1478
|
+
};
|
|
1479
|
+
if (!await this.supportsNextStepInput(sessionRun)) return {
|
|
1480
|
+
ok: false,
|
|
1481
|
+
reason: "unavailable"
|
|
1482
|
+
};
|
|
1483
|
+
const moved = sessionRun.moveQueuedRequestToNextStep(queuedInputId);
|
|
1484
|
+
if (!moved) return {
|
|
1485
|
+
ok: false,
|
|
1486
|
+
reason: "unavailable"
|
|
1487
|
+
};
|
|
1488
|
+
this.publishQueueUpdated(sessionId);
|
|
1489
|
+
return {
|
|
1490
|
+
ok: true,
|
|
1491
|
+
input: this.toPendingInput(moved)
|
|
1492
|
+
};
|
|
1493
|
+
};
|
|
1494
|
+
enqueuePreferredSteeringInput = (sessionRun, request, session) => {
|
|
1495
|
+
try {
|
|
1496
|
+
return this.agentRuntimeManager.getOrCreate({
|
|
1497
|
+
agentRuntimeId: session.agentRuntimeId,
|
|
1498
|
+
session,
|
|
1499
|
+
sessionRun
|
|
1500
|
+
}).capabilities?.nextStepInput === true ? sessionRun.enqueueNextStepRequest(request, session) : null;
|
|
1501
|
+
} catch {
|
|
1502
|
+
return null;
|
|
1503
|
+
}
|
|
1504
|
+
};
|
|
1505
|
+
supportsNextStepInput = async (sessionRun) => {
|
|
1506
|
+
try {
|
|
1507
|
+
const session = await this.sessionManager.getAgentRunSession(sessionRun.sessionId);
|
|
1508
|
+
return this.agentRuntimeManager.getOrCreate({
|
|
1509
|
+
agentRuntimeId: session.agentRuntimeId,
|
|
1510
|
+
session,
|
|
1511
|
+
sessionRun
|
|
1512
|
+
}).capabilities?.nextStepInput === true;
|
|
1513
|
+
} catch {
|
|
1514
|
+
return false;
|
|
1515
|
+
}
|
|
1516
|
+
};
|
|
1517
|
+
toPendingInput = (request) => ({
|
|
1518
|
+
...this.toQueuedInput(request),
|
|
1519
|
+
placement: "steering",
|
|
1520
|
+
intendedRunId: request.intendedRunId
|
|
1521
|
+
});
|
|
1522
|
+
toQueuedInput = (queuedRequest) => ({
|
|
1523
|
+
id: queuedRequest.id,
|
|
1524
|
+
sessionId: queuedRequest.request.message.sessionId,
|
|
1525
|
+
enqueuedAt: queuedRequest.enqueuedAt,
|
|
1526
|
+
message: structuredClone(queuedRequest.request.message),
|
|
1527
|
+
metadata: structuredClone(queuedRequest.request.metadata ?? {})
|
|
1528
|
+
});
|
|
1529
|
+
};
|
|
1530
|
+
//#endregion
|
|
1444
1531
|
//#region src/utils/agent-run-execution-metadata.utils.ts
|
|
1445
1532
|
const AGENT_RUN_EXECUTION_METADATA = {
|
|
1446
1533
|
contractVersion: 1,
|
|
@@ -1515,7 +1602,8 @@ function toAgentRunRequest(envelope) {
|
|
|
1515
1602
|
metadata: structuredClone(metadata),
|
|
1516
1603
|
model: metadata.model,
|
|
1517
1604
|
maxTokens: metadata.maxTokens,
|
|
1518
|
-
thinkingEffort: metadata.thinkingEffort
|
|
1605
|
+
thinkingEffort: metadata.thinkingEffort,
|
|
1606
|
+
delivery: envelope.delivery
|
|
1519
1607
|
};
|
|
1520
1608
|
if (Array.isArray(envelope.content)) {
|
|
1521
1609
|
const sessionId = readOptionalString$11(envelope.sessionId);
|
|
@@ -1613,7 +1701,8 @@ function toRunHandle(accepted) {
|
|
|
1613
1701
|
userMessageId: accepted.userMessageId,
|
|
1614
1702
|
assistantMessageId: null,
|
|
1615
1703
|
runId: accepted.runId,
|
|
1616
|
-
correlationId: accepted.correlationId
|
|
1704
|
+
correlationId: accepted.correlationId,
|
|
1705
|
+
delivery: accepted.delivery
|
|
1617
1706
|
};
|
|
1618
1707
|
}
|
|
1619
1708
|
function findCompletedAssistantMessage(messages, messageId) {
|
|
@@ -1669,6 +1758,7 @@ var AgentRunRequestManager = class {
|
|
|
1669
1758
|
cleanups = [];
|
|
1670
1759
|
observedSessionRuns = /* @__PURE__ */ new Set();
|
|
1671
1760
|
sessionCommandManager;
|
|
1761
|
+
pendingInputs;
|
|
1672
1762
|
started = false;
|
|
1673
1763
|
constructor(agentRuntimeManager, agentManager, configManager, agentContextWindowManager, eventBus, ingress, sessionManager, sessionRunManager, diagnostics) {
|
|
1674
1764
|
this.agentRuntimeManager = agentRuntimeManager;
|
|
@@ -1680,6 +1770,7 @@ var AgentRunRequestManager = class {
|
|
|
1680
1770
|
this.sessionManager = sessionManager;
|
|
1681
1771
|
this.sessionRunManager = sessionRunManager;
|
|
1682
1772
|
this.diagnostics = diagnostics;
|
|
1773
|
+
this.pendingInputs = new AgentRunInputDeliveryService(agentRuntimeManager, sessionManager, sessionRunManager, this.publishRunQueueUpdated);
|
|
1683
1774
|
this.sessionCommandManager = new AgentRunSessionCommandManager(sessionManager, sessionRunManager, this.send);
|
|
1684
1775
|
}
|
|
1685
1776
|
start = () => {
|
|
@@ -1693,15 +1784,6 @@ var AgentRunRequestManager = class {
|
|
|
1693
1784
|
this.sessionCommandManager.dispose();
|
|
1694
1785
|
this.started = false;
|
|
1695
1786
|
};
|
|
1696
|
-
listQueuedInputs = (sessionId) => {
|
|
1697
|
-
return this.sessionRunManager.getSessionRun(sessionId)?.listQueuedRequests().map(this.toQueuedInput) ?? [];
|
|
1698
|
-
};
|
|
1699
|
-
removeQueuedInput = (sessionId, queuedInputId) => {
|
|
1700
|
-
const removed = this.sessionRunManager.getSessionRun(sessionId)?.removeQueuedRequest(queuedInputId) ?? null;
|
|
1701
|
-
if (!removed) return null;
|
|
1702
|
-
this.publishRunQueueUpdated(sessionId);
|
|
1703
|
-
return this.toQueuedInput(removed);
|
|
1704
|
-
};
|
|
1705
1787
|
handleSendRequest = async (envelope) => {
|
|
1706
1788
|
if (!envelope.payload) throw new Error("Invalid agent run send request.");
|
|
1707
1789
|
return toRunHandle(await this.send(toAgentRunRequest(envelope.payload)));
|
|
@@ -1742,11 +1824,23 @@ var AgentRunRequestManager = class {
|
|
|
1742
1824
|
...request.message,
|
|
1743
1825
|
sessionId: session.sessionId
|
|
1744
1826
|
};
|
|
1745
|
-
const
|
|
1827
|
+
const normalizedRequest = {
|
|
1746
1828
|
...request,
|
|
1747
1829
|
sessionId: session.sessionId,
|
|
1748
1830
|
message: baseMessage
|
|
1749
|
-
}
|
|
1831
|
+
};
|
|
1832
|
+
const steeringRequest = request.delivery === "prefer-steer" && sessionRun.isRunning() ? this.pendingInputs.enqueuePreferredSteeringInput(sessionRun, normalizedRequest, session) : null;
|
|
1833
|
+
if (steeringRequest) {
|
|
1834
|
+
this.publishRunQueueUpdated(session.sessionId);
|
|
1835
|
+
return {
|
|
1836
|
+
sessionId: session.sessionId,
|
|
1837
|
+
userMessageId: steeringRequest.request.message.id,
|
|
1838
|
+
runId: steeringRequest.intendedRunId,
|
|
1839
|
+
correlationId: request.correlationId,
|
|
1840
|
+
delivery: "steered"
|
|
1841
|
+
};
|
|
1842
|
+
}
|
|
1843
|
+
const queuedRequest = sessionRun.enqueueRequest(normalizedRequest, session);
|
|
1750
1844
|
const activeRequest = sessionRun.beginNextRun();
|
|
1751
1845
|
this.publishRunQueueUpdated(session.sessionId);
|
|
1752
1846
|
if (activeRequest?.id === queuedRequest.id) await this.startQueuedRun(sessionRun, activeRequest);
|
|
@@ -1755,7 +1849,8 @@ var AgentRunRequestManager = class {
|
|
|
1755
1849
|
sessionId: session.sessionId,
|
|
1756
1850
|
userMessageId: queuedRequest.request.message.id,
|
|
1757
1851
|
runId: activeRequest?.id === queuedRequest.id ? activeRequest.runId : null,
|
|
1758
|
-
correlationId: request.correlationId
|
|
1852
|
+
correlationId: request.correlationId,
|
|
1853
|
+
delivery: activeRequest?.id === queuedRequest.id ? "started" : "queued"
|
|
1759
1854
|
};
|
|
1760
1855
|
};
|
|
1761
1856
|
startQueuedRun = async (sessionRun, activeRequest) => {
|
|
@@ -1816,10 +1911,10 @@ var AgentRunRequestManager = class {
|
|
|
1816
1911
|
sessionRun
|
|
1817
1912
|
});
|
|
1818
1913
|
const { contextBlocks, tools } = await this.agentContextWindowManager.resolveRunSurface(providerRequest);
|
|
1819
|
-
sessionRun.inbox.enqueue(message);
|
|
1820
1914
|
this.startRuntimeRun({
|
|
1821
1915
|
options: {
|
|
1822
1916
|
contextBlocks,
|
|
1917
|
+
initialMessages: [message],
|
|
1823
1918
|
session,
|
|
1824
1919
|
sessionRun,
|
|
1825
1920
|
signal: activeRequest.signal,
|
|
@@ -1858,6 +1953,7 @@ var AgentRunRequestManager = class {
|
|
|
1858
1953
|
const { options, parentCorrelationId, requestRunStartedAt, runtime, spec } = params;
|
|
1859
1954
|
const { session, sessionRun } = options;
|
|
1860
1955
|
let messageCompletedSeen = false;
|
|
1956
|
+
const initialMessageIds = new Set(options.initialMessages.map(({ id }) => id));
|
|
1861
1957
|
let executionMetadataSeen = false;
|
|
1862
1958
|
let runtimeFailed = false;
|
|
1863
1959
|
let runtimeCancelled = false;
|
|
@@ -1866,8 +1962,9 @@ var AgentRunRequestManager = class {
|
|
|
1866
1962
|
let failureProviderCode;
|
|
1867
1963
|
let failureFacts;
|
|
1868
1964
|
let runStartedAt = requestRunStartedAt;
|
|
1869
|
-
lastValueFrom(from(runtime.run(spec, options)).pipe(filter((event) => event.type !== NcpEventType.MessageSent || event.payload.message.
|
|
1965
|
+
lastValueFrom(from(runtime.run(spec, options)).pipe(filter((event) => event.type !== NcpEventType.MessageSent || !initialMessageIds.has(event.payload.message.id)), tap((event) => {
|
|
1870
1966
|
const eventsToPublish = [];
|
|
1967
|
+
const consumedSteeringInput = event.type === NcpEventType.MessageSent && event.payload.message.role === "user";
|
|
1871
1968
|
if (event.type === NcpEventType.RunError) {
|
|
1872
1969
|
const classification = classifyDiagnosticError(event.payload.error, options.signal);
|
|
1873
1970
|
runtimeFailed = true;
|
|
@@ -1895,6 +1992,7 @@ var AgentRunRequestManager = class {
|
|
|
1895
1992
|
}
|
|
1896
1993
|
eventsToPublish.push(event);
|
|
1897
1994
|
eventsToPublish.forEach(this.publishNcpEvent);
|
|
1995
|
+
if (consumedSteeringInput) this.publishRunQueueUpdated(session.sessionId);
|
|
1898
1996
|
}), catchError(async (error) => {
|
|
1899
1997
|
const classification = classifyDiagnosticError(error, options.signal);
|
|
1900
1998
|
runtimeFailed = true;
|
|
@@ -1995,13 +2093,6 @@ var AgentRunRequestManager = class {
|
|
|
1995
2093
|
source: "agent-run-request"
|
|
1996
2094
|
});
|
|
1997
2095
|
};
|
|
1998
|
-
toQueuedInput = (queuedRequest) => ({
|
|
1999
|
-
id: queuedRequest.id,
|
|
2000
|
-
sessionId: queuedRequest.request.message.sessionId,
|
|
2001
|
-
enqueuedAt: queuedRequest.enqueuedAt,
|
|
2002
|
-
message: structuredClone(queuedRequest.request.message),
|
|
2003
|
-
metadata: structuredClone(queuedRequest.request.metadata ?? {})
|
|
2004
|
-
});
|
|
2005
2096
|
getOrCreateSessionForRequest = async (request) => {
|
|
2006
2097
|
const sessionMaterialization = readSessionMaterialization(request.metadata ?? {});
|
|
2007
2098
|
if (sessionMaterialization && (request.sessionId || request.peerId)) throw new Error("session_materialization requires a new session request.");
|
|
@@ -2925,6 +3016,7 @@ var AppPackageManager = class {
|
|
|
2925
3016
|
installationService;
|
|
2926
3017
|
manifestService = new AppManifestService();
|
|
2927
3018
|
operationManager;
|
|
3019
|
+
platformTargetService = new AppPlatformTargetService();
|
|
2928
3020
|
presentationService = new AppPackagePresentationService();
|
|
2929
3021
|
registryService;
|
|
2930
3022
|
runtimeHooks = EMPTY_RUNTIME_HOOKS;
|
|
@@ -2946,7 +3038,23 @@ var AppPackageManager = class {
|
|
|
2946
3038
|
start = async () => await this.ensureBuiltInPackages();
|
|
2947
3039
|
listPackages = async (options = {}) => {
|
|
2948
3040
|
const records = await this.registryService.listApps();
|
|
2949
|
-
return {
|
|
3041
|
+
return {
|
|
3042
|
+
hostTarget: this.readHostTarget(),
|
|
3043
|
+
entries: await Promise.all(records.map(async (record) => await this.toPackageView(await this.installationService.info(record.appId, { measureStorageUsage: options.includeStorageUsage !== false }))))
|
|
3044
|
+
};
|
|
3045
|
+
};
|
|
3046
|
+
readHostTarget = () => {
|
|
3047
|
+
try {
|
|
3048
|
+
const target = this.platformTargetService.readHostTarget();
|
|
3049
|
+
return {
|
|
3050
|
+
key: this.platformTargetService.toTargetKey(target),
|
|
3051
|
+
operatingSystem: target.os,
|
|
3052
|
+
architecture: target.arch,
|
|
3053
|
+
...target.os === "darwin" ? {} : { abi: target.abi }
|
|
3054
|
+
};
|
|
3055
|
+
} catch {
|
|
3056
|
+
return;
|
|
3057
|
+
}
|
|
2950
3058
|
};
|
|
2951
3059
|
listInstalledDataOwners = async () => (await this.registryService.listApps()).map((record) => ({
|
|
2952
3060
|
id: record.appId,
|
|
@@ -3745,10 +3853,12 @@ var ExtensionLifecycleService = class {
|
|
|
3745
3853
|
if (record.state === "running") return;
|
|
3746
3854
|
const { generation, manifest, ready, token } = this.prepareStart(record);
|
|
3747
3855
|
this.recordLifecycle(record, "process.spawn.started", "started");
|
|
3748
|
-
const
|
|
3856
|
+
const launch = resolveRuntimeCommandLaunch(manifest.server.command);
|
|
3857
|
+
const child = spawn(launch.command, manifest.server.args ?? [], {
|
|
3749
3858
|
cwd: manifest.rootDir,
|
|
3750
3859
|
env: createRuntimeChildEnv(process.env, {
|
|
3751
3860
|
...manifest.server.env,
|
|
3861
|
+
...launch.envPatch,
|
|
3752
3862
|
NEXTCLAW_EXTENSION_ID: manifest.id,
|
|
3753
3863
|
NEXTCLAW_EXTENSION_ENDPOINT: record.endpoint,
|
|
3754
3864
|
NEXTCLAW_EXTENSION_GENERATION: generation,
|
|
@@ -9561,28 +9671,103 @@ var ProjectManager = class {
|
|
|
9561
9671
|
isMissingFileError = (error) => typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
9562
9672
|
};
|
|
9563
9673
|
//#endregion
|
|
9674
|
+
//#region src/utils/product-activity.utils.ts
|
|
9675
|
+
function resolveHumanProductActivitySource(request) {
|
|
9676
|
+
const metadata = request.metadata ?? {};
|
|
9677
|
+
if (metadata.session_origin === "cron") return null;
|
|
9678
|
+
if (metadata[CHAT_SESSION_MATERIALIZATION_METADATA_KEY]?.kind === "child") return null;
|
|
9679
|
+
return request.channel ? "channel" : "direct";
|
|
9680
|
+
}
|
|
9681
|
+
function recordProductActivityBestEffort(sink, signal) {
|
|
9682
|
+
if (!sink) return;
|
|
9683
|
+
try {
|
|
9684
|
+
Promise.resolve(sink.record(signal)).catch(() => void 0);
|
|
9685
|
+
} catch {}
|
|
9686
|
+
}
|
|
9687
|
+
//#endregion
|
|
9564
9688
|
//#region src/managers/session-run.manager.ts
|
|
9565
|
-
|
|
9566
|
-
|
|
9567
|
-
|
|
9568
|
-
|
|
9689
|
+
/** Single owner for inputs waiting for either the next run or the next safe step. */
|
|
9690
|
+
var SessionPendingInputs = class {
|
|
9691
|
+
nextRun = [];
|
|
9692
|
+
nextStep = [];
|
|
9693
|
+
claimedNextStep = /* @__PURE__ */ new Map();
|
|
9694
|
+
enqueueNextRun = (request) => {
|
|
9695
|
+
this.nextRun.push(request);
|
|
9696
|
+
};
|
|
9697
|
+
enqueueNextStep = (request, intendedRunId) => {
|
|
9698
|
+
this.nextStep.push({
|
|
9699
|
+
...request,
|
|
9700
|
+
intendedRunId
|
|
9701
|
+
});
|
|
9569
9702
|
};
|
|
9570
|
-
|
|
9571
|
-
|
|
9703
|
+
moveNextRunToNextStep = (requestId, intendedRunId) => {
|
|
9704
|
+
const index = this.nextRun.findIndex(({ id }) => id === requestId);
|
|
9705
|
+
if (index < 0) return null;
|
|
9706
|
+
const [request] = this.nextRun.splice(index, 1);
|
|
9707
|
+
if (!request) return null;
|
|
9708
|
+
this.enqueueNextStep(request, intendedRunId);
|
|
9709
|
+
return this.toPendingRequest(request, "steering", intendedRunId);
|
|
9710
|
+
};
|
|
9711
|
+
list = () => [...this.nextStep.map((request) => this.toPendingRequest(request, "steering", request.intendedRunId)), ...this.nextRun.map((request) => this.toPendingRequest(request, "queued", null))];
|
|
9712
|
+
listNextRun = () => structuredClone(this.nextRun);
|
|
9713
|
+
removeNextRun = (requestId) => {
|
|
9714
|
+
const index = this.nextRun.findIndex(({ id }) => id === requestId);
|
|
9715
|
+
if (index < 0) return null;
|
|
9716
|
+
const [removed] = this.nextRun.splice(index, 1);
|
|
9717
|
+
return removed ? structuredClone(removed) : null;
|
|
9572
9718
|
};
|
|
9719
|
+
shiftNextRun = () => {
|
|
9720
|
+
const request = this.nextRun.shift();
|
|
9721
|
+
return request ? structuredClone(request) : null;
|
|
9722
|
+
};
|
|
9723
|
+
claimNextStep = (runId) => {
|
|
9724
|
+
const claimed = [];
|
|
9725
|
+
for (let index = this.nextStep.length - 1; index >= 0; index -= 1) {
|
|
9726
|
+
const request = this.nextStep[index];
|
|
9727
|
+
if (request?.intendedRunId !== runId) continue;
|
|
9728
|
+
this.nextStep.splice(index, 1);
|
|
9729
|
+
claimed.unshift(request);
|
|
9730
|
+
}
|
|
9731
|
+
for (const request of claimed) this.claimedNextStep.set(request.id, request);
|
|
9732
|
+
return structuredClone(claimed);
|
|
9733
|
+
};
|
|
9734
|
+
acknowledgeNextStep = (requestIds) => {
|
|
9735
|
+
for (const requestId of requestIds) this.claimedNextStep.delete(requestId);
|
|
9736
|
+
};
|
|
9737
|
+
restoreNextStep = (runId) => {
|
|
9738
|
+
const restored = [...this.nextStep.filter(({ intendedRunId }) => intendedRunId === runId), ...[...this.claimedNextStep.values()].filter(({ intendedRunId }) => intendedRunId === runId)].sort((left, right) => left.enqueuedAt.localeCompare(right.enqueuedAt));
|
|
9739
|
+
if (restored.length === 0) return;
|
|
9740
|
+
for (let index = this.nextStep.length - 1; index >= 0; index -= 1) if (this.nextStep[index]?.intendedRunId === runId) this.nextStep.splice(index, 1);
|
|
9741
|
+
for (const request of restored) this.claimedNextStep.delete(request.id);
|
|
9742
|
+
this.nextRun.unshift(...restored.map(({ intendedRunId: _intendedRunId, ...request }) => request));
|
|
9743
|
+
};
|
|
9744
|
+
get hasNextRun() {
|
|
9745
|
+
return this.nextRun.length > 0;
|
|
9746
|
+
}
|
|
9747
|
+
clear = () => {
|
|
9748
|
+
this.nextRun.length = 0;
|
|
9749
|
+
this.nextStep.length = 0;
|
|
9750
|
+
this.claimedNextStep.clear();
|
|
9751
|
+
};
|
|
9752
|
+
toPendingRequest = (request, placement, intendedRunId) => structuredClone({
|
|
9753
|
+
...request,
|
|
9754
|
+
placement,
|
|
9755
|
+
intendedRunId
|
|
9756
|
+
});
|
|
9573
9757
|
};
|
|
9574
9758
|
function isConversationStateEvent(event) {
|
|
9575
9759
|
return event.type !== NcpEventType.ContextWindowUpdated;
|
|
9576
9760
|
}
|
|
9577
9761
|
var SessionRun = class {
|
|
9578
|
-
inbox = new MessageInbox();
|
|
9579
9762
|
sessionId;
|
|
9580
9763
|
statusListeners = /* @__PURE__ */ new Set();
|
|
9581
|
-
|
|
9764
|
+
pendingInputs = new SessionPendingInputs();
|
|
9582
9765
|
activeRunId = null;
|
|
9583
9766
|
activeRunController = null;
|
|
9584
|
-
|
|
9767
|
+
activeProductActivitySource = null;
|
|
9768
|
+
constructor(seed, stateManager = new DefaultNcpAgentConversationStateManager(), productActivitySink) {
|
|
9585
9769
|
this.stateManager = stateManager;
|
|
9770
|
+
this.productActivitySink = productActivitySink;
|
|
9586
9771
|
this.sessionId = seed.sessionId;
|
|
9587
9772
|
this.stateManager.hydrate({
|
|
9588
9773
|
sessionId: seed.sessionId,
|
|
@@ -9620,27 +9805,61 @@ var SessionRun = class {
|
|
|
9620
9805
|
request: structuredClone(request),
|
|
9621
9806
|
session: structuredClone(session)
|
|
9622
9807
|
};
|
|
9623
|
-
this.
|
|
9808
|
+
this.pendingInputs.enqueueNextRun(queuedRequest);
|
|
9624
9809
|
this.emitStatusChangeIfNeeded(wasBusy);
|
|
9625
9810
|
return structuredClone(queuedRequest);
|
|
9626
9811
|
};
|
|
9627
|
-
listQueuedRequests = () =>
|
|
9812
|
+
listQueuedRequests = () => this.pendingInputs.listNextRun();
|
|
9813
|
+
listPendingRequests = () => this.pendingInputs.list();
|
|
9628
9814
|
removeQueuedRequest = (queuedRequestId) => {
|
|
9629
|
-
const index = this.queuedRequests.findIndex(({ id }) => id === queuedRequestId);
|
|
9630
|
-
if (index < 0) return null;
|
|
9631
9815
|
const wasBusy = this.isBusy();
|
|
9632
|
-
const
|
|
9816
|
+
const removed = this.pendingInputs.removeNextRun(queuedRequestId);
|
|
9633
9817
|
this.emitStatusChangeIfNeeded(wasBusy);
|
|
9634
|
-
return removed
|
|
9818
|
+
return removed;
|
|
9819
|
+
};
|
|
9820
|
+
moveQueuedRequestToNextStep = (queuedRequestId) => {
|
|
9821
|
+
if (!this.activeRunId) return null;
|
|
9822
|
+
return this.pendingInputs.moveNextRunToNextStep(queuedRequestId, this.activeRunId);
|
|
9823
|
+
};
|
|
9824
|
+
enqueueNextStepRequest = (request, session) => {
|
|
9825
|
+
if (!this.activeRunId) return null;
|
|
9826
|
+
const pendingRequest = {
|
|
9827
|
+
id: `pending-input-${randomUUID()}`,
|
|
9828
|
+
runId: `agent-run-${randomUUID()}`,
|
|
9829
|
+
enqueuedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9830
|
+
request: structuredClone(request),
|
|
9831
|
+
session: structuredClone(session)
|
|
9832
|
+
};
|
|
9833
|
+
this.pendingInputs.enqueueNextStep(pendingRequest, this.activeRunId);
|
|
9834
|
+
return structuredClone({
|
|
9835
|
+
...pendingRequest,
|
|
9836
|
+
placement: "steering",
|
|
9837
|
+
intendedRunId: this.activeRunId
|
|
9838
|
+
});
|
|
9635
9839
|
};
|
|
9840
|
+
claimNextStepRequests = (runId) => this.pendingInputs.claimNextStep(runId).map((request) => ({
|
|
9841
|
+
...request,
|
|
9842
|
+
placement: "steering",
|
|
9843
|
+
intendedRunId: runId
|
|
9844
|
+
}));
|
|
9845
|
+
acknowledgeNextStepRequests = (requestIds) => {
|
|
9846
|
+
this.pendingInputs.acknowledgeNextStep(requestIds);
|
|
9847
|
+
};
|
|
9848
|
+
getActiveRunId = () => this.activeRunId;
|
|
9636
9849
|
beginNextRun = () => {
|
|
9637
9850
|
if (this.activeRunId) return null;
|
|
9638
9851
|
const wasBusy = this.isBusy();
|
|
9639
|
-
const queuedRequest = this.
|
|
9852
|
+
const queuedRequest = this.pendingInputs.shiftNextRun();
|
|
9640
9853
|
if (!queuedRequest) return null;
|
|
9641
9854
|
const controller = new AbortController();
|
|
9642
9855
|
this.activeRunId = queuedRequest.runId;
|
|
9643
9856
|
this.activeRunController = controller;
|
|
9857
|
+
this.activeProductActivitySource = resolveHumanProductActivitySource(queuedRequest.request);
|
|
9858
|
+
if (this.activeProductActivitySource) recordProductActivityBestEffort(this.productActivitySink, {
|
|
9859
|
+
kind: "intent_accepted",
|
|
9860
|
+
occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9861
|
+
source: this.activeProductActivitySource
|
|
9862
|
+
});
|
|
9644
9863
|
this.emitStatusChangeIfNeeded(wasBusy);
|
|
9645
9864
|
return {
|
|
9646
9865
|
...structuredClone(queuedRequest),
|
|
@@ -9654,7 +9873,7 @@ var SessionRun = class {
|
|
|
9654
9873
|
return true;
|
|
9655
9874
|
};
|
|
9656
9875
|
isRunning = () => this.activeRunId !== null;
|
|
9657
|
-
isBusy = () => this.isRunning() || this.
|
|
9876
|
+
isBusy = () => this.isRunning() || this.pendingInputs.hasNextRun;
|
|
9658
9877
|
dispose = () => {
|
|
9659
9878
|
const wasBusy = this.isBusy();
|
|
9660
9879
|
this.activeRunController?.abort({
|
|
@@ -9664,7 +9883,8 @@ var SessionRun = class {
|
|
|
9664
9883
|
});
|
|
9665
9884
|
this.activeRunController = null;
|
|
9666
9885
|
this.activeRunId = null;
|
|
9667
|
-
this.
|
|
9886
|
+
this.activeProductActivitySource = null;
|
|
9887
|
+
this.pendingInputs.clear();
|
|
9668
9888
|
this.emitStatusChangeIfNeeded(wasBusy);
|
|
9669
9889
|
this.statusListeners.clear();
|
|
9670
9890
|
};
|
|
@@ -9673,8 +9893,15 @@ var SessionRun = class {
|
|
|
9673
9893
|
for (const event of events) {
|
|
9674
9894
|
if (event.type === NcpEventType.RunStarted && event.payload.runId) this.activeRunId = event.payload.runId;
|
|
9675
9895
|
if ((event.type === NcpEventType.MessageAbort || event.type === NcpEventType.RunFinished || event.type === NcpEventType.RunError) && (!event.payload.runId || event.payload.runId === this.activeRunId)) {
|
|
9896
|
+
if (event.type === NcpEventType.RunFinished && this.activeProductActivitySource) recordProductActivityBestEffort(this.productActivitySink, {
|
|
9897
|
+
kind: "run_succeeded",
|
|
9898
|
+
occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9899
|
+
source: this.activeProductActivitySource
|
|
9900
|
+
});
|
|
9901
|
+
if (this.activeRunId) this.pendingInputs.restoreNextStep(this.activeRunId);
|
|
9676
9902
|
this.activeRunId = null;
|
|
9677
9903
|
this.activeRunController = null;
|
|
9904
|
+
this.activeProductActivitySource = null;
|
|
9678
9905
|
}
|
|
9679
9906
|
}
|
|
9680
9907
|
this.emitStatusChangeIfNeeded(wasBusy);
|
|
@@ -9688,8 +9915,9 @@ var SessionRun = class {
|
|
|
9688
9915
|
var SessionRunManager = class {
|
|
9689
9916
|
runs = /* @__PURE__ */ new Map();
|
|
9690
9917
|
pendingCreations = /* @__PURE__ */ new Map();
|
|
9691
|
-
constructor(sessionManager) {
|
|
9918
|
+
constructor(sessionManager, productActivitySink) {
|
|
9692
9919
|
this.sessionManager = sessionManager;
|
|
9920
|
+
this.productActivitySink = productActivitySink;
|
|
9693
9921
|
}
|
|
9694
9922
|
getSessionRun = (sessionId) => this.runs.get(sessionId) ?? null;
|
|
9695
9923
|
isSessionRunning = (sessionId) => this.runs.get(sessionId.trim())?.isBusy() ?? false;
|
|
@@ -9709,7 +9937,7 @@ var SessionRunManager = class {
|
|
|
9709
9937
|
const run = new SessionRun({
|
|
9710
9938
|
messages: await this.sessionManager.listSessionMessages(sessionId),
|
|
9711
9939
|
sessionId
|
|
9712
|
-
});
|
|
9940
|
+
}, void 0, this.productActivitySink);
|
|
9713
9941
|
this.runs.set(sessionId, run);
|
|
9714
9942
|
return run;
|
|
9715
9943
|
};
|
|
@@ -12039,15 +12267,14 @@ var NcpAgentRuntimeWrapper = class {
|
|
|
12039
12267
|
this.params = params;
|
|
12040
12268
|
}
|
|
12041
12269
|
run = async function* (spec, options) {
|
|
12042
|
-
const { contextBlocks, session, sessionRun, signal, tools } = options;
|
|
12270
|
+
const { contextBlocks, initialMessages, session, sessionRun, signal, tools } = options;
|
|
12043
12271
|
this.currentTools = tools.map(this.toOpenAiTool);
|
|
12044
|
-
const messages = sessionRun.inbox.drain();
|
|
12045
12272
|
let executionMetadataSeen = false;
|
|
12046
12273
|
try {
|
|
12047
12274
|
const input = {
|
|
12048
12275
|
sessionId: sessionRun.sessionId,
|
|
12049
12276
|
runId: spec.runId,
|
|
12050
|
-
messages,
|
|
12277
|
+
messages: initialMessages,
|
|
12051
12278
|
contextBlocks: this.params.injectNextclawContext ? contextBlocks : void 0,
|
|
12052
12279
|
correlationId: spec.correlationId,
|
|
12053
12280
|
metadata: this.buildMetadata(session, spec),
|
|
@@ -12170,6 +12397,7 @@ var AgentRunRuntimeContribution = class {
|
|
|
12170
12397
|
runPreflight: this.runNativePreflight
|
|
12171
12398
|
});
|
|
12172
12399
|
return {
|
|
12400
|
+
capabilities: { nextStepInput: true },
|
|
12173
12401
|
run: (spec, options) => runtime.run(spec, {
|
|
12174
12402
|
...options,
|
|
12175
12403
|
contextBlocks: entry.injectNextclawContext === false ? [] : options.contextBlocks
|
|
@@ -15520,28 +15748,34 @@ var McpServiceAppRuntimeService = class {
|
|
|
15520
15748
|
await this.lifecycleManager.closeAll();
|
|
15521
15749
|
this.states.clear();
|
|
15522
15750
|
};
|
|
15523
|
-
toMcpServerRecord = (app, manifest) =>
|
|
15524
|
-
|
|
15525
|
-
|
|
15526
|
-
|
|
15527
|
-
|
|
15528
|
-
|
|
15529
|
-
|
|
15530
|
-
|
|
15531
|
-
|
|
15532
|
-
|
|
15533
|
-
|
|
15534
|
-
|
|
15535
|
-
|
|
15536
|
-
|
|
15537
|
-
|
|
15538
|
-
|
|
15539
|
-
|
|
15540
|
-
|
|
15541
|
-
|
|
15751
|
+
toMcpServerRecord = (app, manifest) => {
|
|
15752
|
+
const launch = resolveRuntimeCommandLaunch(manifest.command);
|
|
15753
|
+
return {
|
|
15754
|
+
name: app.id,
|
|
15755
|
+
definition: {
|
|
15756
|
+
enabled: app.enabled,
|
|
15757
|
+
transport: {
|
|
15758
|
+
type: "stdio",
|
|
15759
|
+
command: launch.command,
|
|
15760
|
+
args: manifest.args,
|
|
15761
|
+
cwd: app.dirPath,
|
|
15762
|
+
env: createRuntimeChildEnv(process.env, {
|
|
15763
|
+
...this.createAppRuntimeEnv(app),
|
|
15764
|
+
...launch.envPatch
|
|
15765
|
+
}),
|
|
15766
|
+
stderr: "pipe"
|
|
15767
|
+
},
|
|
15768
|
+
scope: {
|
|
15769
|
+
allAgents: false,
|
|
15770
|
+
agents: []
|
|
15771
|
+
},
|
|
15772
|
+
policy: {
|
|
15773
|
+
trust: "explicit",
|
|
15774
|
+
start: "eager"
|
|
15775
|
+
}
|
|
15542
15776
|
}
|
|
15543
|
-
}
|
|
15544
|
-
}
|
|
15777
|
+
};
|
|
15778
|
+
};
|
|
15545
15779
|
createAppRuntimeEnv = (app) => {
|
|
15546
15780
|
const env = {};
|
|
15547
15781
|
if (app.storage) {
|
|
@@ -16044,9 +16278,19 @@ function mergeServiceAppRuntimeActions({ record, manifest, runtimeActions }) {
|
|
|
16044
16278
|
return [...declared, ...undeclared].sort((left, right) => left.id.localeCompare(right.id));
|
|
16045
16279
|
}
|
|
16046
16280
|
//#endregion
|
|
16047
|
-
//#region src/
|
|
16048
|
-
const
|
|
16049
|
-
|
|
16281
|
+
//#region src/utils/service-app-error.utils.ts
|
|
16282
|
+
const SERVICE_APP_ERROR_CODES = new Set([
|
|
16283
|
+
"AUTHORIZATION_REQUIRED",
|
|
16284
|
+
"SERVICE_APP_ACTION_NOT_DECLARED",
|
|
16285
|
+
"SERVICE_APP_ACTION_NOT_FOUND",
|
|
16286
|
+
"SERVICE_APP_INVALID_ACTION",
|
|
16287
|
+
"SERVICE_APP_INVALID_CALLER",
|
|
16288
|
+
"SERVICE_APP_INVALID_MANIFEST",
|
|
16289
|
+
"SERVICE_APP_MANAGED_SOURCE",
|
|
16290
|
+
"SERVICE_APP_NOT_FOUND",
|
|
16291
|
+
"SERVICE_APP_READ_FAILED",
|
|
16292
|
+
"SERVICE_APP_RUNTIME_FAILED"
|
|
16293
|
+
]);
|
|
16050
16294
|
var ServiceAppError = class extends Error {
|
|
16051
16295
|
constructor(code, message) {
|
|
16052
16296
|
super(message);
|
|
@@ -16054,7 +16298,11 @@ var ServiceAppError = class extends Error {
|
|
|
16054
16298
|
this.name = "ServiceAppError";
|
|
16055
16299
|
}
|
|
16056
16300
|
};
|
|
16057
|
-
const isServiceAppError = (error) => error instanceof ServiceAppError;
|
|
16301
|
+
const isServiceAppError = (error) => error instanceof ServiceAppError || typeof error === "object" && error !== null && error.name === "ServiceAppError" && typeof error.message === "string" && SERVICE_APP_ERROR_CODES.has(error.code);
|
|
16302
|
+
//#endregion
|
|
16303
|
+
//#region src/managers/service-app.manager.ts
|
|
16304
|
+
const SERVICE_ACTION_GRANTS_FILE_NAME = ".service-action-grants.json";
|
|
16305
|
+
const SERVICE_APP_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
16058
16306
|
var ServiceAppManager = class {
|
|
16059
16307
|
removalService = new ServiceAppRemovalService();
|
|
16060
16308
|
runtimeService;
|
|
@@ -16116,15 +16364,19 @@ var ServiceAppManager = class {
|
|
|
16116
16364
|
if (!Object.hasOwn(manifest.actions, actionName)) throw new ServiceAppError("SERVICE_APP_ACTION_NOT_FOUND", "service action not found");
|
|
16117
16365
|
const declaredRisk = manifest.actions[actionName]?.risk ?? "dangerous";
|
|
16118
16366
|
if (!await this.createGrantStore().isGranted(request.caller, actionId, declaredRisk)) throw new ServiceAppError("AUTHORIZATION_REQUIRED", `This panel app needs permission to call ${actionId}.`);
|
|
16119
|
-
|
|
16120
|
-
|
|
16121
|
-
|
|
16122
|
-
|
|
16123
|
-
|
|
16124
|
-
|
|
16125
|
-
|
|
16126
|
-
|
|
16127
|
-
|
|
16367
|
+
try {
|
|
16368
|
+
return {
|
|
16369
|
+
actionId,
|
|
16370
|
+
result: await this.runtimeService.invokeAction({
|
|
16371
|
+
app: record,
|
|
16372
|
+
manifest,
|
|
16373
|
+
actionName,
|
|
16374
|
+
input: request.input ?? {}
|
|
16375
|
+
})
|
|
16376
|
+
};
|
|
16377
|
+
} catch (error) {
|
|
16378
|
+
throw new ServiceAppError("SERVICE_APP_RUNTIME_FAILED", `Service App ${record.id} action ${actionName} failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
16379
|
+
}
|
|
16128
16380
|
};
|
|
16129
16381
|
grantServiceAction = async (actionId, request) => {
|
|
16130
16382
|
const [grant] = await this.grantServiceActions([actionId], request);
|
|
@@ -16519,7 +16771,7 @@ var NextclawKernel = class {
|
|
|
16519
16771
|
})
|
|
16520
16772
|
});
|
|
16521
16773
|
this.contextCompactionManager = new AgentRunContextCompactionManager(this.agents, this.llmProviders);
|
|
16522
|
-
this.sessionRunManager = new SessionRunManager(this.sessionManager);
|
|
16774
|
+
this.sessionRunManager = new SessionRunManager(this.sessionManager, options.productActivitySink);
|
|
16523
16775
|
this.sessionContextCompactionManager = new SessionContextCompactionManager(this.agentRuntimeManager, this.eventBus, this.sessionManager, this.sessionRunManager);
|
|
16524
16776
|
this.agentRunRequestManager = new AgentRunRequestManager(this.agentRuntimeManager, this.agents, this.configManager, this.agentContextWindowManager, this.eventBus, this.ingress, this.sessionManager, this.sessionRunManager, this.diagnostics);
|
|
16525
16777
|
this.contributions = [
|