chore: release v0.0.5
This commit is contained in:
@@ -66,6 +66,14 @@
|
|||||||
- 数据库结构写到 `docs/backend-database.md`。
|
- 数据库结构写到 `docs/backend-database.md`。
|
||||||
- 文档不要写过期日期;除非用户明确要求记录具体时间。
|
- 文档不要写过期日期;除非用户明确要求记录具体时间。
|
||||||
|
|
||||||
|
## 发版本流程
|
||||||
|
|
||||||
|
- 发版本时,先把 `CHANGELOG.md` 的 `Unreleased` 变更整理成新的版本记录,并保留空的 `Unreleased` 标题。
|
||||||
|
- 按当前版本号提升一个版本,更新根目录 `VERSION`。
|
||||||
|
- 将当前未提交的代码全部提交到 Git。
|
||||||
|
- 提交完成后,给当前提交打最新版本号对应的 tag,例如 `v0.0.5`。
|
||||||
|
- 发版本流程中不要执行编译、测试或构建,除非用户明确要求。
|
||||||
|
|
||||||
## 项目注意事项
|
## 项目注意事项
|
||||||
|
|
||||||
- 当前画布项目和“我的素材”主要保存在浏览器本地,不要在文档中误写成已支持云同步。
|
- 当前画布项目和“我的素材”主要保存在浏览器本地,不要在文档中误写成已支持云同步。
|
||||||
|
|||||||
@@ -2,7 +2,10 @@
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
## v0.0.5 - 2026-05-20
|
||||||
|
|
||||||
+ [新增] 右上角版本号支持点击查看版本更新弹窗,展示当前版本、最新版本和按时间线整理的更新日志。
|
+ [新增] 右上角版本号支持点击查看版本更新弹窗,展示当前版本、最新版本和按时间线整理的更新日志。
|
||||||
|
+ [新增] 设置弹窗支持配置系统提示词,AI 生图、编辑图和文本请求会自动携带。
|
||||||
|
|
||||||
## v0.0.4 - 2026-05-20
|
## v0.0.4 - 2026-05-20
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
# 待测试
|
# 待测试
|
||||||
|
|
||||||
- 点击右上角版本号时,应弹出版本更新弹窗,并展示当前版本、最新版本、检查更新入口和可滚动的版本时间线。
|
- 点击右上角版本号时,应弹出版本更新弹窗,并展示当前版本、最新版本、检查更新入口和可滚动的版本时间线。
|
||||||
|
- 设置弹窗中填写系统提示词后,生图、编辑图和画布助手文本请求应携带该提示词。
|
||||||
|
|||||||
@@ -227,6 +227,9 @@ export function AppTopNav({ activeToolSlug, config, onConfigChange, hideHeader =
|
|||||||
<Form.Item label="默认文本模型" className="mb-0">
|
<Form.Item label="默认文本模型" className="mb-0">
|
||||||
<ModelPicker config={config} value={config.textModel} onChange={(model) => onConfigChange("textModel", model)} fullWidth />
|
<ModelPicker config={config} value={config.textModel} onChange={(model) => onConfigChange("textModel", model)} fullWidth />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item label="系统提示词" className="mb-0">
|
||||||
|
<Input.TextArea rows={4} value={config.systemPrompt} placeholder="例如:你是一位擅长电影感写实摄影的视觉导演。" onChange={(event) => onConfigChange("systemPrompt", event.target.value)} />
|
||||||
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ export type AiConfig = {
|
|||||||
model: string;
|
model: string;
|
||||||
imageModel: string;
|
imageModel: string;
|
||||||
textModel: string;
|
textModel: string;
|
||||||
|
systemPrompt: string;
|
||||||
models: string[];
|
models: string[];
|
||||||
quality: string;
|
quality: string;
|
||||||
size: string;
|
size: string;
|
||||||
@@ -18,6 +19,7 @@ export const defaultConfig: AiConfig = {
|
|||||||
model: "gpt-image-2",
|
model: "gpt-image-2",
|
||||||
imageModel: "gpt-image-2",
|
imageModel: "gpt-image-2",
|
||||||
textModel: "gpt-5.5",
|
textModel: "gpt-5.5",
|
||||||
|
systemPrompt: "",
|
||||||
models: [],
|
models: [],
|
||||||
quality: "auto",
|
quality: "auto",
|
||||||
size: "1:1",
|
size: "1:1",
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { imageToDataUrl } from "@/services/image-storage";
|
|||||||
import type { ReferenceImage } from "@/types/image";
|
import type { ReferenceImage } from "@/types/image";
|
||||||
|
|
||||||
export type ChatCompletionMessage = {
|
export type ChatCompletionMessage = {
|
||||||
role: "user" | "assistant";
|
role: "system" | "user" | "assistant";
|
||||||
content: string | Array<{ type: "text"; text: string } | { type: "image_url"; image_url: { url: string } }>;
|
content: string | Array<{ type: "text"; text: string } | { type: "image_url"; image_url: { url: string } }>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -58,6 +58,16 @@ function parseStreamChunk(chunk: string, onDelta: (value: string) => void) {
|
|||||||
if (deltaText) onDelta(deltaText);
|
if (deltaText) onDelta(deltaText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function withSystemPrompt(config: AiConfig, prompt: string) {
|
||||||
|
const systemPrompt = config.systemPrompt.trim();
|
||||||
|
return systemPrompt ? `${systemPrompt}\n\n${prompt}` : prompt;
|
||||||
|
}
|
||||||
|
|
||||||
|
function withSystemMessage(config: AiConfig, messages: ChatCompletionMessage[]) {
|
||||||
|
const systemPrompt = config.systemPrompt.trim();
|
||||||
|
return systemPrompt ? [{ role: "system" as const, content: systemPrompt }, ...messages] : messages;
|
||||||
|
}
|
||||||
|
|
||||||
export async function requestGeneration(config: AiConfig, prompt: string) {
|
export async function requestGeneration(config: AiConfig, prompt: string) {
|
||||||
const n = Math.max(1, Math.min(15, Math.floor(Math.abs(Number(config.count)) || 1)));
|
const n = Math.max(1, Math.min(15, Math.floor(Math.abs(Number(config.count)) || 1)));
|
||||||
try {
|
try {
|
||||||
@@ -65,7 +75,7 @@ export async function requestGeneration(config: AiConfig, prompt: string) {
|
|||||||
buildApiUrl(config.baseUrl, "/images/generations"),
|
buildApiUrl(config.baseUrl, "/images/generations"),
|
||||||
{
|
{
|
||||||
model: config.model,
|
model: config.model,
|
||||||
prompt,
|
prompt: withSystemPrompt(config, prompt),
|
||||||
n,
|
n,
|
||||||
quality: config.quality || undefined,
|
quality: config.quality || undefined,
|
||||||
size: config.size || undefined,
|
size: config.size || undefined,
|
||||||
@@ -88,7 +98,7 @@ export async function requestEdit(config: AiConfig, prompt: string, references:
|
|||||||
const n = Math.max(1, Math.min(15, Math.floor(Math.abs(Number(config.count)) || 1)));
|
const n = Math.max(1, Math.min(15, Math.floor(Math.abs(Number(config.count)) || 1)));
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.set("model", config.model);
|
formData.set("model", config.model);
|
||||||
formData.set("prompt", prompt);
|
formData.set("prompt", withSystemPrompt(config, prompt));
|
||||||
formData.set("n", String(n));
|
formData.set("n", String(n));
|
||||||
formData.set("response_format", "b64_json");
|
formData.set("response_format", "b64_json");
|
||||||
if (config.quality) {
|
if (config.quality) {
|
||||||
@@ -122,7 +132,7 @@ export async function requestImageQuestion(config: AiConfig, messages: ChatCompl
|
|||||||
buildApiUrl(config.baseUrl, "/chat/completions"),
|
buildApiUrl(config.baseUrl, "/chat/completions"),
|
||||||
{
|
{
|
||||||
model: config.model,
|
model: config.model,
|
||||||
messages,
|
messages: withSystemMessage(config, messages),
|
||||||
stream: true,
|
stream: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user