Commit f492464b authored by AI-甘富林's avatar AI-甘富林

feat(client): add douyin runtime settings and attachment support

parent c5b18b81
This diff is collapsed.
...@@ -2,8 +2,11 @@ import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises"; ...@@ -2,8 +2,11 @@ import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
import path from "node:path"; import path from "node:path";
import { import {
FIXED_DIGITAL_HUMAN_CONFIG, FIXED_DIGITAL_HUMAN_CONFIG,
FIXED_DOUYIN_RUNTIME_CONFIG,
FIXED_EXPERT_MODEL_ENDPOINTS, FIXED_EXPERT_MODEL_ENDPOINTS,
type AppConfig, type AppConfig,
type DouyinRuntimeConfig,
type DouyinTextModelConfig,
type DigitalHumanModelConfig, type DigitalHumanModelConfig,
type ExpertModelConfig, type ExpertModelConfig,
type ModelEndpointConfig, type ModelEndpointConfig,
...@@ -62,6 +65,15 @@ interface LegacyConfig { ...@@ -62,6 +65,15 @@ interface LegacyConfig {
copywriting?: Partial<ModelEndpointConfig>; copywriting?: Partial<ModelEndpointConfig>;
digitalHuman?: Partial<DigitalHumanModelConfig>; digitalHuman?: Partial<DigitalHumanModelConfig>;
}; };
douyinRuntimeConfig?: {
videoAnalyzer?: Partial<DouyinTextModelConfig>;
replicationBrief?: Partial<DouyinTextModelConfig>;
vectcut?: {
baseUrl?: string;
fileBaseUrl?: string;
apiKeyConfigured?: boolean;
};
};
} }
function normalizeGatewayUrl(raw: string): string { function normalizeGatewayUrl(raw: string): string {
...@@ -173,6 +185,27 @@ function createDefaultExpertModelConfig(): ExpertModelConfig { ...@@ -173,6 +185,27 @@ function createDefaultExpertModelConfig(): ExpertModelConfig {
}; };
} }
function createDefaultDouyinTextModelConfig(kind: "videoAnalyzer" | "replicationBrief"): DouyinTextModelConfig {
const config = FIXED_DOUYIN_RUNTIME_CONFIG[kind];
return {
baseUrl: config.baseUrl,
apiKeyConfigured: false,
modelId: config.modelId
};
}
function createDefaultDouyinRuntimeConfig(): DouyinRuntimeConfig {
return {
videoAnalyzer: createDefaultDouyinTextModelConfig("videoAnalyzer"),
replicationBrief: createDefaultDouyinTextModelConfig("replicationBrief"),
vectcut: {
baseUrl: FIXED_DOUYIN_RUNTIME_CONFIG.vectcut.baseUrl,
fileBaseUrl: FIXED_DOUYIN_RUNTIME_CONFIG.vectcut.fileBaseUrl,
apiKeyConfigured: false
}
};
}
function mergeExpertModelConfig( function mergeExpertModelConfig(
current: ExpertModelConfig, current: ExpertModelConfig,
input?: SaveConfigInput["expertModelConfig"] input?: SaveConfigInput["expertModelConfig"]
...@@ -203,6 +236,47 @@ function mergeExpertModelConfig( ...@@ -203,6 +236,47 @@ function mergeExpertModelConfig(
}; };
} }
function mergeDouyinRuntimeConfig(
current: DouyinRuntimeConfig,
input?: SaveConfigInput["douyinRuntimeConfig"]
): DouyinRuntimeConfig {
return {
videoAnalyzer: {
baseUrl: typeof input?.videoAnalyzer?.baseUrl === "string"
? input.videoAnalyzer.baseUrl.trim()
: current.videoAnalyzer.baseUrl,
apiKeyConfigured: typeof input?.videoAnalyzer?.apiKey === "string"
? Boolean(input.videoAnalyzer.apiKey.trim())
: current.videoAnalyzer.apiKeyConfigured,
modelId: typeof input?.videoAnalyzer?.modelId === "string"
? input.videoAnalyzer.modelId.trim()
: current.videoAnalyzer.modelId
},
replicationBrief: {
baseUrl: typeof input?.replicationBrief?.baseUrl === "string"
? input.replicationBrief.baseUrl.trim()
: current.replicationBrief.baseUrl,
apiKeyConfigured: typeof input?.replicationBrief?.apiKey === "string"
? Boolean(input.replicationBrief.apiKey.trim())
: current.replicationBrief.apiKeyConfigured,
modelId: typeof input?.replicationBrief?.modelId === "string"
? input.replicationBrief.modelId.trim()
: current.replicationBrief.modelId
},
vectcut: {
baseUrl: typeof input?.vectcut?.baseUrl === "string"
? input.vectcut.baseUrl.trim()
: current.vectcut.baseUrl,
fileBaseUrl: typeof input?.vectcut?.fileBaseUrl === "string"
? input.vectcut.fileBaseUrl.trim()
: current.vectcut.fileBaseUrl,
apiKeyConfigured: typeof input?.vectcut?.apiKey === "string"
? Boolean(input.vectcut.apiKey.trim())
: current.vectcut.apiKeyConfigured
}
};
}
export function getRuntimeCloudApiTarget(config: Pick<AppConfig, "runtimeCloudApiBaseUrl">): RuntimeCloudApiTarget { export function getRuntimeCloudApiTarget(config: Pick<AppConfig, "runtimeCloudApiBaseUrl">): RuntimeCloudApiTarget {
return resolveRuntimeCloudApiTarget(config.runtimeCloudApiBaseUrl); return resolveRuntimeCloudApiTarget(config.runtimeCloudApiBaseUrl);
} }
...@@ -235,7 +309,8 @@ export class AppConfigService { ...@@ -235,7 +309,8 @@ export class AppConfigService {
cloudApiBaseUrl: normalizeCloudApiBaseUrl(input.cloudApiBaseUrl), cloudApiBaseUrl: normalizeCloudApiBaseUrl(input.cloudApiBaseUrl),
runtimeCloudApiBaseUrl: migrateDeprecatedRuntimeCloudApiBaseUrl(input.runtimeCloudApiBaseUrl), runtimeCloudApiBaseUrl: migrateDeprecatedRuntimeCloudApiBaseUrl(input.runtimeCloudApiBaseUrl),
runtimeMode: normalizeRuntimeMode(input.runtimeMode), runtimeMode: normalizeRuntimeMode(input.runtimeMode),
expertModelConfig: mergeExpertModelConfig(current.expertModelConfig, input.expertModelConfig) expertModelConfig: mergeExpertModelConfig(current.expertModelConfig, input.expertModelConfig),
douyinRuntimeConfig: mergeDouyinRuntimeConfig(current.douyinRuntimeConfig, input.douyinRuntimeConfig)
}; };
await this.writeConfig(config); await this.writeConfig(config);
...@@ -243,6 +318,12 @@ export class AppConfigService { ...@@ -243,6 +318,12 @@ export class AppConfigService {
}); });
} }
async persist(config: AppConfig): Promise<void> {
return this.runExclusive(async () => {
await this.writeConfig(config);
});
}
getDataPath(...segments: string[]): string { getDataPath(...segments: string[]): string {
return path.join(this.userDataPath, ...segments); return path.join(this.userDataPath, ...segments);
} }
...@@ -265,12 +346,14 @@ export class AppConfigService { ...@@ -265,12 +346,14 @@ export class AppConfigService {
cloudApiBaseUrl: normalizeCloudApiBaseUrl(process.env.QJCLAW_CLOUD_API_BASE_URL ?? ""), cloudApiBaseUrl: normalizeCloudApiBaseUrl(process.env.QJCLAW_CLOUD_API_BASE_URL ?? ""),
runtimeCloudApiBaseUrl: "", runtimeCloudApiBaseUrl: "",
runtimeMode: normalizeRuntimeMode(process.env.QJCLAW_RUNTIME_MODE), runtimeMode: normalizeRuntimeMode(process.env.QJCLAW_RUNTIME_MODE),
expertModelConfig: createDefaultExpertModelConfig() expertModelConfig: createDefaultExpertModelConfig(),
douyinRuntimeConfig: createDefaultDouyinRuntimeConfig()
}; };
} }
private normalizeConfig(config: LegacyConfig): AppConfig { private normalizeConfig(config: LegacyConfig): AppConfig {
const defaultExpertModelConfig = createDefaultExpertModelConfig(); const defaultExpertModelConfig = createDefaultExpertModelConfig();
const defaultDouyinRuntimeConfig = createDefaultDouyinRuntimeConfig();
return { return {
setupMode: normalizeSetupMode(config.setupMode), setupMode: normalizeSetupMode(config.setupMode),
provider: config.provider ?? "openai", provider: config.provider ?? "openai",
...@@ -307,6 +390,31 @@ export class AppConfigService { ...@@ -307,6 +390,31 @@ export class AppConfigService {
qiniuAccessKeyConfigured: Boolean(config.expertModelConfig?.digitalHuman?.qiniuAccessKeyConfigured), qiniuAccessKeyConfigured: Boolean(config.expertModelConfig?.digitalHuman?.qiniuAccessKeyConfigured),
qiniuSecretKeyConfigured: Boolean(config.expertModelConfig?.digitalHuman?.qiniuSecretKeyConfigured) qiniuSecretKeyConfigured: Boolean(config.expertModelConfig?.digitalHuman?.qiniuSecretKeyConfigured)
} }
},
douyinRuntimeConfig: {
videoAnalyzer: {
baseUrl: typeof config.douyinRuntimeConfig?.videoAnalyzer?.baseUrl === "string"
? config.douyinRuntimeConfig.videoAnalyzer.baseUrl
: defaultDouyinRuntimeConfig.videoAnalyzer.baseUrl,
apiKeyConfigured: Boolean(config.douyinRuntimeConfig?.videoAnalyzer?.apiKeyConfigured),
modelId: config.douyinRuntimeConfig?.videoAnalyzer?.modelId ?? defaultDouyinRuntimeConfig.videoAnalyzer.modelId
},
replicationBrief: {
baseUrl: typeof config.douyinRuntimeConfig?.replicationBrief?.baseUrl === "string"
? config.douyinRuntimeConfig.replicationBrief.baseUrl
: defaultDouyinRuntimeConfig.replicationBrief.baseUrl,
apiKeyConfigured: Boolean(config.douyinRuntimeConfig?.replicationBrief?.apiKeyConfigured),
modelId: config.douyinRuntimeConfig?.replicationBrief?.modelId ?? defaultDouyinRuntimeConfig.replicationBrief.modelId
},
vectcut: {
baseUrl: typeof config.douyinRuntimeConfig?.vectcut?.baseUrl === "string"
? config.douyinRuntimeConfig.vectcut.baseUrl
: defaultDouyinRuntimeConfig.vectcut.baseUrl,
fileBaseUrl: typeof config.douyinRuntimeConfig?.vectcut?.fileBaseUrl === "string"
? config.douyinRuntimeConfig.vectcut.fileBaseUrl
: defaultDouyinRuntimeConfig.vectcut.fileBaseUrl,
apiKeyConfigured: Boolean(config.douyinRuntimeConfig?.vectcut?.apiKeyConfigured)
}
} }
}; };
} }
......
...@@ -14,6 +14,9 @@ interface SecretRecord { ...@@ -14,6 +14,9 @@ interface SecretRecord {
digitalHumanVolcSecretKey?: string; digitalHumanVolcSecretKey?: string;
digitalHumanQiniuAccessKey?: string; digitalHumanQiniuAccessKey?: string;
digitalHumanQiniuSecretKey?: string; digitalHumanQiniuSecretKey?: string;
videoAnalyzerApiKey?: string;
replicationBriefApiKey?: string;
vectCutApiKey?: string;
} }
interface SecretAccessor { interface SecretAccessor {
...@@ -32,7 +35,10 @@ type SecretName = ...@@ -32,7 +35,10 @@ type SecretName =
| "digitalHumanVolcAccessKey" | "digitalHumanVolcAccessKey"
| "digitalHumanVolcSecretKey" | "digitalHumanVolcSecretKey"
| "digitalHumanQiniuAccessKey" | "digitalHumanQiniuAccessKey"
| "digitalHumanQiniuSecretKey"; | "digitalHumanQiniuSecretKey"
| "videoAnalyzerApiKey"
| "replicationBriefApiKey"
| "vectCutApiKey";
type KeytarModule = typeof import("keytar"); type KeytarModule = typeof import("keytar");
const KEYTAR_SERVICE = "QianjiangClaw"; const KEYTAR_SERVICE = "QianjiangClaw";
...@@ -48,7 +54,10 @@ const KEYTAR_ACCOUNT_MAP: Record<SecretName, string> = { ...@@ -48,7 +54,10 @@ const KEYTAR_ACCOUNT_MAP: Record<SecretName, string> = {
digitalHumanVolcAccessKey: "digital-human-volc-access-key", digitalHumanVolcAccessKey: "digital-human-volc-access-key",
digitalHumanVolcSecretKey: "digital-human-volc-secret-key", digitalHumanVolcSecretKey: "digital-human-volc-secret-key",
digitalHumanQiniuAccessKey: "digital-human-qiniu-access-key", digitalHumanQiniuAccessKey: "digital-human-qiniu-access-key",
digitalHumanQiniuSecretKey: "digital-human-qiniu-secret-key" digitalHumanQiniuSecretKey: "digital-human-qiniu-secret-key",
videoAnalyzerApiKey: "douyin-video-analyzer-api-key",
replicationBriefApiKey: "douyin-replication-brief-api-key",
vectCutApiKey: "douyin-vectcut-api-key"
}; };
class FileSecretStore implements SecretAccessor { class FileSecretStore implements SecretAccessor {
...@@ -244,6 +253,30 @@ export class SecretManager { ...@@ -244,6 +253,30 @@ export class SecretManager {
return this.store.get("digitalHumanQiniuSecretKey"); return this.store.get("digitalHumanQiniuSecretKey");
} }
async setVideoAnalyzerApiKey(value?: string): Promise<void> {
await this.store.set("videoAnalyzerApiKey", value);
}
async getVideoAnalyzerApiKey(): Promise<string | undefined> {
return this.store.get("videoAnalyzerApiKey");
}
async setReplicationBriefApiKey(value?: string): Promise<void> {
await this.store.set("replicationBriefApiKey", value);
}
async getReplicationBriefApiKey(): Promise<string | undefined> {
return this.store.get("replicationBriefApiKey");
}
async setVectCutApiKey(value?: string): Promise<void> {
await this.store.set("vectCutApiKey", value);
}
async getVectCutApiKey(): Promise<string | undefined> {
return this.store.get("vectCutApiKey");
}
private async tryLoadKeytar(): Promise<KeytarModule | null> { private async tryLoadKeytar(): Promise<KeytarModule | null> {
try { try {
const imported = await import("keytar"); const imported = await import("keytar");
...@@ -265,7 +298,10 @@ export class SecretManager { ...@@ -265,7 +298,10 @@ export class SecretManager {
"digitalHumanVolcAccessKey", "digitalHumanVolcAccessKey",
"digitalHumanVolcSecretKey", "digitalHumanVolcSecretKey",
"digitalHumanQiniuAccessKey", "digitalHumanQiniuAccessKey",
"digitalHumanQiniuSecretKey" "digitalHumanQiniuSecretKey",
"videoAnalyzerApiKey",
"replicationBriefApiKey",
"vectCutApiKey"
] as const) { ] as const) {
const existing = await this.store.get(secretName); const existing = await this.store.get(secretName);
if (existing) { if (existing) {
......
...@@ -85,6 +85,7 @@ const desktopApi: DesktopApi = { ...@@ -85,6 +85,7 @@ const desktopApi: DesktopApi = {
createSessionForProject: (projectId: string, title?: string) => ipcRenderer.invoke(IPC_CHANNELS.chatCreateSessionForProject, projectId, title), createSessionForProject: (projectId: string, title?: string) => ipcRenderer.invoke(IPC_CHANNELS.chatCreateSessionForProject, projectId, title),
closeSession: (sessionId: string) => ipcRenderer.invoke(IPC_CHANNELS.chatCloseSession, sessionId), closeSession: (sessionId: string) => ipcRenderer.invoke(IPC_CHANNELS.chatCloseSession, sessionId),
listMessages: (sessionId: string) => ipcRenderer.invoke(IPC_CHANNELS.chatListMessages, sessionId), listMessages: (sessionId: string) => ipcRenderer.invoke(IPC_CHANNELS.chatListMessages, sessionId),
pickAttachments: () => ipcRenderer.invoke(IPC_CHANNELS.chatPickAttachments),
pickImageAttachment: () => ipcRenderer.invoke(IPC_CHANNELS.chatPickImageAttachment), pickImageAttachment: () => ipcRenderer.invoke(IPC_CHANNELS.chatPickImageAttachment),
sendPrompt: (sessionId: string, prompt: string, skillId?: string, attachments?: ChatAttachment[]) => ipcRenderer.invoke(IPC_CHANNELS.chatSendPrompt, sessionId, prompt, skillId, attachments), sendPrompt: (sessionId: string, prompt: string, skillId?: string, attachments?: ChatAttachment[]) => ipcRenderer.invoke(IPC_CHANNELS.chatSendPrompt, sessionId, prompt, skillId, attachments),
streamPrompt: (sessionId: string, prompt: string, skillId?: string, attachments?: ChatAttachment[]) => ipcRenderer.invoke(IPC_CHANNELS.chatStreamPrompt, sessionId, prompt, skillId, attachments), streamPrompt: (sessionId: string, prompt: string, skillId?: string, attachments?: ChatAttachment[]) => ipcRenderer.invoke(IPC_CHANNELS.chatStreamPrompt, sessionId, prompt, skillId, attachments),
......
This diff is collapsed.
...@@ -3945,40 +3945,12 @@ button.secondary { ...@@ -3945,40 +3945,12 @@ button.secondary {
position: relative; position: relative;
min-height: 0; min-height: 0;
height: 100%; height: 100%;
padding: 8px; padding: 0;
overflow: hidden; overflow: hidden;
border-radius: 30px; border: 0;
border: 1px solid rgba(190, 205, 255, 0.88); border-radius: 0;
background: background: transparent;
radial-gradient(circle at 12% 12%, rgba(94, 203, 255, 0.22), transparent 28%), box-shadow: none;
radial-gradient(circle at 88% 10%, rgba(139, 125, 255, 0.18), transparent 24%),
linear-gradient(145deg, #f7f9ff 0%, #eef4ff 52%, #f3efff 100%);
box-shadow: 0 26px 56px rgba(109, 124, 255, 0.12), inset 0 1px 0 rgba(255, 255, 255, 0.88);
}
.settings-page-shell::before,
.settings-page-shell::after {
content: "";
position: absolute;
border-radius: 999px;
pointer-events: none;
filter: blur(12px);
}
.settings-page-shell::before {
width: 240px;
height: 240px;
top: -88px;
right: 11%;
background: rgba(109, 124, 255, 0.16);
}
.settings-page-shell::after {
width: 220px;
height: 220px;
left: -76px;
bottom: -84px;
background: rgba(94, 203, 255, 0.16);
} }
.settings-page-shell > * { .settings-page-shell > * {
...@@ -4137,7 +4109,7 @@ button.secondary { ...@@ -4137,7 +4109,7 @@ button.secondary {
display: grid; display: grid;
gap: 10px; gap: 10px;
grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-columns: repeat(2, minmax(0, 1fr));
grid-template-rows: minmax(164px, 0.72fr) minmax(0, 1.28fr); grid-template-rows: minmax(164px, 0.43fr) minmax(0, 1.57fr);
grid-template-areas: grid-template-areas:
"connection diagnostics" "connection diagnostics"
"models models"; "models models";
...@@ -4173,7 +4145,7 @@ button.secondary { ...@@ -4173,7 +4145,7 @@ button.secondary {
overflow: hidden; overflow: hidden;
border: 1px solid rgba(157, 180, 255, 0.45); border: 1px solid rgba(157, 180, 255, 0.45);
background: linear-gradient(180deg, rgba(255, 255, 255, 0.72), rgba(255, 255, 255, 0.5)); background: linear-gradient(180deg, rgba(255, 255, 255, 0.72), rgba(255, 255, 255, 0.5));
box-shadow: 0 14px 30px rgba(109, 124, 255, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.9); box-shadow: 0 10px 22px rgba(109, 124, 255, 0.06), inset 0 1px 0 rgba(255, 255, 255, 0.88);
backdrop-filter: blur(16px); backdrop-filter: blur(16px);
} }
...@@ -4200,11 +4172,11 @@ button.secondary { ...@@ -4200,11 +4172,11 @@ button.secondary {
min-height: 0; min-height: 0;
height: 100%; height: 100%;
gap: 10px; gap: 10px;
padding: 14px; padding: 10px;
border-radius: 20px; border: 0;
border: 1px solid rgba(175, 196, 255, 0.55); border-radius: 0;
background: linear-gradient(180deg, rgba(255, 255, 255, 0.9), rgba(247, 249, 255, 0.76)); background: transparent;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.92), 0 8px 22px rgba(94, 125, 255, 0.06); box-shadow: none;
} }
.settings-section-card-compact { .settings-section-card-compact {
...@@ -4274,6 +4246,24 @@ button.secondary { ...@@ -4274,6 +4246,24 @@ button.secondary {
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
.settings-inline-key-row {
display: grid;
grid-template-columns: minmax(0, 520px) auto;
align-items: end;
gap: 10px;
}
.settings-inline-key-row .settings-input-label {
display: grid;
}
.settings-inline-save-button {
min-width: 88px;
padding-inline: 16px;
justify-self: start;
white-space: nowrap;
}
.settings-input-label { .settings-input-label {
min-width: 0; min-width: 0;
gap: 5px; gap: 5px;
...@@ -4315,12 +4305,34 @@ button.secondary { ...@@ -4315,12 +4305,34 @@ button.secondary {
} }
.model-config-grid-four { .model-config-grid-four {
min-height: 0;
height: 100%; height: 100%;
overflow: auto; overflow-y: auto;
padding-right: 2px; overflow-x: hidden;
grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr); padding-right: 8px;
grid-template-rows: repeat(3, minmax(0, 1fr)); grid-template-columns: repeat(2, minmax(0, 1fr));
align-content: stretch; grid-auto-rows: minmax(188px, auto);
align-content: start;
scrollbar-width: thin;
scrollbar-color: rgba(125, 143, 255, 0.34) transparent;
}
.model-config-grid-four::-webkit-scrollbar {
width: 8px;
}
.model-config-grid-four::-webkit-scrollbar-track {
background: transparent;
}
.model-config-grid-four::-webkit-scrollbar-thumb {
border-radius: 999px;
background: rgba(125, 143, 255, 0.28);
border: 1px solid rgba(255, 255, 255, 0.22);
}
.model-config-grid-four::-webkit-scrollbar-thumb:hover {
background: rgba(125, 143, 255, 0.44);
} }
.model-config-card { .model-config-card {
...@@ -4382,26 +4394,6 @@ button.secondary { ...@@ -4382,26 +4394,6 @@ button.secondary {
align-content: start; align-content: start;
} }
.model-config-card-copywriting {
grid-column: 1;
grid-row: 1;
}
.model-config-card-image {
grid-column: 1;
grid-row: 2;
}
.model-config-card-video {
grid-column: 1;
grid-row: 3;
}
.model-config-card-digital-human {
grid-column: 2;
grid-row: 1 / span 3;
}
.model-config-card-body-digital-human { .model-config-card-body-digital-human {
overflow: visible; overflow: visible;
padding-right: 0; padding-right: 0;
...@@ -4510,27 +4502,7 @@ button.secondary { ...@@ -4510,27 +4502,7 @@ button.secondary {
@media (max-width: 1180px) { @media (max-width: 1180px) {
.model-config-grid-four { .model-config-grid-four {
grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-columns: repeat(2, minmax(0, 1fr));
grid-template-rows: auto auto auto; grid-auto-rows: minmax(188px, auto);
}
.model-config-card-copywriting {
grid-column: 1;
grid-row: 1;
}
.model-config-card-image {
grid-column: 2;
grid-row: 1;
}
.model-config-card-video {
grid-column: 1 / -1;
grid-row: 2;
}
.model-config-card-digital-human {
grid-column: 1 / -1;
grid-row: 3;
} }
} }
...@@ -4572,15 +4544,11 @@ button.secondary { ...@@ -4572,15 +4544,11 @@ button.secondary {
.model-config-grid, .model-config-grid,
.model-config-grid-four { .model-config-grid-four {
grid-template-columns: 1fr; grid-template-columns: 1fr;
grid-template-rows: none; grid-auto-rows: minmax(0, auto);
} }
.model-config-card-copywriting, .settings-inline-key-row {
.model-config-card-image, grid-template-columns: minmax(0, 1fr);
.model-config-card-video,
.model-config-card-digital-human {
grid-column: auto;
grid-row: auto;
} }
.settings-field-grid-digital-human { .settings-field-grid-digital-human {
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
chatCreateSessionForProject: "chat:create-session-for-project", chatCreateSessionForProject: "chat:create-session-for-project",
chatCloseSession: "chat:close-session", chatCloseSession: "chat:close-session",
chatListMessages: "chat:list-messages", chatListMessages: "chat:list-messages",
chatPickAttachments: "chat:pick-attachments",
chatPickImageAttachment: "chat:pick-image-attachment", chatPickImageAttachment: "chat:pick-image-attachment",
chatSendPrompt: "chat:send-prompt", chatSendPrompt: "chat:send-prompt",
chatStreamPrompt: "chat:stream-prompt", chatStreamPrompt: "chat:stream-prompt",
...@@ -416,7 +417,7 @@ export interface ProjectSessionState { ...@@ -416,7 +417,7 @@ export interface ProjectSessionState {
} }
export interface ChatAttachment { export interface ChatAttachment {
kind: "image"; kind: "image" | "file";
name: string; name: string;
mimeType: string; mimeType: string;
localPath: string; localPath: string;
...@@ -563,6 +564,18 @@ export interface DigitalHumanModelConfig { ...@@ -563,6 +564,18 @@ export interface DigitalHumanModelConfig {
qiniuSecretKeyConfigured: boolean; qiniuSecretKeyConfigured: boolean;
} }
export interface DouyinTextModelConfig {
baseUrl: string;
apiKeyConfigured: boolean;
modelId?: string;
}
export interface VectCutModelConfig {
baseUrl: string;
fileBaseUrl: string;
apiKeyConfigured: boolean;
}
export interface ExpertModelConfig { export interface ExpertModelConfig {
image: ModelEndpointConfig; image: ModelEndpointConfig;
video: ModelEndpointConfig; video: ModelEndpointConfig;
...@@ -570,6 +583,12 @@ export interface ExpertModelConfig { ...@@ -570,6 +583,12 @@ export interface ExpertModelConfig {
digitalHuman: DigitalHumanModelConfig; digitalHuman: DigitalHumanModelConfig;
} }
export interface DouyinRuntimeConfig {
videoAnalyzer: DouyinTextModelConfig;
replicationBrief: DouyinTextModelConfig;
vectcut: VectCutModelConfig;
}
export const FIXED_EXPERT_MODEL_ENDPOINTS = { export const FIXED_EXPERT_MODEL_ENDPOINTS = {
copywriting: { copywriting: {
baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1", baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1",
...@@ -596,6 +615,21 @@ export const FIXED_DIGITAL_HUMAN_CONFIG = { ...@@ -596,6 +615,21 @@ export const FIXED_DIGITAL_HUMAN_CONFIG = {
qiniuKeyPrefix: "omnihuman" qiniuKeyPrefix: "omnihuman"
} as const; } as const;
export const FIXED_DOUYIN_RUNTIME_CONFIG = {
videoAnalyzer: {
baseUrl: "https://ark.cn-beijing.volces.com/api/v3",
modelId: "",
},
replicationBrief: {
baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1",
modelId: "",
},
vectcut: {
baseUrl: "https://open.vectcut.com/cut_jianying",
fileBaseUrl: "https://open.vectcut.com"
}
} as const;
export interface AppConfig { export interface AppConfig {
setupMode: SetupMode; setupMode: SetupMode;
provider: string; provider: string;
...@@ -610,6 +644,7 @@ export interface AppConfig { ...@@ -610,6 +644,7 @@ export interface AppConfig {
runtimeCloudApiBaseUrl: string; runtimeCloudApiBaseUrl: string;
runtimeMode: RuntimeModePreference; runtimeMode: RuntimeModePreference;
expertModelConfig: ExpertModelConfig; expertModelConfig: ExpertModelConfig;
douyinRuntimeConfig: DouyinRuntimeConfig;
} }
export interface DiagnosticsExportResult { export interface DiagnosticsExportResult {
...@@ -631,6 +666,18 @@ export interface DigitalHumanModelInput { ...@@ -631,6 +666,18 @@ export interface DigitalHumanModelInput {
qiniuSecretKey?: string; qiniuSecretKey?: string;
} }
export interface DouyinTextModelInput {
baseUrl?: string;
apiKey?: string;
modelId?: string;
}
export interface VectCutModelInput {
baseUrl?: string;
fileBaseUrl?: string;
apiKey?: string;
}
export interface SaveConfigInput { export interface SaveConfigInput {
setupMode: SetupMode; setupMode: SetupMode;
provider: string; provider: string;
...@@ -650,6 +697,11 @@ export interface SaveConfigInput { ...@@ -650,6 +697,11 @@ export interface SaveConfigInput {
copywriting?: ModelEndpointInput; copywriting?: ModelEndpointInput;
digitalHuman?: DigitalHumanModelInput; digitalHuman?: DigitalHumanModelInput;
}; };
douyinRuntimeConfig?: {
videoAnalyzer?: DouyinTextModelInput;
replicationBrief?: DouyinTextModelInput;
vectcut?: VectCutModelInput;
};
} }
export interface AuthSessionSummary { export interface AuthSessionSummary {
...@@ -844,6 +896,7 @@ export interface DesktopApi { ...@@ -844,6 +896,7 @@ export interface DesktopApi {
createSessionForProject(projectId: string, title?: string): Promise<ProjectSessionSummary>; createSessionForProject(projectId: string, title?: string): Promise<ProjectSessionSummary>;
closeSession(sessionId: string): Promise<ProjectSessionSummary[]>; closeSession(sessionId: string): Promise<ProjectSessionSummary[]>;
listMessages(sessionId: string): Promise<ChatMessage[]>; listMessages(sessionId: string): Promise<ChatMessage[]>;
pickAttachments(): Promise<ChatAttachment[]>;
pickImageAttachment(): Promise<ChatAttachment | null>; pickImageAttachment(): Promise<ChatAttachment | null>;
sendPrompt(sessionId: string, prompt: string, skillId?: string, attachments?: ChatAttachment[]): Promise<PromptResult>; sendPrompt(sessionId: string, prompt: string, skillId?: string, attachments?: ChatAttachment[]): Promise<PromptResult>;
streamPrompt(sessionId: string, prompt: string, skillId?: string, attachments?: ChatAttachment[]): Promise<ChatStreamPromptResult>; streamPrompt(sessionId: string, prompt: string, skillId?: string, attachments?: ChatAttachment[]): Promise<ChatStreamPromptResult>;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment