@nextclaw/server 0.10.57 → 0.11.1

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.
Files changed (3) hide show
  1. package/dist/index.d.ts +11 -127
  2. package/dist/index.js +35 -719
  3. package/package.json +5 -5
package/dist/index.d.ts CHANGED
@@ -6,27 +6,27 @@ import { NcpHttpAgentStreamProvider } from '@nextclaw/ncp-http-agent-server';
6
6
  import { IncomingMessage } from 'node:http';
7
7
  import { Hono } from 'hono';
8
8
 
9
- type UiNcpStoredAttachmentRecord = {
9
+ type UiNcpStoredAssetRecord = {
10
10
  id: string;
11
11
  uri: string;
12
12
  storageKey: string;
13
- originalName: string;
13
+ fileName: string;
14
14
  storedName: string;
15
15
  mimeType: string;
16
16
  sizeBytes: number;
17
17
  createdAt: string;
18
18
  sha256: string;
19
19
  };
20
- type UiNcpAttachmentView = {
20
+ type UiNcpAssetView = {
21
21
  id: string;
22
22
  name: string;
23
23
  mimeType: string;
24
24
  sizeBytes: number;
25
- attachmentUri: string;
25
+ assetUri: string;
26
26
  url: string;
27
27
  };
28
- type UiNcpAttachmentUploadView = {
29
- attachments: UiNcpAttachmentView[];
28
+ type UiNcpAssetPutView = {
29
+ assets: UiNcpAssetView[];
30
30
  };
31
31
 
32
32
  type MarketplaceItemType = "plugin" | "skill" | "mcp";
@@ -353,7 +353,6 @@ type UiRouterOptions = {
353
353
  applyLiveConfigReload?: () => Promise<void>;
354
354
  marketplace?: MarketplaceApiConfig;
355
355
  cronService?: InstanceType<typeof NextclawCore.CronService>;
356
- chatRuntime?: UiChatRuntime;
357
356
  ncpAgent?: UiNcpAgent;
358
357
  authService?: UiAuthService;
359
358
  remoteAccess?: UiRemoteAccessHost;
@@ -840,115 +839,6 @@ type SecretsConfigUpdate = {
840
839
  providers?: Record<string, SecretProviderView> | null;
841
840
  refs?: Record<string, SecretRefView> | null;
842
841
  };
843
- type ChatTurnRequest = {
844
- message: string;
845
- sessionKey?: string;
846
- agentId?: string;
847
- channel?: string;
848
- chatId?: string;
849
- model?: string;
850
- metadata?: Record<string, unknown>;
851
- runId?: string;
852
- };
853
- type ChatTurnResult = {
854
- reply: string;
855
- sessionKey: string;
856
- agentId?: string;
857
- model?: string;
858
- metadata?: Record<string, unknown>;
859
- };
860
- type ChatTurnStreamEvent = {
861
- type: "delta";
862
- delta: string;
863
- } | {
864
- type: "session_event";
865
- event: SessionEventView;
866
- } | {
867
- type: "final";
868
- result: ChatTurnResult;
869
- } | {
870
- type: "error";
871
- error: string;
872
- };
873
- type ChatTurnView = {
874
- reply: string;
875
- sessionKey: string;
876
- agentId?: string;
877
- model?: string;
878
- requestedAt: string;
879
- completedAt: string;
880
- durationMs: number;
881
- };
882
- type ChatCapabilitiesView = {
883
- stopSupported: boolean;
884
- stopReason?: string;
885
- };
886
- type ChatCommandOptionView = {
887
- name: string;
888
- description: string;
889
- type: "string" | "boolean" | "number";
890
- required?: boolean;
891
- };
892
- type ChatCommandView = {
893
- name: string;
894
- description: string;
895
- options?: ChatCommandOptionView[];
896
- };
897
- type ChatCommandsView = {
898
- commands: ChatCommandView[];
899
- total: number;
900
- };
901
- type ChatTurnStopRequest = {
902
- runId: string;
903
- sessionKey?: string;
904
- agentId?: string;
905
- };
906
- type ChatTurnStopResult = {
907
- stopped: boolean;
908
- runId: string;
909
- sessionKey?: string;
910
- reason?: string;
911
- };
912
- type ChatRunState = "queued" | "running" | "completed" | "failed" | "aborted";
913
- type ChatRunView = {
914
- runId: string;
915
- sessionKey: string;
916
- agentId?: string;
917
- model?: string;
918
- state: ChatRunState;
919
- requestedAt: string;
920
- startedAt?: string;
921
- completedAt?: string;
922
- stopSupported: boolean;
923
- stopReason?: string;
924
- error?: string;
925
- reply?: string;
926
- eventCount: number;
927
- };
928
- type ChatRunListView = {
929
- runs: ChatRunView[];
930
- total: number;
931
- };
932
- type UiChatRuntime = {
933
- processTurn: (params: ChatTurnRequest) => Promise<ChatTurnResult>;
934
- processTurnStream?: (params: ChatTurnRequest) => AsyncGenerator<ChatTurnStreamEvent>;
935
- startTurnRun?: (params: ChatTurnRequest) => Promise<ChatRunView> | ChatRunView;
936
- streamRun?: (params: {
937
- runId: string;
938
- fromEventIndex?: number;
939
- }) => AsyncGenerator<ChatTurnStreamEvent>;
940
- getRun?: (params: {
941
- runId: string;
942
- }) => Promise<ChatRunView | null> | ChatRunView | null;
943
- listRuns?: (params: {
944
- sessionKey?: string;
945
- states?: ChatRunState[];
946
- limit?: number;
947
- }) => Promise<ChatRunListView> | ChatRunListView;
948
- getCapabilities?: (params: Pick<ChatTurnRequest, "sessionKey" | "agentId">) => Promise<ChatCapabilitiesView> | ChatCapabilitiesView;
949
- listSessionTypes?: () => Promise<ChatSessionTypesView> | ChatSessionTypesView;
950
- stopTurn?: (params: ChatTurnStopRequest) => Promise<ChatTurnStopResult> | ChatTurnStopResult;
951
- };
952
842
  type UiNcpSessionListView = {
953
843
  sessions: NcpSessionSummary[];
954
844
  total: number;
@@ -966,14 +856,14 @@ type UiNcpAgent = {
966
856
  streamProvider?: NcpHttpAgentStreamProvider;
967
857
  sessionApi?: NcpSessionApi;
968
858
  listSessionTypes?: (params?: SessionTypeDescribeParams) => Promise<ChatSessionTypesView> | ChatSessionTypesView;
969
- attachmentApi?: {
970
- saveAttachment: (input: {
859
+ assetApi?: {
860
+ put: (input: {
971
861
  fileName: string;
972
862
  mimeType?: string | null;
973
863
  bytes: Uint8Array;
974
864
  createdAt?: Date;
975
- }) => Promise<UiNcpStoredAttachmentRecord>;
976
- statAttachment: (uri: string) => Promise<UiNcpStoredAttachmentRecord | null> | UiNcpStoredAttachmentRecord | null;
865
+ }) => Promise<UiNcpStoredAssetRecord>;
866
+ stat: (uri: string) => Promise<UiNcpStoredAssetRecord | null> | UiNcpStoredAssetRecord | null;
977
867
  resolveContentPath: (uri: string) => string | null;
978
868
  };
979
869
  basePath?: string;
@@ -1148,11 +1038,6 @@ type UiServerEvent = {
1148
1038
  payload: {
1149
1039
  path: string;
1150
1040
  };
1151
- } | {
1152
- type: "run.updated";
1153
- payload: {
1154
- run: ChatRunView;
1155
- };
1156
1041
  } | {
1157
1042
  type: "session.updated";
1158
1043
  payload: {
@@ -1180,7 +1065,6 @@ type UiServerOptions = {
1180
1065
  staticDir?: string;
1181
1066
  marketplace?: MarketplaceApiConfig;
1182
1067
  cronService?: CronService;
1183
- chatRuntime?: UiChatRuntime;
1184
1068
  ncpAgent?: UiNcpAgent;
1185
1069
  remoteAccess?: UiRemoteAccessHost;
1186
1070
  getPluginChannelBindings?: () => PluginChannelBinding[];
@@ -1254,4 +1138,4 @@ declare function getUiBridgeSecretPath(): string;
1254
1138
  declare function readUiBridgeSecret(): string | null;
1255
1139
  declare function ensureUiBridgeSecret(): string;
1256
1140
 
1257
- export { type AgentBindingView, type AgentProfileView, type ApiError, type ApiResponse, type AppMetaView, type AuthEnabledUpdateRequest, type AuthLoginRequest, type AuthPasswordUpdateRequest, type AuthSetupRequest, type AuthStatusView, type BindingPeerView, type BochaFreshnessValue, type ChannelAuthPollRequest, type ChannelAuthPollResult, type ChannelAuthStartRequest, type ChannelAuthStartResult, type ChannelSpecView, type ChatCapabilitiesView, type ChatCommandOptionView, type ChatCommandView, type ChatCommandsView, type ChatRunListView, type ChatRunState, type ChatRunView, type ChatSessionTypeCtaView, type ChatSessionTypeOptionView, type ChatSessionTypesView, type ChatTurnRequest, type ChatTurnResult, type ChatTurnStopRequest, type ChatTurnStopResult, type ChatTurnStreamEvent, type ChatTurnView, type ConfigActionExecuteRequest, type ConfigActionExecuteResult, type ConfigActionManifest, type ConfigActionType, type ConfigMetaView, type ConfigSchemaResponse, type ConfigUiHint, type ConfigUiHints, type ConfigView, type CronActionResult, type CronEnableRequest, type CronJobStateView, type CronJobView, type CronListView, type CronPayloadView, type CronRunRequest, type CronScheduleView, DEFAULT_SESSION_TYPE, type MarketplaceApiConfig, type MarketplaceInstallKind, type MarketplaceInstallSkillParams, type MarketplaceInstallSpec, type MarketplaceInstalledRecord, type MarketplaceInstalledView, type MarketplaceInstaller, type MarketplaceItemSummary, type MarketplaceItemType, type MarketplaceItemView, type MarketplaceListView, type MarketplaceLocalizedTextMap, type MarketplaceMcpContentView, type MarketplaceMcpDoctorResult, type MarketplaceMcpInstallKind, type MarketplaceMcpInstallRequest, type MarketplaceMcpInstallResult, type MarketplaceMcpInstallSpec, type MarketplaceMcpManageAction, type MarketplaceMcpManageRequest, type MarketplaceMcpManageResult, type MarketplaceMcpTemplateInput, type MarketplacePluginContentView, type MarketplacePluginInstallKind, type MarketplacePluginInstallRequest, type MarketplacePluginInstallResult, type MarketplacePluginManageAction, type MarketplacePluginManageRequest, type MarketplacePluginManageResult, type MarketplaceRecommendationView, type MarketplaceSkillContentView, type MarketplaceSkillInstallKind, type MarketplaceSkillInstallRequest, type MarketplaceSkillInstallResult, type MarketplaceSkillManageAction, type MarketplaceSkillManageRequest, type MarketplaceSkillManageResult, type MarketplaceSort, type ProviderAuthImportResult, type ProviderAuthPollRequest, type ProviderAuthPollResult, type ProviderAuthStartRequest, type ProviderAuthStartResult, type ProviderConfigUpdate, type ProviderConfigView, type ProviderConnectionTestRequest, type ProviderConnectionTestResult, type ProviderCreateRequest, type ProviderCreateResult, type ProviderDeleteResult, type ProviderSpecView, type RemoteAccessView, type RemoteAccountView, type RemoteBrowserAuthPollRequest, type RemoteBrowserAuthPollResult, type RemoteBrowserAuthStartRequest, type RemoteBrowserAuthStartResult, type RemoteDoctorCheckView, type RemoteDoctorView, type RemoteLoginRequest, type RemoteRuntimeView, type RemoteServiceAction, type RemoteServiceActionResult, type RemoteServiceView, type RemoteSettingsUpdateRequest, type RemoteSettingsView, type RuntimeConfigUpdate, type SearchConfigUpdate, type SearchConfigView, type SearchProviderConfigView, type SearchProviderName, type SearchProviderSpecView, type SecretProviderEnvView, type SecretProviderExecView, type SecretProviderFileView, type SecretProviderView, type SecretRefView, type SecretSourceView, type SecretsConfigUpdate, type SecretsView, type SessionConfigView, type SessionEntryView, type SessionEventView, type SessionHistoryView, type SessionMessageView, type SessionPatchUpdate, SessionPatchValidationError, type SessionTypeDescribeParams, type SessionsListView, type UiChatRuntime, type UiNcpAgent, type UiNcpAttachmentUploadView, type UiNcpAttachmentView, type UiNcpSessionListView, type UiNcpSessionMessagesView, type UiNcpStoredAttachmentRecord, type UiRemoteAccessHost, type UiServerEvent, type UiServerHandle, type UiServerOptions, buildConfigMeta, buildConfigSchemaView, buildConfigView, createCustomProvider, createUiRouter, deleteCustomProvider, deleteSession, ensureUiBridgeSecret, executeConfigAction, getSessionHistory, getUiBridgeSecretPath, listSessions, loadConfigOrDefault, patchSession, readUiBridgeSecret, startUiServer, testProviderConnection, updateChannel, updateModel, updateProvider, updateRuntime, updateSearch, updateSecrets };
1141
+ export { type AgentBindingView, type AgentProfileView, type ApiError, type ApiResponse, type AppMetaView, type AuthEnabledUpdateRequest, type AuthLoginRequest, type AuthPasswordUpdateRequest, type AuthSetupRequest, type AuthStatusView, type BindingPeerView, type BochaFreshnessValue, type ChannelAuthPollRequest, type ChannelAuthPollResult, type ChannelAuthStartRequest, type ChannelAuthStartResult, type ChannelSpecView, type ChatSessionTypeCtaView, type ChatSessionTypeOptionView, type ChatSessionTypesView, type ConfigActionExecuteRequest, type ConfigActionExecuteResult, type ConfigActionManifest, type ConfigActionType, type ConfigMetaView, type ConfigSchemaResponse, type ConfigUiHint, type ConfigUiHints, type ConfigView, type CronActionResult, type CronEnableRequest, type CronJobStateView, type CronJobView, type CronListView, type CronPayloadView, type CronRunRequest, type CronScheduleView, DEFAULT_SESSION_TYPE, type MarketplaceApiConfig, type MarketplaceInstallKind, type MarketplaceInstallSkillParams, type MarketplaceInstallSpec, type MarketplaceInstalledRecord, type MarketplaceInstalledView, type MarketplaceInstaller, type MarketplaceItemSummary, type MarketplaceItemType, type MarketplaceItemView, type MarketplaceListView, type MarketplaceLocalizedTextMap, type MarketplaceMcpContentView, type MarketplaceMcpDoctorResult, type MarketplaceMcpInstallKind, type MarketplaceMcpInstallRequest, type MarketplaceMcpInstallResult, type MarketplaceMcpInstallSpec, type MarketplaceMcpManageAction, type MarketplaceMcpManageRequest, type MarketplaceMcpManageResult, type MarketplaceMcpTemplateInput, type MarketplacePluginContentView, type MarketplacePluginInstallKind, type MarketplacePluginInstallRequest, type MarketplacePluginInstallResult, type MarketplacePluginManageAction, type MarketplacePluginManageRequest, type MarketplacePluginManageResult, type MarketplaceRecommendationView, type MarketplaceSkillContentView, type MarketplaceSkillInstallKind, type MarketplaceSkillInstallRequest, type MarketplaceSkillInstallResult, type MarketplaceSkillManageAction, type MarketplaceSkillManageRequest, type MarketplaceSkillManageResult, type MarketplaceSort, type ProviderAuthImportResult, type ProviderAuthPollRequest, type ProviderAuthPollResult, type ProviderAuthStartRequest, type ProviderAuthStartResult, type ProviderConfigUpdate, type ProviderConfigView, type ProviderConnectionTestRequest, type ProviderConnectionTestResult, type ProviderCreateRequest, type ProviderCreateResult, type ProviderDeleteResult, type ProviderSpecView, type RemoteAccessView, type RemoteAccountView, type RemoteBrowserAuthPollRequest, type RemoteBrowserAuthPollResult, type RemoteBrowserAuthStartRequest, type RemoteBrowserAuthStartResult, type RemoteDoctorCheckView, type RemoteDoctorView, type RemoteLoginRequest, type RemoteRuntimeView, type RemoteServiceAction, type RemoteServiceActionResult, type RemoteServiceView, type RemoteSettingsUpdateRequest, type RemoteSettingsView, type RuntimeConfigUpdate, type SearchConfigUpdate, type SearchConfigView, type SearchProviderConfigView, type SearchProviderName, type SearchProviderSpecView, type SecretProviderEnvView, type SecretProviderExecView, type SecretProviderFileView, type SecretProviderView, type SecretRefView, type SecretSourceView, type SecretsConfigUpdate, type SecretsView, type SessionConfigView, type SessionEntryView, type SessionEventView, type SessionHistoryView, type SessionMessageView, type SessionPatchUpdate, SessionPatchValidationError, type SessionTypeDescribeParams, type SessionsListView, type UiNcpAgent, type UiNcpAssetPutView, type UiNcpAssetView, type UiNcpSessionListView, type UiNcpSessionMessagesView, type UiNcpStoredAssetRecord, type UiRemoteAccessHost, type UiServerEvent, type UiServerHandle, type UiServerOptions, buildConfigMeta, buildConfigSchemaView, buildConfigView, createCustomProvider, createUiRouter, deleteCustomProvider, deleteSession, ensureUiBridgeSecret, executeConfigAction, getSessionHistory, getUiBridgeSecretPath, listSessions, loadConfigOrDefault, patchSession, readUiBridgeSecret, startUiServer, testProviderConnection, updateChannel, updateModel, updateProvider, updateRuntime, updateSearch, updateSecrets };
package/dist/index.js CHANGED
@@ -396,7 +396,7 @@ var AppRoutesController = class {
396
396
  ok({
397
397
  status: "ok",
398
398
  services: {
399
- chatRuntime: this.options.chatRuntime ? "ready" : "unavailable",
399
+ ncpAgent: this.options.ncpAgent ? "ready" : "unavailable",
400
400
  cronService: this.options.cronService ? "ready" : "unavailable"
401
401
  }
402
402
  })
@@ -548,9 +548,6 @@ var AuthRoutesController = class {
548
548
  };
549
549
  };
550
550
 
551
- // src/ui/router/chat.controller.ts
552
- import * as NextclawCore2 from "@nextclaw/core";
553
-
554
551
  // src/ui/config.ts
555
552
  import {
556
553
  loadConfig as loadConfig2,
@@ -2017,596 +2014,6 @@ function updateSecrets(configPath, patch) {
2017
2014
  };
2018
2015
  }
2019
2016
 
2020
- // src/ui/router/chat-utils.ts
2021
- import * as NextclawCore from "@nextclaw/core";
2022
- function normalizeSessionType2(value) {
2023
- return readNonEmptyString(value)?.toLowerCase();
2024
- }
2025
- function resolveSessionTypeLabel(sessionType) {
2026
- if (sessionType === "native") {
2027
- return "Native";
2028
- }
2029
- return sessionType.trim().split(/[-_]+/g).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ") || sessionType;
2030
- }
2031
- async function buildChatSessionTypesView(chatRuntime) {
2032
- if (!chatRuntime?.listSessionTypes) {
2033
- return {
2034
- defaultType: DEFAULT_SESSION_TYPE,
2035
- options: [{ value: DEFAULT_SESSION_TYPE, label: resolveSessionTypeLabel(DEFAULT_SESSION_TYPE) }]
2036
- };
2037
- }
2038
- const payload = await chatRuntime.listSessionTypes();
2039
- const deduped = /* @__PURE__ */ new Map();
2040
- for (const rawOption of payload.options ?? []) {
2041
- const normalized = normalizeSessionType2(rawOption.value);
2042
- if (!normalized) {
2043
- continue;
2044
- }
2045
- deduped.set(normalized, {
2046
- value: normalized,
2047
- label: readNonEmptyString(rawOption.label) ?? resolveSessionTypeLabel(normalized)
2048
- });
2049
- }
2050
- if (!deduped.has(DEFAULT_SESSION_TYPE)) {
2051
- deduped.set(DEFAULT_SESSION_TYPE, {
2052
- value: DEFAULT_SESSION_TYPE,
2053
- label: resolveSessionTypeLabel(DEFAULT_SESSION_TYPE)
2054
- });
2055
- }
2056
- const defaultType = normalizeSessionType2(payload.defaultType) ?? DEFAULT_SESSION_TYPE;
2057
- if (!deduped.has(defaultType)) {
2058
- deduped.set(defaultType, {
2059
- value: defaultType,
2060
- label: resolveSessionTypeLabel(defaultType)
2061
- });
2062
- }
2063
- const options = Array.from(deduped.values()).sort((left, right) => {
2064
- if (left.value === DEFAULT_SESSION_TYPE) {
2065
- return -1;
2066
- }
2067
- if (right.value === DEFAULT_SESSION_TYPE) {
2068
- return 1;
2069
- }
2070
- return left.value.localeCompare(right.value);
2071
- });
2072
- return {
2073
- defaultType,
2074
- options
2075
- };
2076
- }
2077
- function resolveAgentIdFromSessionKey(sessionKey) {
2078
- const parsed = NextclawCore.parseAgentScopedSessionKey(sessionKey);
2079
- const agentId = readNonEmptyString(parsed?.agentId);
2080
- return agentId;
2081
- }
2082
- function createChatRunId() {
2083
- const now = Date.now().toString(36);
2084
- const rand = Math.random().toString(36).slice(2, 10);
2085
- return `run-${now}-${rand}`;
2086
- }
2087
- function isChatRunState(value) {
2088
- return value === "queued" || value === "running" || value === "completed" || value === "failed" || value === "aborted";
2089
- }
2090
- function readChatRunStates(value) {
2091
- if (typeof value !== "string") {
2092
- return void 0;
2093
- }
2094
- const values = value.split(",").map((item) => item.trim().toLowerCase()).filter((item) => Boolean(item) && isChatRunState(item));
2095
- if (values.length === 0) {
2096
- return void 0;
2097
- }
2098
- return Array.from(new Set(values));
2099
- }
2100
- function buildChatTurnView(params) {
2101
- const completedAt = /* @__PURE__ */ new Date();
2102
- return {
2103
- reply: String(params.result.reply ?? ""),
2104
- sessionKey: readNonEmptyString(params.result.sessionKey) ?? params.fallbackSessionKey,
2105
- ...readNonEmptyString(params.result.agentId) || params.requestedAgentId ? { agentId: readNonEmptyString(params.result.agentId) ?? params.requestedAgentId } : {},
2106
- ...readNonEmptyString(params.result.model) || params.requestedModel ? { model: readNonEmptyString(params.result.model) ?? params.requestedModel } : {},
2107
- requestedAt: params.requestedAt.toISOString(),
2108
- completedAt: completedAt.toISOString(),
2109
- durationMs: Math.max(0, completedAt.getTime() - params.startedAtMs)
2110
- };
2111
- }
2112
- function buildChatTurnViewFromRun(params) {
2113
- const requestedAt = readNonEmptyString(params.run.requestedAt) ?? (/* @__PURE__ */ new Date()).toISOString();
2114
- const completedAt = readNonEmptyString(params.run.completedAt) ?? (/* @__PURE__ */ new Date()).toISOString();
2115
- const requestedAtMs = Date.parse(requestedAt);
2116
- const completedAtMs = Date.parse(completedAt);
2117
- return {
2118
- reply: readNonEmptyString(params.run.reply) ?? params.fallbackReply ?? "",
2119
- sessionKey: readNonEmptyString(params.run.sessionKey) ?? params.fallbackSessionKey,
2120
- ...readNonEmptyString(params.run.agentId) || params.fallbackAgentId ? { agentId: readNonEmptyString(params.run.agentId) ?? params.fallbackAgentId } : {},
2121
- ...readNonEmptyString(params.run.model) || params.fallbackModel ? { model: readNonEmptyString(params.run.model) ?? params.fallbackModel } : {},
2122
- requestedAt,
2123
- completedAt,
2124
- durationMs: Number.isFinite(requestedAtMs) && Number.isFinite(completedAtMs) ? Math.max(0, completedAtMs - requestedAtMs) : 0
2125
- };
2126
- }
2127
- function toSseFrame(event, data) {
2128
- return `event: ${event}
2129
- data: ${JSON.stringify(data)}
2130
-
2131
- `;
2132
- }
2133
-
2134
- // src/ui/router/chat.controller.ts
2135
- var ChatRoutesController = class {
2136
- constructor(options) {
2137
- this.options = options;
2138
- }
2139
- getCapabilities = async (c) => {
2140
- const chatRuntime = this.options.chatRuntime;
2141
- if (!chatRuntime) {
2142
- return c.json(err("NOT_AVAILABLE", "chat runtime unavailable"), 503);
2143
- }
2144
- const query = c.req.query();
2145
- const params = {
2146
- sessionKey: readNonEmptyString(query.sessionKey),
2147
- agentId: readNonEmptyString(query.agentId)
2148
- };
2149
- try {
2150
- const capabilities = chatRuntime.getCapabilities ? await chatRuntime.getCapabilities(params) : { stopSupported: Boolean(chatRuntime.stopTurn) };
2151
- return c.json(ok(capabilities));
2152
- } catch (error) {
2153
- return c.json(err("CHAT_RUNTIME_FAILED", String(error)), 500);
2154
- }
2155
- };
2156
- getSessionTypes = async (c) => {
2157
- try {
2158
- const payload = await buildChatSessionTypesView(this.options.chatRuntime);
2159
- return c.json(ok(payload));
2160
- } catch (error) {
2161
- return c.json(err("CHAT_SESSION_TYPES_FAILED", String(error)), 500);
2162
- }
2163
- };
2164
- getCommands = async (c) => {
2165
- try {
2166
- const config = loadConfigOrDefault(this.options.configPath);
2167
- const registry = new NextclawCore2.CommandRegistry(config);
2168
- const commands = registry.listSlashCommands().map((command) => ({
2169
- name: command.name,
2170
- description: command.description,
2171
- ...Array.isArray(command.options) && command.options.length > 0 ? {
2172
- options: command.options.map((option) => ({
2173
- name: option.name,
2174
- description: option.description,
2175
- type: option.type,
2176
- ...option.required === true ? { required: true } : {}
2177
- }))
2178
- } : {}
2179
- }));
2180
- const payload = {
2181
- commands,
2182
- total: commands.length
2183
- };
2184
- return c.json(ok(payload));
2185
- } catch (error) {
2186
- return c.json(err("CHAT_COMMANDS_FAILED", String(error)), 500);
2187
- }
2188
- };
2189
- processTurn = async (c) => {
2190
- if (!this.options.chatRuntime) {
2191
- return c.json(err("NOT_AVAILABLE", "chat runtime unavailable"), 503);
2192
- }
2193
- const body = await readJson(c.req.raw);
2194
- if (!body.ok) {
2195
- return c.json(err("INVALID_BODY", "invalid json body"), 400);
2196
- }
2197
- const message = readNonEmptyString(body.data.message);
2198
- if (!message) {
2199
- return c.json(err("INVALID_BODY", "message is required"), 400);
2200
- }
2201
- const sessionKey = readNonEmptyString(body.data.sessionKey) ?? `ui:${Date.now().toString(36)}:${Math.random().toString(36).slice(2, 8)}`;
2202
- const requestedAt = /* @__PURE__ */ new Date();
2203
- const startedAtMs = requestedAt.getTime();
2204
- const metadata = isRecord(body.data.metadata) ? body.data.metadata : void 0;
2205
- const requestedAgentId = readNonEmptyString(body.data.agentId) ?? resolveAgentIdFromSessionKey(sessionKey);
2206
- const requestedModel = readNonEmptyString(body.data.model);
2207
- const request = {
2208
- message,
2209
- sessionKey,
2210
- channel: readNonEmptyString(body.data.channel) ?? "ui",
2211
- chatId: readNonEmptyString(body.data.chatId) ?? "web-ui",
2212
- ...requestedAgentId ? { agentId: requestedAgentId } : {},
2213
- ...requestedModel ? { model: requestedModel } : {},
2214
- ...metadata ? { metadata } : {}
2215
- };
2216
- try {
2217
- const result = await this.options.chatRuntime.processTurn(request);
2218
- const response = buildChatTurnView({
2219
- result,
2220
- fallbackSessionKey: sessionKey,
2221
- requestedAgentId,
2222
- requestedModel,
2223
- requestedAt,
2224
- startedAtMs
2225
- });
2226
- this.options.publish({ type: "config.updated", payload: { path: "session" } });
2227
- return c.json(ok(response));
2228
- } catch (error) {
2229
- return c.json(err("CHAT_TURN_FAILED", formatUserFacingError(error)), 500);
2230
- }
2231
- };
2232
- stopTurn = async (c) => {
2233
- const chatRuntime = this.options.chatRuntime;
2234
- if (!chatRuntime?.stopTurn) {
2235
- return c.json(err("NOT_AVAILABLE", "chat turn stop is not supported by runtime"), 503);
2236
- }
2237
- const body = await readJson(c.req.raw);
2238
- if (!body.ok || !body.data || typeof body.data !== "object") {
2239
- return c.json(err("INVALID_BODY", "invalid json body"), 400);
2240
- }
2241
- const runId = readNonEmptyString(body.data.runId);
2242
- if (!runId) {
2243
- return c.json(err("INVALID_BODY", "runId is required"), 400);
2244
- }
2245
- const request = {
2246
- runId,
2247
- ...readNonEmptyString(body.data.sessionKey) ? { sessionKey: readNonEmptyString(body.data.sessionKey) } : {},
2248
- ...readNonEmptyString(body.data.agentId) ? { agentId: readNonEmptyString(body.data.agentId) } : {}
2249
- };
2250
- try {
2251
- const result = await chatRuntime.stopTurn(request);
2252
- return c.json(ok(result));
2253
- } catch (error) {
2254
- return c.json(err("CHAT_TURN_STOP_FAILED", String(error)), 500);
2255
- }
2256
- };
2257
- streamTurn = async (c) => {
2258
- const chatRuntime = this.options.chatRuntime;
2259
- if (!chatRuntime) {
2260
- return c.json(err("NOT_AVAILABLE", "chat runtime unavailable"), 503);
2261
- }
2262
- const body = await readJson(c.req.raw);
2263
- if (!body.ok) {
2264
- return c.json(err("INVALID_BODY", "invalid json body"), 400);
2265
- }
2266
- const message = readNonEmptyString(body.data.message);
2267
- if (!message) {
2268
- return c.json(err("INVALID_BODY", "message is required"), 400);
2269
- }
2270
- const sessionKey = readNonEmptyString(body.data.sessionKey) ?? `ui:${Date.now().toString(36)}:${Math.random().toString(36).slice(2, 8)}`;
2271
- const requestedAt = /* @__PURE__ */ new Date();
2272
- const startedAtMs = requestedAt.getTime();
2273
- const metadata = isRecord(body.data.metadata) ? body.data.metadata : void 0;
2274
- const requestedAgentId = readNonEmptyString(body.data.agentId) ?? resolveAgentIdFromSessionKey(sessionKey);
2275
- const requestedModel = readNonEmptyString(body.data.model);
2276
- let runId = createChatRunId();
2277
- const supportsManagedRuns = Boolean(chatRuntime.startTurnRun && chatRuntime.streamRun);
2278
- let stopCapabilities = { stopSupported: Boolean(chatRuntime.stopTurn) };
2279
- if (chatRuntime.getCapabilities) {
2280
- try {
2281
- stopCapabilities = await chatRuntime.getCapabilities({
2282
- sessionKey,
2283
- ...requestedAgentId ? { agentId: requestedAgentId } : {}
2284
- });
2285
- } catch {
2286
- stopCapabilities = {
2287
- stopSupported: false,
2288
- stopReason: "failed to resolve runtime stop capability"
2289
- };
2290
- }
2291
- }
2292
- const request = {
2293
- message,
2294
- sessionKey,
2295
- channel: readNonEmptyString(body.data.channel) ?? "ui",
2296
- chatId: readNonEmptyString(body.data.chatId) ?? "web-ui",
2297
- runId,
2298
- ...requestedAgentId ? { agentId: requestedAgentId } : {},
2299
- ...requestedModel ? { model: requestedModel } : {},
2300
- ...metadata ? { metadata } : {}
2301
- };
2302
- let managedRun = null;
2303
- if (supportsManagedRuns && chatRuntime.startTurnRun) {
2304
- try {
2305
- managedRun = await chatRuntime.startTurnRun(request);
2306
- } catch (error) {
2307
- return c.json(err("CHAT_TURN_FAILED", formatUserFacingError(error)), 500);
2308
- }
2309
- if (readNonEmptyString(managedRun.runId)) {
2310
- runId = readNonEmptyString(managedRun.runId);
2311
- }
2312
- stopCapabilities = {
2313
- stopSupported: managedRun.stopSupported,
2314
- ...readNonEmptyString(managedRun.stopReason) ? { stopReason: readNonEmptyString(managedRun.stopReason) } : {}
2315
- };
2316
- }
2317
- const encoder = new TextEncoder();
2318
- const stream = new ReadableStream({
2319
- start: async (controller) => {
2320
- const push = (event, data) => {
2321
- controller.enqueue(encoder.encode(toSseFrame(event, data)));
2322
- };
2323
- try {
2324
- push("ready", {
2325
- sessionKey: managedRun?.sessionKey ?? sessionKey,
2326
- requestedAt: managedRun?.requestedAt ?? requestedAt.toISOString(),
2327
- runId,
2328
- stopSupported: stopCapabilities.stopSupported,
2329
- ...readNonEmptyString(stopCapabilities.stopReason) ? { stopReason: readNonEmptyString(stopCapabilities.stopReason) } : {}
2330
- });
2331
- if (supportsManagedRuns && chatRuntime.streamRun) {
2332
- let hasFinal2 = false;
2333
- for await (const event of chatRuntime.streamRun({ runId })) {
2334
- const typed = event;
2335
- if (typed.type === "delta") {
2336
- if (typed.delta) {
2337
- push("delta", { delta: typed.delta });
2338
- }
2339
- continue;
2340
- }
2341
- if (typed.type === "session_event") {
2342
- push("session_event", typed.event);
2343
- continue;
2344
- }
2345
- if (typed.type === "final") {
2346
- const latestRun = chatRuntime.getRun ? await chatRuntime.getRun({ runId }) : null;
2347
- const response = latestRun ? buildChatTurnViewFromRun({
2348
- run: latestRun,
2349
- fallbackSessionKey: sessionKey,
2350
- fallbackAgentId: requestedAgentId,
2351
- fallbackModel: requestedModel,
2352
- fallbackReply: typed.result.reply
2353
- }) : buildChatTurnView({
2354
- result: typed.result,
2355
- fallbackSessionKey: sessionKey,
2356
- requestedAgentId,
2357
- requestedModel,
2358
- requestedAt,
2359
- startedAtMs
2360
- });
2361
- hasFinal2 = true;
2362
- push("final", response);
2363
- this.options.publish({ type: "config.updated", payload: { path: "session" } });
2364
- continue;
2365
- }
2366
- if (typed.type === "error") {
2367
- push("error", {
2368
- code: "CHAT_TURN_FAILED",
2369
- message: formatUserFacingError(typed.error)
2370
- });
2371
- return;
2372
- }
2373
- }
2374
- if (!hasFinal2) {
2375
- push("error", {
2376
- code: "CHAT_TURN_FAILED",
2377
- message: "stream ended without a final result"
2378
- });
2379
- return;
2380
- }
2381
- push("done", { ok: true });
2382
- return;
2383
- }
2384
- const streamTurn = chatRuntime.processTurnStream;
2385
- if (!streamTurn) {
2386
- const result = await chatRuntime.processTurn(request);
2387
- const response = buildChatTurnView({
2388
- result,
2389
- fallbackSessionKey: sessionKey,
2390
- requestedAgentId,
2391
- requestedModel,
2392
- requestedAt,
2393
- startedAtMs
2394
- });
2395
- push("final", response);
2396
- this.options.publish({ type: "config.updated", payload: { path: "session" } });
2397
- push("done", { ok: true });
2398
- return;
2399
- }
2400
- let hasFinal = false;
2401
- for await (const event of streamTurn(request)) {
2402
- const typed = event;
2403
- if (typed.type === "delta") {
2404
- if (typed.delta) {
2405
- push("delta", { delta: typed.delta });
2406
- }
2407
- continue;
2408
- }
2409
- if (typed.type === "session_event") {
2410
- push("session_event", typed.event);
2411
- continue;
2412
- }
2413
- if (typed.type === "final") {
2414
- const response = buildChatTurnView({
2415
- result: typed.result,
2416
- fallbackSessionKey: sessionKey,
2417
- requestedAgentId,
2418
- requestedModel,
2419
- requestedAt,
2420
- startedAtMs
2421
- });
2422
- hasFinal = true;
2423
- push("final", response);
2424
- this.options.publish({ type: "config.updated", payload: { path: "session" } });
2425
- continue;
2426
- }
2427
- if (typed.type === "error") {
2428
- push("error", {
2429
- code: "CHAT_TURN_FAILED",
2430
- message: formatUserFacingError(typed.error)
2431
- });
2432
- return;
2433
- }
2434
- }
2435
- if (!hasFinal) {
2436
- push("error", {
2437
- code: "CHAT_TURN_FAILED",
2438
- message: "stream ended without a final result"
2439
- });
2440
- return;
2441
- }
2442
- push("done", { ok: true });
2443
- } catch (error) {
2444
- push("error", {
2445
- code: "CHAT_TURN_FAILED",
2446
- message: formatUserFacingError(error)
2447
- });
2448
- } finally {
2449
- controller.close();
2450
- }
2451
- }
2452
- });
2453
- return new Response(stream, {
2454
- status: 200,
2455
- headers: {
2456
- "Content-Type": "text/event-stream; charset=utf-8",
2457
- "Cache-Control": "no-cache, no-transform",
2458
- "Connection": "keep-alive",
2459
- "X-Accel-Buffering": "no"
2460
- }
2461
- });
2462
- };
2463
- listRuns = async (c) => {
2464
- const chatRuntime = this.options.chatRuntime;
2465
- if (!chatRuntime?.listRuns) {
2466
- return c.json(err("NOT_AVAILABLE", "chat run management unavailable"), 503);
2467
- }
2468
- const query = c.req.query();
2469
- const sessionKey = readNonEmptyString(query.sessionKey);
2470
- const states = readChatRunStates(query.states);
2471
- const limit = typeof query.limit === "string" ? Number.parseInt(query.limit, 10) : void 0;
2472
- try {
2473
- const data = await chatRuntime.listRuns({
2474
- ...sessionKey ? { sessionKey } : {},
2475
- ...states ? { states } : {},
2476
- ...Number.isFinite(limit) ? { limit } : {}
2477
- });
2478
- return c.json(ok(data));
2479
- } catch (error) {
2480
- return c.json(err("CHAT_RUN_QUERY_FAILED", String(error)), 500);
2481
- }
2482
- };
2483
- getRun = async (c) => {
2484
- const chatRuntime = this.options.chatRuntime;
2485
- if (!chatRuntime?.getRun) {
2486
- return c.json(err("NOT_AVAILABLE", "chat run management unavailable"), 503);
2487
- }
2488
- const runId = readNonEmptyString(c.req.param("runId"));
2489
- if (!runId) {
2490
- return c.json(err("INVALID_PATH", "runId is required"), 400);
2491
- }
2492
- try {
2493
- const run = await chatRuntime.getRun({ runId });
2494
- if (!run) {
2495
- return c.json(err("NOT_FOUND", `chat run not found: ${runId}`), 404);
2496
- }
2497
- return c.json(ok(run));
2498
- } catch (error) {
2499
- return c.json(err("CHAT_RUN_QUERY_FAILED", String(error)), 500);
2500
- }
2501
- };
2502
- streamRun = async (c) => {
2503
- const chatRuntime = this.options.chatRuntime;
2504
- const streamRun = chatRuntime?.streamRun;
2505
- const getRun = chatRuntime?.getRun;
2506
- if (!streamRun || !getRun) {
2507
- return c.json(err("NOT_AVAILABLE", "chat run stream unavailable"), 503);
2508
- }
2509
- const runId = readNonEmptyString(c.req.param("runId"));
2510
- if (!runId) {
2511
- return c.json(err("INVALID_PATH", "runId is required"), 400);
2512
- }
2513
- const query = c.req.query();
2514
- const fromEventIndex = typeof query.fromEventIndex === "string" ? Number.parseInt(query.fromEventIndex, 10) : void 0;
2515
- const run = await getRun({ runId });
2516
- if (!run) {
2517
- return c.json(err("NOT_FOUND", `chat run not found: ${runId}`), 404);
2518
- }
2519
- const encoder = new TextEncoder();
2520
- const stream = new ReadableStream({
2521
- start: async (controller) => {
2522
- const push = (event, data) => {
2523
- controller.enqueue(encoder.encode(toSseFrame(event, data)));
2524
- };
2525
- try {
2526
- push("ready", {
2527
- sessionKey: run.sessionKey,
2528
- requestedAt: run.requestedAt,
2529
- runId: run.runId,
2530
- stopSupported: run.stopSupported,
2531
- ...readNonEmptyString(run.stopReason) ? { stopReason: readNonEmptyString(run.stopReason) } : {}
2532
- });
2533
- let hasFinal = false;
2534
- for await (const event of streamRun({
2535
- runId: run.runId,
2536
- ...Number.isFinite(fromEventIndex) ? { fromEventIndex } : {}
2537
- })) {
2538
- const typed = event;
2539
- if (typed.type === "delta") {
2540
- if (typed.delta) {
2541
- push("delta", { delta: typed.delta });
2542
- }
2543
- continue;
2544
- }
2545
- if (typed.type === "session_event") {
2546
- push("session_event", typed.event);
2547
- continue;
2548
- }
2549
- if (typed.type === "final") {
2550
- const latestRun = await getRun({ runId: run.runId });
2551
- const response = latestRun ? buildChatTurnViewFromRun({
2552
- run: latestRun,
2553
- fallbackSessionKey: run.sessionKey,
2554
- fallbackAgentId: run.agentId,
2555
- fallbackModel: run.model,
2556
- fallbackReply: typed.result.reply
2557
- }) : buildChatTurnView({
2558
- result: typed.result,
2559
- fallbackSessionKey: run.sessionKey,
2560
- requestedAgentId: run.agentId,
2561
- requestedModel: run.model,
2562
- requestedAt: new Date(run.requestedAt),
2563
- startedAtMs: Date.parse(run.requestedAt)
2564
- });
2565
- hasFinal = true;
2566
- push("final", response);
2567
- continue;
2568
- }
2569
- if (typed.type === "error") {
2570
- push("error", {
2571
- code: "CHAT_TURN_FAILED",
2572
- message: formatUserFacingError(typed.error)
2573
- });
2574
- return;
2575
- }
2576
- }
2577
- if (!hasFinal) {
2578
- const latestRun = await getRun({ runId: run.runId });
2579
- if (latestRun?.state === "failed") {
2580
- push("error", {
2581
- code: "CHAT_TURN_FAILED",
2582
- message: formatUserFacingError(latestRun.error ?? "chat run failed")
2583
- });
2584
- return;
2585
- }
2586
- }
2587
- push("done", { ok: true });
2588
- } catch (error) {
2589
- push("error", {
2590
- code: "CHAT_TURN_FAILED",
2591
- message: formatUserFacingError(error)
2592
- });
2593
- } finally {
2594
- controller.close();
2595
- }
2596
- }
2597
- });
2598
- return new Response(stream, {
2599
- status: 200,
2600
- headers: {
2601
- "Content-Type": "text/event-stream; charset=utf-8",
2602
- "Cache-Control": "no-cache, no-transform",
2603
- "Connection": "keep-alive",
2604
- "X-Accel-Buffering": "no"
2605
- }
2606
- });
2607
- };
2608
- };
2609
-
2610
2017
  // src/ui/channel-auth.ts
2611
2018
  import { saveConfig as saveConfig3 } from "@nextclaw/core";
2612
2019
  import {
@@ -3623,32 +3030,32 @@ var CronRoutesController = class {
3623
3030
 
3624
3031
  // src/ui/router/ncp-attachment.controller.ts
3625
3032
  import { readFile as readFile2 } from "fs/promises";
3626
- var ATTACHMENT_CONTENT_BASE_PATH = "/api/ncp/attachments/content";
3627
- function buildAttachmentContentUrl(attachmentUri) {
3628
- const query = new URLSearchParams({ uri: attachmentUri });
3629
- return `${ATTACHMENT_CONTENT_BASE_PATH}?${query.toString()}`;
3033
+ var ASSET_CONTENT_BASE_PATH = "/api/ncp/assets/content";
3034
+ function buildAssetContentUrl(assetUri) {
3035
+ const query = new URLSearchParams({ uri: assetUri });
3036
+ return `${ASSET_CONTENT_BASE_PATH}?${query.toString()}`;
3630
3037
  }
3631
3038
  function encodeContentDispositionFileName(fileName) {
3632
3039
  return encodeURIComponent(fileName).replace(/\*/g, "%2A");
3633
3040
  }
3634
- function toAttachmentView(record) {
3041
+ function toAssetView(record) {
3635
3042
  return {
3636
3043
  id: record.id,
3637
- name: record.originalName,
3044
+ name: record.fileName,
3638
3045
  mimeType: record.mimeType,
3639
3046
  sizeBytes: record.sizeBytes,
3640
- attachmentUri: record.uri,
3641
- url: buildAttachmentContentUrl(record.uri)
3047
+ assetUri: record.uri,
3048
+ url: buildAssetContentUrl(record.uri)
3642
3049
  };
3643
3050
  }
3644
- var NcpAttachmentRoutesController = class {
3051
+ var NcpAssetRoutesController = class {
3645
3052
  constructor(options) {
3646
3053
  this.options = options;
3647
3054
  }
3648
- uploadAttachments = async (c) => {
3649
- const attachmentApi = this.options.ncpAgent?.attachmentApi;
3650
- if (!attachmentApi) {
3651
- return c.json(err("NOT_AVAILABLE", "ncp attachment api unavailable"), 503);
3055
+ putAssets = async (c) => {
3056
+ const assetApi = this.options.ncpAgent?.assetApi;
3057
+ if (!assetApi) {
3058
+ return c.json(err("NOT_AVAILABLE", "ncp asset api unavailable"), 503);
3652
3059
  }
3653
3060
  let formData;
3654
3061
  try {
@@ -3665,38 +3072,38 @@ var NcpAttachmentRoutesController = class {
3665
3072
  if (files.length === 0) {
3666
3073
  return c.json(err("INVALID_BODY", "no files provided"), 400);
3667
3074
  }
3668
- const attachments = [];
3075
+ const assets = [];
3669
3076
  for (const file of files) {
3670
- const record = await attachmentApi.saveAttachment({
3077
+ const record = await assetApi.put({
3671
3078
  fileName: file.name,
3672
3079
  mimeType: file.type || null,
3673
3080
  bytes: new Uint8Array(await file.arrayBuffer())
3674
3081
  });
3675
- attachments.push(toAttachmentView(record));
3082
+ assets.push(toAssetView(record));
3676
3083
  }
3677
- const payload = { attachments };
3084
+ const payload = { assets };
3678
3085
  return c.json(ok(payload));
3679
3086
  };
3680
- getAttachmentContent = async (c) => {
3681
- const attachmentApi = this.options.ncpAgent?.attachmentApi;
3682
- if (!attachmentApi) {
3683
- return c.json(err("NOT_AVAILABLE", "ncp attachment api unavailable"), 503);
3087
+ getAssetContent = async (c) => {
3088
+ const assetApi = this.options.ncpAgent?.assetApi;
3089
+ if (!assetApi) {
3090
+ return c.json(err("NOT_AVAILABLE", "ncp asset api unavailable"), 503);
3684
3091
  }
3685
3092
  const uri = c.req.query("uri")?.trim();
3686
3093
  if (!uri) {
3687
- return c.json(err("INVALID_URI", "attachment uri is required"), 400);
3094
+ return c.json(err("INVALID_URI", "asset uri is required"), 400);
3688
3095
  }
3689
- const record = await attachmentApi.statAttachment(uri);
3690
- const contentPath = attachmentApi.resolveContentPath(uri);
3096
+ const record = await assetApi.stat(uri);
3097
+ const contentPath = assetApi.resolveContentPath(uri);
3691
3098
  if (!record || !contentPath) {
3692
- return c.json(err("NOT_FOUND", `attachment not found: ${uri}`), 404);
3099
+ return c.json(err("NOT_FOUND", `asset not found: ${uri}`), 404);
3693
3100
  }
3694
3101
  const body = await readFile2(contentPath);
3695
3102
  return new Response(body, {
3696
3103
  headers: {
3697
3104
  "content-length": String(body.byteLength),
3698
3105
  "content-type": record.mimeType || "application/octet-stream",
3699
- "content-disposition": `inline; filename*=UTF-8''${encodeContentDispositionFileName(record.originalName)}`
3106
+ "content-disposition": `inline; filename*=UTF-8''${encodeContentDispositionFileName(record.fileName)}`
3700
3107
  }
3701
3108
  });
3702
3109
  };
@@ -4341,7 +3748,7 @@ var McpMarketplaceController = class {
4341
3748
  };
4342
3749
 
4343
3750
  // src/ui/router/marketplace/installed.ts
4344
- import * as NextclawCore3 from "@nextclaw/core";
3751
+ import * as NextclawCore from "@nextclaw/core";
4345
3752
  import { discoverPluginStatusReport } from "@nextclaw/openclaw-compat";
4346
3753
 
4347
3754
  // src/ui/router/marketplace/spec.ts
@@ -4448,9 +3855,9 @@ function dedupeInstalledPluginRecordsByCanonicalSpec(records) {
4448
3855
  }
4449
3856
 
4450
3857
  // src/ui/router/marketplace/installed.ts
4451
- var getWorkspacePathFromConfig3 = NextclawCore3.getWorkspacePathFromConfig;
3858
+ var getWorkspacePathFromConfig3 = NextclawCore.getWorkspacePathFromConfig;
4452
3859
  function createSkillsLoader(workspace) {
4453
- const ctor = NextclawCore3.SkillsLoader;
3860
+ const ctor = NextclawCore.SkillsLoader;
4454
3861
  if (!ctor) {
4455
3862
  return null;
4456
3863
  }
@@ -5362,75 +4769,6 @@ var RemoteRoutesController = class {
5362
4769
  };
5363
4770
  };
5364
4771
 
5365
- // src/ui/router/session.controller.ts
5366
- var SessionRoutesController = class {
5367
- constructor(options) {
5368
- this.options = options;
5369
- }
5370
- listSessions = (c) => {
5371
- const query = c.req.query();
5372
- const q = typeof query.q === "string" ? query.q : void 0;
5373
- const limit = typeof query.limit === "string" ? Number.parseInt(query.limit, 10) : void 0;
5374
- const activeMinutes = typeof query.activeMinutes === "string" ? Number.parseInt(query.activeMinutes, 10) : void 0;
5375
- const data = listSessions(this.options.configPath, {
5376
- q,
5377
- limit: Number.isFinite(limit) ? limit : void 0,
5378
- activeMinutes: Number.isFinite(activeMinutes) ? activeMinutes : void 0
5379
- });
5380
- return c.json(ok(data));
5381
- };
5382
- getSessionHistory = (c) => {
5383
- const key = decodeURIComponent(c.req.param("key"));
5384
- const query = c.req.query();
5385
- const limit = typeof query.limit === "string" ? Number.parseInt(query.limit, 10) : void 0;
5386
- const data = getSessionHistory(this.options.configPath, key, Number.isFinite(limit) ? limit : void 0);
5387
- if (!data) {
5388
- return c.json(err("NOT_FOUND", `session not found: ${key}`), 404);
5389
- }
5390
- return c.json(ok(data));
5391
- };
5392
- patchSession = async (c) => {
5393
- const key = decodeURIComponent(c.req.param("key"));
5394
- const body = await readJson(c.req.raw);
5395
- if (!body.ok || !body.data || typeof body.data !== "object") {
5396
- return c.json(err("INVALID_BODY", "invalid json body"), 400);
5397
- }
5398
- let availableSessionTypes;
5399
- if (Object.prototype.hasOwnProperty.call(body.data, "sessionType")) {
5400
- const sessionTypes = await buildChatSessionTypesView(this.options.chatRuntime);
5401
- availableSessionTypes = sessionTypes.options.map((item) => item.value);
5402
- }
5403
- let data;
5404
- try {
5405
- data = patchSession(this.options.configPath, key, body.data, {
5406
- ...availableSessionTypes ? { availableSessionTypes } : {}
5407
- });
5408
- } catch (error) {
5409
- if (error instanceof SessionPatchValidationError) {
5410
- if (error.code === "SESSION_TYPE_IMMUTABLE") {
5411
- return c.json(err(error.code, error.message), 409);
5412
- }
5413
- return c.json(err(error.code, error.message), 400);
5414
- }
5415
- throw error;
5416
- }
5417
- if (!data) {
5418
- return c.json(err("NOT_FOUND", `session not found: ${key}`), 404);
5419
- }
5420
- this.options.publish({ type: "config.updated", payload: { path: "session" } });
5421
- return c.json(ok(data));
5422
- };
5423
- deleteSession = (c) => {
5424
- const key = decodeURIComponent(c.req.param("key"));
5425
- const deleted = deleteSession(this.options.configPath, key);
5426
- if (!deleted) {
5427
- return c.json(err("NOT_FOUND", `session not found: ${key}`), 404);
5428
- }
5429
- this.options.publish({ type: "config.updated", payload: { path: "session" } });
5430
- return c.json(ok({ deleted: true }));
5431
- };
5432
- };
5433
-
5434
4772
  // src/ui/router.ts
5435
4773
  function registerAuthRoutes(app, authController) {
5436
4774
  app.get("/api/auth/status", authController.getStatus);
@@ -5461,24 +4799,7 @@ function registerConfigRoutes(app, configController) {
5461
4799
  app.put("/api/config/runtime", configController.updateRuntime);
5462
4800
  app.post("/api/config/actions/:actionId/execute", configController.executeAction);
5463
4801
  }
5464
- function registerChatRoutes(app, chatController) {
5465
- app.get("/api/chat/capabilities", chatController.getCapabilities);
5466
- app.get("/api/chat/session-types", chatController.getSessionTypes);
5467
- app.get("/api/chat/commands", chatController.getCommands);
5468
- app.post("/api/chat/turn", chatController.processTurn);
5469
- app.post("/api/chat/turn/stop", chatController.stopTurn);
5470
- app.post("/api/chat/turn/stream", chatController.streamTurn);
5471
- app.get("/api/chat/runs", chatController.listRuns);
5472
- app.get("/api/chat/runs/:runId", chatController.getRun);
5473
- app.get("/api/chat/runs/:runId/stream", chatController.streamRun);
5474
- }
5475
- function registerSessionRoutes(app, sessionController) {
5476
- app.get("/api/sessions", sessionController.listSessions);
5477
- app.get("/api/sessions/:key/history", sessionController.getSessionHistory);
5478
- app.put("/api/sessions/:key", sessionController.patchSession);
5479
- app.delete("/api/sessions/:key", sessionController.deleteSession);
5480
- }
5481
- function registerNcpRoutes(app, options, ncpSessionController, ncpAttachmentController) {
4802
+ function registerNcpRoutes(app, options, ncpSessionController, ncpAssetController) {
5482
4803
  if (!options.ncpAgent) {
5483
4804
  return;
5484
4805
  }
@@ -5493,8 +4814,8 @@ function registerNcpRoutes(app, options, ncpSessionController, ncpAttachmentCont
5493
4814
  app.put("/api/ncp/sessions/:sessionId", ncpSessionController.patchSession);
5494
4815
  app.get("/api/ncp/sessions/:sessionId/messages", ncpSessionController.listSessionMessages);
5495
4816
  app.delete("/api/ncp/sessions/:sessionId", ncpSessionController.deleteSession);
5496
- app.post("/api/ncp/attachments", ncpAttachmentController.uploadAttachments);
5497
- app.get("/api/ncp/attachments/content", ncpAttachmentController.getAttachmentContent);
4817
+ app.post("/api/ncp/assets", ncpAssetController.putAssets);
4818
+ app.get("/api/ncp/assets/content", ncpAssetController.getAssetContent);
5498
4819
  }
5499
4820
  function registerCronRoutes(app, cronController) {
5500
4821
  app.get("/api/cron", cronController.listJobs);
@@ -5522,11 +4843,9 @@ function createUiRouter(options) {
5522
4843
  const appController = new AppRoutesController(options);
5523
4844
  const authController = new AuthRoutesController(authService);
5524
4845
  const configController = new ConfigRoutesController(options);
5525
- const chatController = new ChatRoutesController(options);
5526
- const sessionController = new SessionRoutesController(options);
5527
4846
  const cronController = new CronRoutesController(options);
5528
4847
  const ncpSessionController = new NcpSessionRoutesController(options);
5529
- const ncpAttachmentController = new NcpAttachmentRoutesController(options);
4848
+ const ncpAssetController = new NcpAssetRoutesController(options);
5530
4849
  const remoteController = options.remoteAccess ? new RemoteRoutesController(options.remoteAccess) : null;
5531
4850
  const pluginMarketplaceController = new PluginMarketplaceController(options, marketplaceBaseUrl);
5532
4851
  const skillMarketplaceController = new SkillMarketplaceController(options, marketplaceBaseUrl);
@@ -5549,9 +4868,7 @@ function createUiRouter(options) {
5549
4868
  app.get("/api/app/meta", appController.appMeta);
5550
4869
  registerAuthRoutes(app, authController);
5551
4870
  registerConfigRoutes(app, configController);
5552
- registerChatRoutes(app, chatController);
5553
- registerSessionRoutes(app, sessionController);
5554
- registerNcpRoutes(app, options, ncpSessionController, ncpAttachmentController);
4871
+ registerNcpRoutes(app, options, ncpSessionController, ncpAssetController);
5555
4872
  registerCronRoutes(app, cronController);
5556
4873
  registerRemoteRoutes(app, remoteController);
5557
4874
  mountMarketplaceRoutes(app, {
@@ -5660,7 +4977,6 @@ function startUiServer(options) {
5660
4977
  applyLiveConfigReload: options.applyLiveConfigReload,
5661
4978
  marketplace: options.marketplace,
5662
4979
  cronService: options.cronService,
5663
- chatRuntime: options.chatRuntime,
5664
4980
  ncpAgent: options.ncpAgent,
5665
4981
  authService,
5666
4982
  remoteAccess: options.remoteAccess,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/server",
3
- "version": "0.10.57",
3
+ "version": "0.11.1",
4
4
  "private": false,
5
5
  "description": "Nextclaw UI/API server.",
6
6
  "type": "module",
@@ -19,11 +19,11 @@
19
19
  "hono": "^4.6.2",
20
20
  "ws": "^8.18.0",
21
21
  "@nextclaw/mcp": "0.1.51",
22
- "@nextclaw/ncp-http-agent-server": "0.3.3",
23
- "@nextclaw/ncp": "0.3.3",
22
+ "@nextclaw/ncp": "0.4.0",
23
+ "@nextclaw/openclaw-compat": "0.3.35",
24
+ "@nextclaw/ncp-http-agent-server": "0.3.4",
24
25
  "@nextclaw/runtime": "0.2.16",
25
- "@nextclaw/core": "0.11.2",
26
- "@nextclaw/openclaw-compat": "0.3.33"
26
+ "@nextclaw/core": "0.11.2"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@types/node": "^20.17.6",