Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ backend/.env
*.pyc
__pycache__/
.vite/
*.tsbuildinfo
frontend/vite.config.d.ts
frontend/vite.config.js
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ The figures below were generated entirely by PlotCraft — natural language in,

## License

This repository does not currently declare an open-source license. Until a LICENSE file is added, all rights are reserved by the author by default. You may refer to the code for reference, but please contact the author for permission before redistribution, derivative work, or commercial use.
This project is licensed under the MIT License — see the [LICENSE](./LICENSE) file for details. You are free to use, modify, and distribute this software, provided the copyright notice and license text are included.

---

Expand Down
2 changes: 1 addition & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ npm run dev

## 许可证

本仓库当前未声明开源许可证。在添加 LICENSE 文件之前,默认适用作者保留全部版权的隐式条款——可参考使用,但二次分发 / 衍生 / 商用前请联系作者授权
本项目基于 MIT 许可证开源——详见 [LICENSE](./LICENSE) 文件。您可以自由使用、修改和分发本软件,但需保留版权声明与许可文本

---

Expand Down
2 changes: 1 addition & 1 deletion README.zh-TW.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ npm run dev

## 授權條款

本倉庫當前未宣告開源授權條款。在新增 LICENSE 檔案之前,預設適用作者保留全部版權的隱式條款——可參考使用,但再散布 / 衍生 / 商用前請聯絡作者授權
本專案基於 MIT 授權條款開源——詳見 [LICENSE](./LICENSE) 檔案。您可以自由使用、修改和散布本軟體,但需保留版權聲明與授權文字

---

Expand Down
13 changes: 0 additions & 13 deletions backend/app/providers/factory.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from __future__ import annotations

import json
from typing import Any

from .base import Provider
Expand All @@ -19,15 +18,3 @@ def make_provider(provider: str, model_name: str, api_key: str, base_url: str =
# 预留:未来接入 Replicate / FAL 物理化位图生成模型
raise NotImplementedError("replicate provider 接口已预留,首版未实现。")
raise ValueError(f"未知 provider: {provider}")


def from_db_row(row) -> Provider:
"""从 SQLite row 构造带解密 key 的 Provider。"""
from ..crypto import decrypt
return make_provider(
provider=row["provider"],
model_name=row["model_name"],
api_key=decrypt(row["api_key_enc"]),
base_url=row["base_url"],
extra=json.loads(row["extra"] or "{}"),
)
3 changes: 2 additions & 1 deletion backend/app/routes/templates.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

import json
import logging
from pathlib import Path

from fastapi import APIRouter, HTTPException
Expand Down Expand Up @@ -118,6 +119,6 @@ async def seed_templates_if_empty() -> int:
)
n += 1
except Exception as exc:
print(f"[seed] 跳过 {fp.name}: {exc}")
logging.warning("跳过模板种子 %s: %s", fp.name, exc)
await db.commit()
return n
1 change: 1 addition & 0 deletions backend/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ aiofiles>=24.1.0
fastapi>=0.115.0
uvicorn[standard]>=0.32.0
python-dotenv>=1.0.1
pydantic-settings>=2.5.0
openai>=1.55.0
google-genai>=0.3.0
16 changes: 0 additions & 16 deletions frontend/src/components/SetupBanner.tsx

This file was deleted.

1 change: 1 addition & 0 deletions frontend/src/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ export const api = {
}),

