@nextclaw/ui 0.9.13 → 0.9.15
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/CHANGELOG.md +15 -0
- package/dist/assets/ChannelsList-Cu_hLbps.js +1 -0
- package/dist/assets/{ChatPage-B9dHVmrV.js → ChatPage-Dmpau_7n.js} +2 -2
- package/dist/assets/{DocBrowser-S-1-qnZQ.js → DocBrowser-C3ijFxFF.js} +1 -1
- package/dist/assets/{LogoBadge-t1JzzCtI.js → LogoBadge-BgjXmBcw.js} +1 -1
- package/dist/assets/{MarketplacePage-CzIHYJpM.js → MarketplacePage-CAIdEiw8.js} +1 -1
- package/dist/assets/{McpMarketplacePage-BTJdjNQ1.js → McpMarketplacePage-DPtH1xcY.js} +1 -1
- package/dist/assets/ModelConfig-D-pqArCg.js +1 -0
- package/dist/assets/{ProvidersList-BOQArFRk.js → ProvidersList-DnWsJqMQ.js} +1 -1
- package/dist/assets/{RemoteAccessPage-CYNQ53xu.js → RemoteAccessPage-BrXq-x0-.js} +1 -1
- package/dist/assets/{RuntimeConfig-B0B73pye.js → RuntimeConfig-UE9VaFO7.js} +1 -1
- package/dist/assets/{SearchConfig-CKy2QkAP.js → SearchConfig-CP-RM3V3.js} +1 -1
- package/dist/assets/{SecretsConfig-BpZLUu88.js → SecretsConfig-CfN_bazs.js} +1 -1
- package/dist/assets/{SessionsConfig-CoFI6Fa2.js → SessionsConfig-CgkKzKGv.js} +1 -1
- package/dist/assets/{chat-message-D3jZIASl.js → chat-message-CGL3sMsS.js} +1 -1
- package/dist/assets/index-D4alkESd.js +8 -0
- package/dist/assets/{label-BOvIOmQx.js → label-CbOSodIL.js} +1 -1
- package/dist/assets/{page-layout-PG3cwSpz.js → page-layout-BtDnyNLf.js} +1 -1
- package/dist/assets/{popover-BB-kINz7.js → popover-DGlUjPQc.js} +1 -1
- package/dist/assets/{security-config-Bb6l-viE.js → security-config-D6Bs1yoK.js} +1 -1
- package/dist/assets/{skeleton-CLSc5FYO.js → skeleton-BLV99JbX.js} +1 -1
- package/dist/assets/{status-dot-Behu7kDZ.js → status-dot-C8vM3IN1.js} +1 -1
- package/dist/assets/{switch-CvNG9775.js → switch-AuwUiga3.js} +1 -1
- package/dist/assets/{tabs-custom-CUdBQO_7.js → tabs-custom-CTS7SaFG.js} +1 -1
- package/dist/assets/{useConfirmDialog-CLLe2uIJ.js → useConfirmDialog-DrMAdNfN.js} +1 -1
- package/dist/index.html +1 -1
- package/dist/logos/weixin.svg +5 -0
- package/package.json +3 -3
- package/public/logos/weixin.svg +5 -0
- package/src/api/config.ts +4 -2
- package/src/components/chat/chat-stream/transport.ts +42 -2
- package/src/components/config/ChannelForm.tsx +1 -122
- package/src/components/config/ChannelsList.test.tsx +127 -0
- package/src/components/config/ChannelsList.tsx +2 -1
- package/src/components/config/ModelConfig.tsx +1 -4
- package/src/components/config/channel-form-fields.ts +131 -0
- package/src/lib/i18n.channels.ts +52 -0
- package/src/lib/i18n.ts +2 -43
- package/src/lib/logos.ts +1 -0
- package/src/transport/app-client.ts +6 -22
- package/src/transport/local.transport.ts +4 -3
- package/src/transport/remote.transport.ts +7 -2
- package/src/transport/sse-stream.test.ts +54 -0
- package/src/transport/sse-stream.ts +3 -17
- package/dist/assets/ChannelsList-bROKR37R.js +0 -1
- package/dist/assets/ModelConfig-BD4o3Kna.js +0 -1
- package/dist/assets/index-CmGwUgcl.js +0 -8
- package/src/components/config/ModelConfig.test.tsx +0 -78
package/src/lib/i18n.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CHANNEL_LABELS } from './i18n.channels';
|
|
1
2
|
import { MARKETPLACE_LABELS } from './i18n.marketplace';
|
|
2
3
|
import { REMOTE_LABELS } from './i18n.remote';
|
|
3
4
|
|
|
@@ -312,49 +313,7 @@ export const LABELS: Record<string, { zh: string; en: string }> = {
|
|
|
312
313
|
leaveBlankToKeepUnchanged: { zh: '留空则保持不变', en: 'Leave blank to keep unchanged' },
|
|
313
314
|
|
|
314
315
|
// Channel
|
|
315
|
-
|
|
316
|
-
channelsPageDescription: { zh: '在一个页面中连续筛选、切换并配置各个消息渠道。', en: 'Filter, switch, and configure messaging channels in one continuous workspace.' },
|
|
317
|
-
channelsLoading: { zh: '加载渠道中...', en: 'Loading channels...' },
|
|
318
|
-
channelsTabEnabled: { zh: '已启用', en: 'Enabled' },
|
|
319
|
-
channelsTabAll: { zh: '全部渠道', en: 'All Channels' },
|
|
320
|
-
channelsFilterPlaceholder: { zh: '搜索渠道', en: 'Search channels' },
|
|
321
|
-
channelsNoMatch: { zh: '没有匹配的渠道', en: 'No matching channels' },
|
|
322
|
-
channelsSelectTitle: { zh: '选择左侧渠道开始配置', en: 'Select a channel from the left to configure' },
|
|
323
|
-
channelsSelectDescription: { zh: '你可以连续切换多个渠道并逐个保存配置。', en: 'Switch between channels continuously and save each configuration.' },
|
|
324
|
-
channelsFormDescription: { zh: '配置消息渠道参数', en: 'Configure message channel parameters' },
|
|
325
|
-
channelsEmptyTitle: { zh: '暂无启用渠道', en: 'No channels enabled' },
|
|
326
|
-
channelsEmptyDescription: { zh: '启用一个消息渠道以开始接收消息。', en: 'Enable a messaging channel to start receiving messages.' },
|
|
327
|
-
channelDescriptionDefault: { zh: '配置该通信渠道', en: 'Configure this communication channel' },
|
|
328
|
-
channelDescTelegram: { zh: '连接 Telegram 机器人以进行即时消息收发', en: 'Connect with Telegram bots for instant messaging' },
|
|
329
|
-
channelDescSlack: { zh: '接入 Slack 工作区进行团队协作消息处理', en: 'Integrate with Slack workspaces for team collaboration' },
|
|
330
|
-
channelDescEmail: { zh: '通过邮件协议收发消息', en: 'Send and receive messages via email protocols' },
|
|
331
|
-
channelDescWebhook: { zh: '接收 HTTP Webhook 以支持自定义集成', en: 'Receive HTTP webhooks for custom integrations' },
|
|
332
|
-
channelDescDiscord: { zh: '将 Discord 机器人连接到你的社区服务器', en: 'Connect Discord bots to your community servers' },
|
|
333
|
-
channelDescFeishu: { zh: '企业消息与协作平台接入', en: 'Enterprise messaging and collaboration platform' },
|
|
334
|
-
configureMessageChannelParameters: { zh: '配置消息渠道参数', en: 'Configure message channel parameters' },
|
|
335
|
-
channelsGuideTitle: { zh: '查看指南', en: 'View Guide' },
|
|
336
|
-
allowFrom: { zh: '允许来源', en: 'Allow From' },
|
|
337
|
-
token: { zh: 'Token', en: 'Token' },
|
|
338
|
-
botToken: { zh: 'Bot Token', en: 'Bot Token' },
|
|
339
|
-
appToken: { zh: 'App Token', en: 'App Token' },
|
|
340
|
-
appId: { zh: 'App ID', en: 'App ID' },
|
|
341
|
-
corpId: { zh: '企业 ID', en: 'Corp ID' },
|
|
342
|
-
agentId: { zh: '应用 Agent ID', en: 'Agent ID' },
|
|
343
|
-
appSecret: { zh: 'App Secret', en: 'App Secret' },
|
|
344
|
-
markdownSupport: { zh: 'Markdown 支持', en: 'Markdown Support' },
|
|
345
|
-
clientId: { zh: 'Client ID', en: 'Client ID' },
|
|
346
|
-
clientSecret: { zh: 'Client Secret', en: 'Client Secret' },
|
|
347
|
-
encryptKey: { zh: '加密密钥', en: 'Encrypt Key' },
|
|
348
|
-
verificationToken: { zh: '验证令牌', en: 'Verification Token' },
|
|
349
|
-
bridgeUrl: { zh: '桥接 URL', en: 'Bridge URL' },
|
|
350
|
-
gatewayUrl: { zh: '网关 URL', en: 'Gateway URL' },
|
|
351
|
-
proxy: { zh: '代理', en: 'Proxy' },
|
|
352
|
-
intents: { zh: 'Intents', en: 'Intents' },
|
|
353
|
-
mode: { zh: '模式', en: 'Mode' },
|
|
354
|
-
webhookPath: { zh: 'Webhook 路径', en: 'Webhook Path' },
|
|
355
|
-
callbackPort: { zh: '回调端口', en: 'Callback Port' },
|
|
356
|
-
callbackPath: { zh: '回调路径', en: 'Callback Path' },
|
|
357
|
-
groupPolicy: { zh: '群组策略', en: 'Group Policy' },
|
|
316
|
+
...CHANNEL_LABELS,
|
|
358
317
|
consentGranted: { zh: '同意条款', en: 'Consent Granted' },
|
|
359
318
|
imapHost: { zh: 'IMAP 服务器', en: 'IMAP Host' },
|
|
360
319
|
imapPort: { zh: 'IMAP 端口', en: 'IMAP Port' },
|
package/src/lib/logos.ts
CHANGED
|
@@ -4,11 +4,6 @@ import { RemoteSessionMultiplexTransport } from './remote.transport';
|
|
|
4
4
|
import type { AppTransport, RemoteRuntimeInfo, RequestInput, StreamInput, StreamSession } from './transport.types';
|
|
5
5
|
|
|
6
6
|
const REMOTE_RUNTIME_PATH = '/_remote/runtime';
|
|
7
|
-
const DEFAULT_REMOTE_RUNTIME: RemoteRuntimeInfo = {
|
|
8
|
-
mode: 'remote',
|
|
9
|
-
protocolVersion: 1,
|
|
10
|
-
wsPath: '/_remote/ws'
|
|
11
|
-
};
|
|
12
7
|
|
|
13
8
|
async function resolveRuntime(apiBase: string): Promise<AppTransport> {
|
|
14
9
|
const runtimeUrl = `${apiBase.replace(/\/$/, '')}${REMOTE_RUNTIME_PATH}`;
|
|
@@ -27,28 +22,17 @@ async function resolveRuntime(apiBase: string): Promise<AppTransport> {
|
|
|
27
22
|
return new LocalAppTransport({ apiBase });
|
|
28
23
|
}
|
|
29
24
|
|
|
30
|
-
const
|
|
31
|
-
if (!contentType.includes('application/json')) {
|
|
32
|
-
return response.status >= 400
|
|
33
|
-
? new RemoteSessionMultiplexTransport(DEFAULT_REMOTE_RUNTIME, apiBase)
|
|
34
|
-
: new LocalAppTransport({ apiBase });
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
let payload: { ok?: boolean; data?: RemoteRuntimeInfo } | null = null;
|
|
38
|
-
try {
|
|
39
|
-
payload = await response.json() as { ok?: boolean; data?: RemoteRuntimeInfo };
|
|
40
|
-
} catch {
|
|
41
|
-
return response.status >= 400
|
|
42
|
-
? new RemoteSessionMultiplexTransport(DEFAULT_REMOTE_RUNTIME, apiBase)
|
|
43
|
-
: new LocalAppTransport({ apiBase });
|
|
44
|
-
}
|
|
45
|
-
|
|
25
|
+
const payload = await response.json() as { ok?: boolean; data?: RemoteRuntimeInfo };
|
|
46
26
|
if (response.ok && payload.ok && payload.data?.mode === 'remote') {
|
|
47
27
|
return new RemoteSessionMultiplexTransport(payload.data, apiBase);
|
|
48
28
|
}
|
|
49
29
|
|
|
50
30
|
if (response.status >= 400) {
|
|
51
|
-
return new RemoteSessionMultiplexTransport(
|
|
31
|
+
return new RemoteSessionMultiplexTransport({
|
|
32
|
+
mode: 'remote',
|
|
33
|
+
protocolVersion: 1,
|
|
34
|
+
wsPath: '/_remote/ws'
|
|
35
|
+
}, apiBase);
|
|
52
36
|
}
|
|
53
37
|
|
|
54
38
|
return new LocalAppTransport({ apiBase });
|
|
@@ -101,6 +101,7 @@ class LocalRealtimeGateway {
|
|
|
101
101
|
|
|
102
102
|
export class LocalAppTransport implements AppTransport {
|
|
103
103
|
private readonly realtimeGateway: LocalRealtimeGateway;
|
|
104
|
+
private readonly apiBase: string;
|
|
104
105
|
|
|
105
106
|
constructor(
|
|
106
107
|
private readonly options: {
|
|
@@ -108,8 +109,8 @@ export class LocalAppTransport implements AppTransport {
|
|
|
108
109
|
wsPath?: string;
|
|
109
110
|
} = {}
|
|
110
111
|
) {
|
|
111
|
-
|
|
112
|
-
this.realtimeGateway = new LocalRealtimeGateway(resolveTransportWebSocketUrl(apiBase, options.wsPath ?? '/ws'));
|
|
112
|
+
this.apiBase = options.apiBase ?? API_BASE;
|
|
113
|
+
this.realtimeGateway = new LocalRealtimeGateway(resolveTransportWebSocketUrl(this.apiBase, options.wsPath ?? '/ws'));
|
|
113
114
|
}
|
|
114
115
|
|
|
115
116
|
async request<T>(input: RequestInput): Promise<T> {
|
|
@@ -135,7 +136,7 @@ export class LocalAppTransport implements AppTransport {
|
|
|
135
136
|
}
|
|
136
137
|
|
|
137
138
|
const finished = (async () => {
|
|
138
|
-
const response = await fetch(`${
|
|
139
|
+
const response = await fetch(`${this.apiBase}${input.path}`, {
|
|
139
140
|
method: input.method,
|
|
140
141
|
credentials: 'include',
|
|
141
142
|
headers: {
|
|
@@ -14,7 +14,7 @@ type RemoteBrowserFrame =
|
|
|
14
14
|
| { type: 'response'; id: string; status: number; body?: unknown }
|
|
15
15
|
| { type: 'request.error'; id: string; message: string; code?: string }
|
|
16
16
|
| { type: 'stream.event'; streamId: string; event: string; payload?: unknown }
|
|
17
|
-
| { type: 'stream.end'; streamId: string
|
|
17
|
+
| { type: 'stream.end'; streamId: string }
|
|
18
18
|
| { type: 'stream.error'; streamId: string; message: string; code?: string }
|
|
19
19
|
| { type: 'event'; event: AppEvent }
|
|
20
20
|
| { type: 'connection.error'; message: string; code?: string };
|
|
@@ -31,6 +31,7 @@ type PendingRequest = {
|
|
|
31
31
|
|
|
32
32
|
type PendingStream = {
|
|
33
33
|
onEvent: StreamInput['onEvent'];
|
|
34
|
+
finalResult: unknown;
|
|
34
35
|
resolve: (value: unknown) => void;
|
|
35
36
|
reject: (error: Error) => void;
|
|
36
37
|
};
|
|
@@ -131,6 +132,7 @@ export class RemoteSessionMultiplexTransport implements AppTransport {
|
|
|
131
132
|
|
|
132
133
|
this.pendingStreams.set(streamId, {
|
|
133
134
|
onEvent: input.onEvent,
|
|
135
|
+
finalResult: undefined,
|
|
134
136
|
resolve: (value) => {
|
|
135
137
|
if (settled) {
|
|
136
138
|
return;
|
|
@@ -351,6 +353,9 @@ export class RemoteSessionMultiplexTransport implements AppTransport {
|
|
|
351
353
|
}
|
|
352
354
|
if (frame.type === 'stream.event') {
|
|
353
355
|
try {
|
|
356
|
+
if (frame.event === 'final') {
|
|
357
|
+
pending.finalResult = frame.payload;
|
|
358
|
+
}
|
|
354
359
|
pending.onEvent({ name: frame.event, payload: frame.payload });
|
|
355
360
|
} catch (error) {
|
|
356
361
|
this.pendingStreams.delete(frame.streamId);
|
|
@@ -360,7 +365,7 @@ export class RemoteSessionMultiplexTransport implements AppTransport {
|
|
|
360
365
|
}
|
|
361
366
|
this.pendingStreams.delete(frame.streamId);
|
|
362
367
|
if (frame.type === 'stream.end') {
|
|
363
|
-
pending.resolve(
|
|
368
|
+
pending.resolve(pending.finalResult);
|
|
364
369
|
return;
|
|
365
370
|
}
|
|
366
371
|
pending.reject(new Error(frame.message));
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { readSseStreamResult } from './sse-stream';
|
|
3
|
+
|
|
4
|
+
function createSseResponse(frames: string[]): Response {
|
|
5
|
+
const payload = new TextEncoder().encode(frames.join(''));
|
|
6
|
+
const stream = new ReadableStream<Uint8Array>({
|
|
7
|
+
start(controller) {
|
|
8
|
+
controller.enqueue(payload);
|
|
9
|
+
controller.close();
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
return new Response(stream, {
|
|
13
|
+
status: 200,
|
|
14
|
+
headers: {
|
|
15
|
+
'content-type': 'text/event-stream; charset=utf-8'
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function encodeFrame(event: string, payload: unknown): string {
|
|
21
|
+
return `event: ${event}\ndata: ${JSON.stringify(payload)}\n\n`;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
describe('readSseStreamResult', () => {
|
|
25
|
+
it('preserves final frames for callers while still resolving with the final payload', async () => {
|
|
26
|
+
const events: Array<{ name: string; payload?: unknown }> = [];
|
|
27
|
+
const response = createSseResponse([
|
|
28
|
+
encodeFrame('ncp-event', { type: 'message.text-delta', payload: { delta: 'hello' } }),
|
|
29
|
+
encodeFrame('final', { sessionId: 's1', reply: 'hello' })
|
|
30
|
+
]);
|
|
31
|
+
|
|
32
|
+
const result = await readSseStreamResult(response, (event) => {
|
|
33
|
+
events.push(event);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
expect(result).toEqual({ sessionId: 's1', reply: 'hello' });
|
|
37
|
+
expect(events.map((event) => event.name)).toEqual(['ncp-event', 'final']);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('allows passthrough SSE streams to end without a final frame', async () => {
|
|
41
|
+
const events: Array<{ name: string; payload?: unknown }> = [];
|
|
42
|
+
const response = createSseResponse([
|
|
43
|
+
encodeFrame('ncp-event', { type: 'message.text-delta', payload: { delta: 'hello' } }),
|
|
44
|
+
encodeFrame('ncp-event', { type: 'run.finished', payload: { sessionId: 's1' } })
|
|
45
|
+
]);
|
|
46
|
+
|
|
47
|
+
const result = await readSseStreamResult(response, (event) => {
|
|
48
|
+
events.push(event);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
expect(result).toBeUndefined();
|
|
52
|
+
expect(events.map((event) => event.name)).toEqual(['ncp-event', 'ncp-event']);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { StreamEvent } from './transport.types';
|
|
2
2
|
|
|
3
|
-
type
|
|
3
|
+
type FinalResultSink = (value: unknown) => void;
|
|
4
4
|
|
|
5
5
|
function parseSseFrame(frame: string): StreamEvent | null {
|
|
6
6
|
const lines = frame.split('\n');
|
|
@@ -36,16 +36,10 @@ function parseSseFrame(frame: string): StreamEvent | null {
|
|
|
36
36
|
return { name, payload };
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
function readSseErrorMessage(payload: SseErrorPayload, fallback: string): string {
|
|
40
|
-
return typeof payload === 'string'
|
|
41
|
-
? payload
|
|
42
|
-
: payload?.message ?? fallback;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
39
|
function processSseFrame(
|
|
46
40
|
rawFrame: string,
|
|
47
41
|
onEvent: (event: StreamEvent) => void,
|
|
48
|
-
setFinalResult:
|
|
42
|
+
setFinalResult: FinalResultSink
|
|
49
43
|
): void {
|
|
50
44
|
const frame = parseSseFrame(rawFrame);
|
|
51
45
|
if (!frame) {
|
|
@@ -53,10 +47,6 @@ function processSseFrame(
|
|
|
53
47
|
}
|
|
54
48
|
if (frame.name === 'final') {
|
|
55
49
|
setFinalResult(frame.payload);
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
if (frame.name === 'error') {
|
|
59
|
-
throw new Error(readSseErrorMessage(frame.payload as SseErrorPayload, 'chat stream failed'));
|
|
60
50
|
}
|
|
61
51
|
onEvent(frame);
|
|
62
52
|
}
|
|
@@ -64,7 +54,7 @@ function processSseFrame(
|
|
|
64
54
|
function flushBufferedFrames(
|
|
65
55
|
bufferState: { value: string },
|
|
66
56
|
onEvent: (event: StreamEvent) => void,
|
|
67
|
-
setFinalResult:
|
|
57
|
+
setFinalResult: FinalResultSink
|
|
68
58
|
): void {
|
|
69
59
|
let boundary = bufferState.value.indexOf('\n\n');
|
|
70
60
|
while (boundary !== -1) {
|
|
@@ -86,7 +76,6 @@ export async function readSseStreamResult<TFinal>(
|
|
|
86
76
|
const decoder = new TextDecoder();
|
|
87
77
|
const bufferState = { value: '' };
|
|
88
78
|
let finalResult: unknown = undefined;
|
|
89
|
-
|
|
90
79
|
try {
|
|
91
80
|
while (true) {
|
|
92
81
|
const { value, done } = await reader.read();
|
|
@@ -107,8 +96,5 @@ export async function readSseStreamResult<TFinal>(
|
|
|
107
96
|
reader.releaseLock();
|
|
108
97
|
}
|
|
109
98
|
|
|
110
|
-
if (finalResult === undefined) {
|
|
111
|
-
throw new Error('stream ended without final event');
|
|
112
|
-
}
|
|
113
99
|
return finalResult as TFinal;
|
|
114
100
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as v,j as a,X as Z,a3 as ee,e as T,K as ae,aq as te,b1 as se,b2 as ne,b3 as le,a0 as re,G as oe,ai as ce,H as ie}from"./vendor-TJ2hy_Lv.js";import{t as e,c as I,Z as me,u as q,a as $,b as H,$ as pe,a0 as de,I as D,S as be,e as ue,f as xe,g as ye,h as ge,B as E}from"./index-CmGwUgcl.js";import{L as he}from"./label-BOvIOmQx.js";import{S as fe}from"./switch-CvNG9775.js";import{S as K}from"./status-dot-Behu7kDZ.js";import{L as J}from"./LogoBadge-t1JzzCtI.js";import{h as _}from"./config-hints-CApS3K_7.js";import{c as we,b as ve,a as je,C as ke}from"./config-layout-BHnOoweL.js";import{T as Se}from"./tabs-custom-CUdBQO_7.js";import{P as Ce,a as Ne}from"./page-layout-PG3cwSpz.js";function Pe({value:t,onChange:m,className:i,placeholder:r=""}){const[o,u]=v.useState(""),d=x=>{x.key==="Enter"&&o.trim()?(x.preventDefault(),m([...t,o.trim()]),u("")):x.key==="Backspace"&&!o&&t.length>0&&m(t.slice(0,-1))},g=x=>{m(t.filter((j,h)=>h!==x))};return a.jsxs("div",{className:I("flex flex-wrap gap-2 p-2 border rounded-md min-h-[42px]",i),children:[t.map((x,j)=>a.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-1 bg-primary text-primary-foreground rounded text-sm",children:[x,a.jsx("button",{type:"button",onClick:()=>g(j),className:"hover:text-red-300 transition-colors",children:a.jsx(Z,{className:"h-3 w-3"})})]},j)),a.jsx("input",{type:"text",value:o,onChange:x=>u(x.target.value),onKeyDown:d,className:"flex-1 outline-none min-w-[100px] bg-transparent text-sm",placeholder:r||e("enterTag")})]})}function z(t){var r,o;const m=me();return((r=t.tutorialUrls)==null?void 0:r[m])||((o=t.tutorialUrls)==null?void 0:o.default)||t.tutorialUrl}const Ie={telegram:"telegram.svg",slack:"slack.svg",discord:"discord.svg",whatsapp:"whatsapp.svg",qq:"qq.svg",feishu:"feishu.svg",dingtalk:"dingtalk.svg",wecom:"wecom.svg",mochat:"mochat.svg",email:"email.svg"};function Fe(t,m){const i=m.toLowerCase(),r=t[i];return r?`/logos/${r}`:null}function Y(t){return Fe(Ie,t)}const B=[{value:"pairing",label:"pairing"},{value:"allowlist",label:"allowlist"},{value:"open",label:"open"},{value:"disabled",label:"disabled"}],G=[{value:"open",label:"open"},{value:"allowlist",label:"allowlist"},{value:"disabled",label:"disabled"}],Te=[{value:"off",label:"off"},{value:"partial",label:"partial"},{value:"block",label:"block"},{value:"progress",label:"progress"}],De=t=>t.includes("token")||t.includes("secret")||t.includes("password")?a.jsx(ae,{className:"h-3.5 w-3.5 text-gray-500"}):t.includes("url")||t.includes("host")?a.jsx(te,{className:"h-3.5 w-3.5 text-gray-500"}):t.includes("email")||t.includes("mail")?a.jsx(se,{className:"h-3.5 w-3.5 text-gray-500"}):t.includes("id")||t.includes("from")?a.jsx(ne,{className:"h-3.5 w-3.5 text-gray-500"}):t==="enabled"||t==="consentGranted"?a.jsx(le,{className:"h-3.5 w-3.5 text-gray-500"}):a.jsx(re,{className:"h-3.5 w-3.5 text-gray-500"});function R(){return{telegram:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"token",type:"password",label:e("botToken")},{name:"allowFrom",type:"tags",label:e("allowFrom")},{name:"proxy",type:"text",label:e("proxy")},{name:"accountId",type:"text",label:e("accountId")},{name:"dmPolicy",type:"select",label:e("dmPolicy"),options:B},{name:"groupPolicy",type:"select",label:e("groupPolicy"),options:G},{name:"groupAllowFrom",type:"tags",label:e("groupAllowFrom")},{name:"requireMention",type:"boolean",label:e("requireMention")},{name:"mentionPatterns",type:"tags",label:e("mentionPatterns")},{name:"groups",type:"json",label:e("groupRulesJson")}],discord:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"token",type:"password",label:e("botToken")},{name:"allowBots",type:"boolean",label:e("allowBotMessages")},{name:"allowFrom",type:"tags",label:e("allowFrom")},{name:"gatewayUrl",type:"text",label:e("gatewayUrl")},{name:"intents",type:"number",label:e("intents")},{name:"proxy",type:"text",label:e("proxy")},{name:"mediaMaxMb",type:"number",label:e("attachmentMaxSizeMb")},{name:"streaming",type:"select",label:e("streamingMode"),options:Te},{name:"draftChunk",type:"json",label:e("draftChunkingJson")},{name:"textChunkLimit",type:"number",label:e("textChunkLimit")},{name:"accountId",type:"text",label:e("accountId")},{name:"dmPolicy",type:"select",label:e("dmPolicy"),options:B},{name:"groupPolicy",type:"select",label:e("groupPolicy"),options:G},{name:"groupAllowFrom",type:"tags",label:e("groupAllowFrom")},{name:"requireMention",type:"boolean",label:e("requireMention")},{name:"mentionPatterns",type:"tags",label:e("mentionPatterns")},{name:"groups",type:"json",label:e("groupRulesJson")}],whatsapp:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"bridgeUrl",type:"text",label:e("bridgeUrl")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],feishu:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"appId",type:"text",label:e("appId")},{name:"appSecret",type:"password",label:e("appSecret")},{name:"encryptKey",type:"password",label:e("encryptKey")},{name:"verificationToken",type:"password",label:e("verificationToken")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],dingtalk:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"clientId",type:"text",label:e("clientId")},{name:"clientSecret",type:"password",label:e("clientSecret")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],wecom:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"corpId",type:"text",label:e("corpId")},{name:"agentId",type:"text",label:e("agentId")},{name:"secret",type:"password",label:e("secret")},{name:"token",type:"password",label:e("token")},{name:"callbackPort",type:"number",label:e("callbackPort")},{name:"callbackPath",type:"text",label:e("callbackPath")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],slack:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"mode",type:"text",label:e("mode")},{name:"webhookPath",type:"text",label:e("webhookPath")},{name:"allowBots",type:"boolean",label:e("allowBotMessages")},{name:"botToken",type:"password",label:e("botToken")},{name:"appToken",type:"password",label:e("appToken")}],email:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"consentGranted",type:"boolean",label:e("consentGranted")},{name:"imapHost",type:"text",label:e("imapHost")},{name:"imapPort",type:"number",label:e("imapPort")},{name:"imapUsername",type:"text",label:e("imapUsername")},{name:"imapPassword",type:"password",label:e("imapPassword")},{name:"fromAddress",type:"email",label:e("fromAddress")}],mochat:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"baseUrl",type:"text",label:e("baseUrl")},{name:"clawToken",type:"password",label:e("clawToken")},{name:"agentUserId",type:"text",label:e("agentUserId")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],qq:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"appId",type:"text",label:e("appId")},{name:"secret",type:"password",label:e("appSecret")},{name:"markdownSupport",type:"boolean",label:e("markdownSupport")},{name:"allowFrom",type:"tags",label:e("allowFrom")}]}}function A(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function V(t,m){const i={...t};for(const[r,o]of Object.entries(m)){const u=i[r];if(A(u)&&A(o)){i[r]=V(u,o);continue}i[r]=o}return i}function Ae(t,m){const i=t.split("."),r={};let o=r;for(let u=0;u<i.length-1;u+=1){const d=i[u];o[d]={},o=o[d]}return o[i[i.length-1]]=m,r}function Le({channelName:t}){var O,U;const{data:m}=q(),{data:i}=$(),{data:r}=H(),o=pe(),u=de(),[d,g]=v.useState({}),[x,j]=v.useState({}),[h,f]=v.useState(null),k=t?m==null?void 0:m.channels[t]:null,w=t?R()[t]??[]:[],c=r==null?void 0:r.uiHints,p=t?`channels.${t}`:null,S=((O=r==null?void 0:r.actions)==null?void 0:O.filter(s=>s.scope===p))??[],C=t&&(((U=_(`channels.${t}`,c))==null?void 0:U.label)??t),P=i==null?void 0:i.channels.find(s=>s.name===t),F=P?z(P):void 0;v.useEffect(()=>{if(k){g({...k});const s={};(t?R()[t]??[]:[]).filter(l=>l.type==="json").forEach(l=>{const y=k[l.name];s[l.name]=JSON.stringify(y??{},null,2)}),j(s)}else g({}),j({})},[k,t]);const N=(s,n)=>{g(l=>({...l,[s]:n}))},L=s=>{if(s.preventDefault(),!t)return;const n={...d};for(const l of w){if(l.type!=="password")continue;const y=n[l.name];(typeof y!="string"||y.length===0)&&delete n[l.name]}for(const l of w){if(l.type!=="json")continue;const y=x[l.name]??"";try{n[l.name]=y.trim()?JSON.parse(y):{}}catch{T.error(`${e("invalidJson")}: ${l.name}`);return}}o.mutate({channel:t,data:n})},Q=s=>{if(!s||!t)return;const n=s.channels;if(!A(n))return;const l=n[t];A(l)&&g(y=>V(y,l))},W=async s=>{if(!(!t||!p)){f(s.id);try{let n={...d};s.saveBeforeRun&&(n={...n,...s.savePatch??{}},g(n),await o.mutateAsync({channel:t,data:n}));const l=await u.mutateAsync({actionId:s.id,data:{scope:p,draftConfig:Ae(p,n)}});Q(l.patch),l.ok?T.success(l.message||e("success")):T.error(l.message||e("error"))}catch(n){const l=n instanceof Error?n.message:String(n);T.error(`${e("error")}: ${l}`)}finally{f(null)}}};if(!t||!P||!k)return a.jsx("div",{className:we,children:a.jsxs("div",{children:[a.jsx("h3",{className:"text-base font-semibold text-gray-900",children:e("channelsSelectTitle")}),a.jsx("p",{className:"mt-2 text-sm text-gray-500",children:e("channelsSelectDescription")})]})});const M=!!k.enabled;return a.jsxs("div",{className:ve,children:[a.jsx("div",{className:"border-b border-gray-100 px-6 py-5",children:a.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[a.jsxs("div",{className:"min-w-0",children:[a.jsxs("div",{className:"flex items-center gap-3",children:[a.jsx(J,{name:t,src:Y(t),className:I("h-9 w-9 rounded-lg border",M?"border-primary/30 bg-white":"border-gray-200/70 bg-white"),imgClassName:"h-5 w-5 object-contain",fallback:a.jsx("span",{className:"text-sm font-semibold uppercase text-gray-500",children:t[0]})}),a.jsx("h3",{className:"truncate text-lg font-semibold text-gray-900 capitalize",children:C})]}),a.jsx("p",{className:"mt-2 text-sm text-gray-500",children:e("channelsFormDescription")}),F&&a.jsxs("a",{href:F,className:"mt-2 inline-flex items-center gap-1.5 text-xs text-primary transition-colors hover:text-primary-hover",children:[a.jsx(ee,{className:"h-3.5 w-3.5"}),e("channelsGuideTitle")]})]}),a.jsx(K,{status:M?"active":"inactive",label:M?e("statusActive"):e("statusInactive")})]})}),a.jsxs("form",{onSubmit:L,className:"flex min-h-0 flex-1 flex-col",children:[a.jsx("div",{className:"min-h-0 flex-1 space-y-6 overflow-y-auto overscroll-contain px-6 py-5",children:w.map(s=>{const n=t?_(`channels.${t}.${s.name}`,c):void 0,l=(n==null?void 0:n.label)??s.label,y=n==null?void 0:n.placeholder;return a.jsxs("div",{className:"space-y-2.5",children:[a.jsxs(he,{htmlFor:s.name,className:"flex items-center gap-2 text-sm font-medium text-gray-900",children:[De(s.name),l]}),s.type==="boolean"&&a.jsxs("div",{className:"flex items-center justify-between rounded-xl bg-gray-50 p-3",children:[a.jsx("span",{className:"text-sm text-gray-500",children:d[s.name]?e("enabled"):e("disabled")}),a.jsx(fe,{id:s.name,checked:d[s.name]||!1,onCheckedChange:b=>N(s.name,b),className:"data-[state=checked]:bg-emerald-500"})]}),(s.type==="text"||s.type==="email")&&a.jsx(D,{id:s.name,type:s.type,value:d[s.name]||"",onChange:b=>N(s.name,b.target.value),placeholder:y,className:"rounded-xl"}),s.type==="password"&&a.jsx(D,{id:s.name,type:"password",value:d[s.name]||"",onChange:b=>N(s.name,b.target.value),placeholder:y??e("leaveBlankToKeepUnchanged"),className:"rounded-xl"}),s.type==="number"&&a.jsx(D,{id:s.name,type:"number",value:d[s.name]||0,onChange:b=>N(s.name,parseInt(b.target.value,10)||0),placeholder:y,className:"rounded-xl"}),s.type==="tags"&&a.jsx(Pe,{value:d[s.name]||[],onChange:b=>N(s.name,b)}),s.type==="select"&&a.jsxs(be,{value:d[s.name]||"",onValueChange:b=>N(s.name,b),children:[a.jsx(ue,{className:"rounded-xl",children:a.jsx(xe,{})}),a.jsx(ye,{children:(s.options??[]).map(b=>a.jsx(ge,{value:b.value,children:b.label},b.value))})]}),s.type==="json"&&a.jsx("textarea",{id:s.name,value:x[s.name]??"{}",onChange:b=>j(X=>({...X,[s.name]:b.target.value})),className:"min-h-[120px] w-full resize-none rounded-lg border border-gray-200 bg-white px-3 py-2 text-xs font-mono"})]},s.name)})}),a.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 border-t border-gray-100 px-6 py-4",children:[a.jsx("div",{className:"flex flex-wrap items-center gap-2",children:S.filter(s=>s.trigger==="manual").map(s=>a.jsx(E,{type:"button",onClick:()=>W(s),disabled:o.isPending||!!h,variant:"secondary",children:h===s.id?e("connecting"):s.title},s.id))}),a.jsx(E,{type:"submit",disabled:o.isPending||!!h,children:o.isPending?e("saving"):e("save")})]})]})]})}const Me={telegram:"channelDescTelegram",slack:"channelDescSlack",email:"channelDescEmail",webhook:"channelDescWebhook",discord:"channelDescDiscord",feishu:"channelDescFeishu"};function Ke(){const{data:t}=q(),{data:m}=$(),{data:i}=H(),[r,o]=v.useState("enabled"),[u,d]=v.useState(),[g,x]=v.useState(""),j=i==null?void 0:i.uiHints,h=m==null?void 0:m.channels,f=t==null?void 0:t.channels,k=[{id:"enabled",label:e("channelsTabEnabled"),count:(h??[]).filter(c=>{var p;return(p=f==null?void 0:f[c.name])==null?void 0:p.enabled}).length},{id:"all",label:e("channelsTabAll"),count:(h??[]).length}],w=v.useMemo(()=>{const c=g.trim().toLowerCase();return(h??[]).filter(p=>{var C;const S=((C=f==null?void 0:f[p.name])==null?void 0:C.enabled)||!1;return r==="enabled"?S:!0}).filter(p=>c?(p.displayName||p.name).toLowerCase().includes(c)||p.name.toLowerCase().includes(c):!0)},[r,f,h,g]);return v.useEffect(()=>{if(w.length===0){d(void 0);return}w.some(p=>p.name===u)||d(w[0].name)},[w,u]),!t||!m?a.jsx("div",{className:"p-8 text-gray-400",children:e("channelsLoading")}):a.jsxs(Ce,{className:"xl:flex xl:h-full xl:min-h-0 xl:flex-col xl:pb-0",children:[a.jsx(Ne,{title:e("channelsPageTitle"),description:e("channelsPageDescription")}),a.jsxs("div",{className:I(ke,"xl:min-h-0 xl:flex-1"),children:[a.jsxs("section",{className:je,children:[a.jsx("div",{className:"border-b border-gray-100 px-4 pt-4",children:a.jsx(Se,{tabs:k,activeTab:r,onChange:o,className:"mb-0"})}),a.jsx("div",{className:"border-b border-gray-100 px-4 py-3",children:a.jsxs("div",{className:"relative",children:[a.jsx(oe,{className:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400"}),a.jsx(D,{value:g,onChange:c=>x(c.target.value),placeholder:e("channelsFilterPlaceholder"),className:"h-10 rounded-xl pl-9"})]})}),a.jsxs("div",{className:"min-h-0 flex-1 space-y-2 overflow-y-auto overscroll-contain p-3",children:[w.map(c=>{const p=t.channels[c.name],S=(p==null?void 0:p.enabled)||!1,C=_(`channels.${c.name}`,j),P=z(c),F=(C==null?void 0:C.help)||e(Me[c.name]||"channelDescriptionDefault"),N=u===c.name;return a.jsx("button",{type:"button",onClick:()=>d(c.name),className:I("w-full rounded-xl border p-2.5 text-left transition-all",N?"border-primary/30 bg-primary-50/40 shadow-sm":"border-gray-200/70 bg-white hover:border-gray-300 hover:bg-gray-50/70"),children:a.jsxs("div",{className:"flex items-start justify-between gap-3",children:[a.jsxs("div",{className:"flex min-w-0 items-center gap-3",children:[a.jsx(J,{name:c.name,src:Y(c.name),className:I("h-10 w-10 rounded-lg border",S?"border-primary/30 bg-white":"border-gray-200/70 bg-white"),imgClassName:"h-5 w-5 object-contain",fallback:a.jsx("span",{className:"text-sm font-semibold uppercase text-gray-500",children:c.name[0]})}),a.jsxs("div",{className:"min-w-0",children:[a.jsx("p",{className:"truncate text-sm font-semibold text-gray-900",children:c.displayName||c.name}),a.jsx("p",{className:"line-clamp-1 text-[11px] text-gray-500",children:F})]})]}),a.jsxs("div",{className:"flex items-center gap-2",children:[P&&a.jsx("a",{href:P,onClick:L=>L.stopPropagation(),className:"inline-flex h-7 w-7 items-center justify-center rounded-md text-gray-300 transition-colors hover:bg-gray-100/70 hover:text-gray-500",title:e("channelsGuideTitle"),children:a.jsx(ce,{className:"h-3.5 w-3.5"})}),a.jsx(K,{status:S?"active":"inactive",label:S?e("statusActive"):e("statusInactive"),className:"min-w-[56px] justify-center"})]})]})},c.name)}),w.length===0&&a.jsxs("div",{className:"flex h-full min-h-[220px] flex-col items-center justify-center rounded-xl border border-dashed border-gray-200 bg-gray-50/70 py-10 text-center",children:[a.jsx("div",{className:"mb-3 flex h-10 w-10 items-center justify-center rounded-lg bg-white",children:a.jsx(ie,{className:"h-5 w-5 text-gray-300"})}),a.jsx("p",{className:"text-sm font-medium text-gray-700",children:e("channelsNoMatch")})]})]})]}),a.jsx(Le,{channelName:u})]})]})}export{Ke as ChannelsList};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as n,j as e,ac as W,v as z,F as q,a3 as G,ad as K,ae as Y}from"./vendor-TJ2hy_Lv.js";import{I as A,c as L,u as $,a as J,b as Q,d as X,t as m,C as U,S as Z,e as H,f as ee,g as se,h as te,D as ae,B as re}from"./index-CmGwUgcl.js";import{L as R}from"./label-BOvIOmQx.js";import{S as u}from"./skeleton-CLSc5FYO.js";import{h as _}from"./config-hints-CApS3K_7.js";import{b as le,f as oe,t as F,c as ne}from"./provider-models-BOeNnjk9.js";import{P as ce,a as ie}from"./page-layout-PG3cwSpz.js";function de(c){const r=new Set;for(const p of c){const x=p.trim();x.length>0&&r.add(x)}return[...r]}function me({id:c,value:r,onChange:p,options:x,disabled:i=!1,placeholder:T,className:k,inputClassName:v,emptyText:j,createText:b,maxItems:N=Number.POSITIVE_INFINITY,onEnter:M}){const[o,l]=n.useState(!1);n.useEffect(()=>{i&&o&&l(!1)},[i,o]);const h=n.useMemo(()=>de(x),[x]),d=r.trim().toLowerCase(),a=n.useMemo(()=>{const s=h.map((f,w)=>({option:f,index:w}));d.length>0&&s.sort((f,w)=>{const S=f.option.toLowerCase(),P=w.option.toLowerCase(),D=S===d?0:S.startsWith(d)?1:S.includes(d)?2:3,I=P===d?0:P.startsWith(d)?1:P.includes(d)?2:3;return D!==I?D-I:f.index-w.index});const g=s.map(f=>f.option);return Number.isFinite(N)?g.slice(0,Math.max(1,N)):g},[h,d,N]),C=r.trim().length>0&&h.some(s=>s===r.trim());return e.jsxs("div",{className:L("relative",k),onBlur:()=>{setTimeout(()=>l(!1),120)},children:[e.jsx(A,{id:c,value:r,disabled:i,onFocus:()=>{i||l(!0)},onChange:s=>{p(s.target.value),!o&&!i&&l(!0)},onKeyDown:s=>{s.key==="Enter"&&(M&&(s.preventDefault(),M()),l(!1))},placeholder:T,className:L("pr-10",v)}),e.jsx("button",{type:"button",onMouseDown:s=>s.preventDefault(),onClick:()=>l(s=>!s),disabled:i,className:L("absolute inset-y-0 right-0 inline-flex w-10 items-center justify-center",i?"cursor-not-allowed text-gray-300":"text-gray-400 hover:text-gray-600"),"aria-label":"toggle model options",children:e.jsx(W,{className:"h-4 w-4"})}),o&&!i&&e.jsx("div",{className:"absolute z-20 mt-1 w-full overflow-hidden rounded-xl border border-gray-200 bg-white shadow-lg",children:e.jsxs("div",{className:"max-h-60 overflow-y-auto py-1",children:[!C&&r.trim().length>0&&e.jsxs("button",{type:"button",onMouseDown:s=>s.preventDefault(),onClick:()=>{p(r.trim()),l(!1)},className:"flex w-full items-center gap-2 px-3 py-2 text-left text-sm hover:bg-gray-50",children:[e.jsx(z,{className:"h-4 w-4 text-transparent"}),e.jsx("span",{className:"truncate text-gray-700",children:b?b.replace("{value}",r.trim()):r.trim()})]}),a.map(s=>e.jsxs("button",{type:"button",onMouseDown:g=>g.preventDefault(),onClick:()=>{p(s),l(!1)},className:"flex w-full items-center gap-2 px-3 py-2 text-left text-sm hover:bg-gray-50",children:[e.jsx(z,{className:L("h-4 w-4",s===r.trim()?"text-primary":"text-transparent")}),e.jsx("span",{className:"truncate text-gray-700",children:s})]},s)),a.length===0&&r.trim().length===0&&e.jsx("div",{className:"px-3 py-2 text-sm text-gray-500",children:j??"No models available"})]})})]})}function Ne(){const{data:c,isLoading:r}=$(),{data:p}=J(),{data:x}=Q(),i=X(),[T,k]=n.useState(""),[v,j]=n.useState(""),[b,N]=n.useState(""),M=x==null?void 0:x.uiHints,o=_("agents.defaults.model",M),l=_("agents.defaults.workspace",M),h=n.useMemo(()=>le({meta:p,config:c,onlyConfigured:!0}),[c,p]),d=n.useMemo(()=>new Map(h.map(t=>[t.name,t])),[h]),a=d.get(T),C=(a==null?void 0:a.name)??"",s=n.useMemo(()=>(a==null?void 0:a.aliases)??[],[a]),g=n.useMemo(()=>(a==null?void 0:a.models)??[],[a]);n.useEffect(()=>{var E,B;if(!((E=c==null?void 0:c.agents)!=null&&E.defaults))return;const t=(c.agents.defaults.model||"").trim(),y=oe(t,h)??"",V=((B=d.get(y))==null?void 0:B.aliases)??[];k(y),j(y?F(t,V):""),N(c.agents.defaults.workspace||"")},[c,h,d]);const f=n.useMemo(()=>{const t=new Set;for(const O of g){const y=O.trim();y&&t.add(y)}return[...t]},[g]),w=n.useMemo(()=>{if(!a)return"";const t=F(v,s);return t?ne(a.prefix,t):""},[v,a,s]),S=m("modelIdentifierHelp")||(o==null?void 0:o.help)||"",P=t=>{k(t),j("")},D=t=>{if(!a){j("");return}j(F(t,s))},I=t=>{t.preventDefault(),i.mutate({model:w,workspace:b})};return r?e.jsxs("div",{className:"max-w-2xl space-y-6",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(u,{className:"h-8 w-32"}),e.jsx(u,{className:"h-4 w-48"})]}),e.jsxs(U,{className:"rounded-2xl border-gray-200 p-6",children:[e.jsxs("div",{className:"flex items-center gap-4 mb-6",children:[e.jsx(u,{className:"h-12 w-12 rounded-xl"}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(u,{className:"h-5 w-24"}),e.jsx(u,{className:"h-3 w-32"})]})]}),e.jsx(u,{className:"h-4 w-20 mb-2"}),e.jsx(u,{className:"h-10 w-full rounded-xl"})]}),e.jsxs(U,{className:"rounded-2xl border-gray-200 p-6",children:[e.jsx(u,{className:"h-5 w-24 mb-2"}),e.jsx(u,{className:"h-10 w-full rounded-xl"})]})]}):e.jsxs(ce,{children:[e.jsx(ie,{title:m("modelPageTitle"),description:m("modelPageDescription")}),e.jsxs("form",{onSubmit:I,className:"space-y-8",children:[e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-8",children:[e.jsxs("div",{className:"p-8 rounded-2xl bg-white border border-gray-200 shadow-card",children:[e.jsxs("div",{className:"flex items-center gap-4 mb-8",children:[e.jsx("div",{className:"h-10 w-10 rounded-xl bg-primary flex items-center justify-center text-white",children:e.jsx(q,{className:"h-5 w-5"})}),e.jsx("h3",{className:"text-lg font-bold text-gray-900",children:m("defaultModel")})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(R,{htmlFor:"model",className:"text-xs font-semibold text-gray-500 uppercase tracking-wider",children:(o==null?void 0:o.label)??"Model Name"}),e.jsxs("div",{className:"flex flex-col gap-2 sm:flex-row sm:items-center",children:[e.jsx("div",{className:"sm:w-[38%] sm:min-w-[170px]",children:e.jsxs(Z,{value:C,onValueChange:P,children:[e.jsx(H,{className:"h-10 w-full rounded-xl",children:e.jsx(ee,{placeholder:m("providersSelectPlaceholder")})}),e.jsx(se,{children:h.map(t=>e.jsx(te,{value:t.name,children:t.displayName},t.name))})]})}),e.jsx("span",{className:"hidden h-10 items-center justify-center leading-none text-lg font-semibold text-gray-300 sm:inline-flex",children:"/"}),e.jsx(me,{id:"model",value:v,onChange:D,options:f,disabled:!C,placeholder:(o==null?void 0:o.placeholder)??"gpt-5.1",className:"sm:flex-1",inputClassName:"h-10 rounded-xl",emptyText:m("modelPickerNoOptions"),createText:m("modelPickerUseCustom")},C)]}),e.jsx("p",{className:"text-xs text-gray-400",children:S}),e.jsx("p",{className:"text-xs text-gray-500",children:m("modelInputCustomHint")}),e.jsxs("a",{href:`${ae}/guide/model-selection`,className:"inline-flex items-center gap-1.5 text-xs text-primary hover:text-primary-hover transition-colors",children:[e.jsx(G,{className:"h-3.5 w-3.5"}),m("channelsGuideTitle")]})]})]}),e.jsxs("div",{className:"p-8 rounded-2xl bg-white border border-gray-200 shadow-card",children:[e.jsxs("div",{className:"flex items-center gap-4 mb-8",children:[e.jsx("div",{className:"h-10 w-10 rounded-xl bg-primary flex items-center justify-center text-white",children:e.jsx(K,{className:"h-5 w-5"})}),e.jsx("h3",{className:"text-lg font-bold text-gray-900",children:m("workspace")})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(R,{htmlFor:"workspace",className:"text-xs font-semibold text-gray-500 uppercase tracking-wider",children:(l==null?void 0:l.label)??"Default Path"}),e.jsx(A,{id:"workspace",value:b,onChange:t=>N(t.target.value),placeholder:(l==null?void 0:l.placeholder)??"/path/to/workspace",className:"rounded-xl"})]})]})]}),e.jsx("div",{className:"flex justify-end pt-4",children:e.jsx(re,{type:"submit",disabled:i.isPending,size:"lg",children:i.isPending?e.jsx(Y,{className:"h-5 w-5 animate-spin"}):m("saveChanges")})})]})]})}export{Ne as ModelConfig};
|