listHistory: (limit = 50) => req<GenerationRecord[]>(`/api/history?limit=${limit}`),
getHistorySvg: (id: number) => req<{ svg: string }>(`/api/history/${id}/svg`),
clearHistory: () => req<void>("/api/history", { method: "DELETE" }),
deleteHistory: (id: number) => req<void>(`/api/history/${id}`, { method: "DELETE" }),
};
13 changes: 7 additions & 6 deletions frontend/src/pages/Generate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export default function GeneratePage() {
const [code, setCode] = useState("");
const [originalCode, setOriginalCode] = useState("");
const [showDiff, setShowDiff] = useState(false);
const [tplSystemPrompt, setTplSystemPrompt] = useState("");
const svgRef = useRef<HTMLDivElement>(null);
const abortRef = useRef<AbortController | null>(null);

Expand Down Expand Up @@ -52,15 +53,15 @@ export default function GeneratePage() {
if (tpl?.user_template && !userPrompt) {
setUserPrompt(tpl.user_template);
}
if (tpl?.system_prompt) setSystemOverride(tpl.system_prompt);
// 仅当用户未自定义 system prompt(内容为空或仍为上一个模板的默认值)时才跟随模板
const newDefault = tpl?.system_prompt || "";
if (systemOverride === "" || systemOverride === tplSystemPrompt) {
setSystemOverride(newDefault);
}
setTplSystemPrompt(newDefault);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [templateId]);

// 模板切换时刷新 systemOverride(当用户没自定义时跟模板走)
useEffect(() => {
if (tpl) setSystemOverride(tpl.system_prompt || "");
}, [tpl]);

async function run() {
if (!modelId) {
setErr("请先在「模型」页配置 AI 模型");
Expand Down
32 changes: 31 additions & 1 deletion frontend/src/pages/History.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { vscodeDark } from "@uiw/codemirror-theme-vscode";
export default function HistoryPage() {
const [items, setItems] = useState<GenerationRecord[]>([]);
const [active, setActive] = useState<GenerationRecord | null>(null);
const [svg, setSvg] = useState<string | null>(null);
const [msg, setMsg] = useState("");

async function load() {
Expand All @@ -21,6 +22,19 @@ export default function HistoryPage() {
load();
}, []);

async function selectRecord(r: GenerationRecord) {
setActive(r);
setSvg(null);
if (r.status === "success") {
try {
const res = await api.getHistorySvg(r.id);
setSvg(res.svg);
} catch {
// SVG 可能不存在(如旧记录),静默处理
}
}
}

async function clearAll() {
if (!confirm("清空全部历史?")) return;
await api.clearHistory();
Expand Down Expand Up @@ -52,7 +66,7 @@ export default function HistoryPage() {
items.map((r) => (
<li
key={r.id}
onClick={() => setActive(r)}
onClick={() => selectRecord(r)}
className={`p-3 border rounded cursor-pointer text-sm ${
active?.id === r.id ? "bg-slate-100 border-slate-400" : "hover:bg-slate-50"
}`}
Expand Down Expand Up @@ -104,6 +118,22 @@ export default function HistoryPage() {
editable={false}
/>
</div>
{active.status === "success" && (
<div className="bg-white border border-slate-200 rounded-lg p-4">
<div className="font-semibold text-sm mb-2">SVG 预览</div>
<div className="border border-slate-200 rounded bg-slate-50 flex items-center justify-center min-h-[200px] p-3">
{svg ? (
<div
className="w-full h-full flex items-center justify-center"
dangerouslySetInnerHTML={{ __html: svg }}
style={{ maxHeight: "50vh" }}
/>
) : (
<div className="text-slate-400 text-sm">加载中…</div>
)}
</div>
</div>
)}
</div>
) : (
<div className="text-slate-500 text-sm">点击左侧查看详情。</div>
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/pages/ModelConfig.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState } from "react";
import { useState, useEffect } from "react";
import type { ModelConfig, ModelConfigInput } from "../lib/api";
import { api } from "../lib/api";

Expand Down Expand Up @@ -37,7 +37,10 @@ export default function ModelConfigPage() {
}

// 第一次进入时加载
if (loading === false && models.length === 0 && !msg) load();
useEffect(() => {
load();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

function reset() {
setEditing({ ...empty });
Expand Down
1 change: 1 addition & 0 deletions frontend/src/vite-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="vite/client" />
1 change: 0 additions & 1 deletion frontend/tsconfig.node.tsbuildinfo

This file was deleted.

1 change: 0 additions & 1 deletion frontend/tsconfig.tsbuildinfo

This file was deleted.

2 changes: 0 additions & 2 deletions frontend/vite.config.d.ts

This file was deleted.

11 changes: 0 additions & 11 deletions frontend/vite.config.js

This file was deleted.