chore: sync local changes to Gitea
This commit is contained in:
BIN
bin/gitea-mcp
BIN
bin/gitea-mcp
Binary file not shown.
30
worker.js
30
worker.js
@@ -3,17 +3,17 @@ export default {
|
|||||||
const url = new URL(request.url);
|
const url = new URL(request.url);
|
||||||
const { pathname } = url;
|
const { pathname } = url;
|
||||||
|
|
||||||
// CORS preflight for API
|
// API 的 CORS 预检请求
|
||||||
if (request.method === "OPTIONS" && pathname.startsWith("/api/")) {
|
if (request.method === "OPTIONS" && pathname.startsWith("/api/")) {
|
||||||
return new Response(null, { headers: corsHeaders() });
|
return new Response(null, { headers: corsHeaders() });
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- API: list languages (common) ---
|
// --- API:返回语言列表(常用) ---
|
||||||
if (pathname === "/api/languages") {
|
if (pathname === "/api/languages") {
|
||||||
return jsonResponse({ languages: COMMON_LANGUAGES }, 200, corsHeaders());
|
return jsonResponse({ languages: COMMON_LANGUAGES }, 200, corsHeaders());
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- API: translate ---
|
// --- API:翻译 ---
|
||||||
if (pathname === "/api/translate") {
|
if (pathname === "/api/translate") {
|
||||||
if (request.method !== "POST") {
|
if (request.method !== "POST") {
|
||||||
return jsonResponse(
|
return jsonResponse(
|
||||||
@@ -23,7 +23,7 @@ export default {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optional API key
|
// 可选的 API Key 校验
|
||||||
const apiKey = env.API_KEY;
|
const apiKey = env.API_KEY;
|
||||||
if (apiKey) {
|
if (apiKey) {
|
||||||
const got =
|
const got =
|
||||||
@@ -44,7 +44,7 @@ export default {
|
|||||||
|
|
||||||
const text = (body.text ?? "").toString();
|
const text = (body.text ?? "").toString();
|
||||||
const target_lang = (body.target_lang ?? "").toString().trim();
|
const target_lang = (body.target_lang ?? "").toString().trim();
|
||||||
const source_lang_raw = (body.source_lang ?? "").toString().trim(); // optional
|
const source_lang_raw = (body.source_lang ?? "").toString().trim(); // 可选
|
||||||
|
|
||||||
if (!text) return jsonResponse({ error: "text is required" }, 400, corsHeaders());
|
if (!text) return jsonResponse({ error: "text is required" }, 400, corsHeaders());
|
||||||
if (!target_lang) return jsonResponse({ error: "target_lang is required" }, 400, corsHeaders());
|
if (!target_lang) return jsonResponse({ error: "target_lang is required" }, 400, corsHeaders());
|
||||||
@@ -59,7 +59,7 @@ export default {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (translate_all) {
|
if (translate_all) {
|
||||||
// Use batch requests (Workers AI supports batch schema on this model) :contentReference[oaicite:2]{index=2}
|
// 使用批量请求(Workers AI 在该模型上支持批量 schema)
|
||||||
const requests = chunks.slice(0, 50).map((t) => ({
|
const requests = chunks.slice(0, 50).map((t) => ({
|
||||||
text: t,
|
text: t,
|
||||||
...(source_lang_raw ? { source_lang: normalizeLang(source_lang_raw) } : {}),
|
...(source_lang_raw ? { source_lang: normalizeLang(source_lang_raw) } : {}),
|
||||||
@@ -67,12 +67,12 @@ export default {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
const out = await env.AI.run("@cf/meta/m2m100-1.2b", { requests });
|
const out = await env.AI.run("@cf/meta/m2m100-1.2b", { requests });
|
||||||
// Some bindings return array-like results; normalize defensively:
|
// 某些绑定会返回类似数组的结果;这里做防御性归一化处理:
|
||||||
const translated_pages = Array.isArray(out)
|
const translated_pages = Array.isArray(out)
|
||||||
? out.map((x) => x?.translated_text ?? "")
|
? out.map((x) => x?.translated_text ?? "")
|
||||||
: (out?.responses ?? out?.results ?? out?.translated_pages ?? null);
|
: (out?.responses ?? out?.results ?? out?.translated_pages ?? null);
|
||||||
|
|
||||||
// Fallback: if unknown, just translate one-by-one
|
// 兜底处理:如果返回结构不符合预期,就退回到单页翻译
|
||||||
if (Array.isArray(translated_pages)) {
|
if (Array.isArray(translated_pages)) {
|
||||||
return jsonResponse(
|
return jsonResponse(
|
||||||
{
|
{
|
||||||
@@ -89,7 +89,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default: translate one page
|
// 默认:仅翻译单页
|
||||||
const chunk = chunks[safePage - 1] ?? "";
|
const chunk = chunks[safePage - 1] ?? "";
|
||||||
const out = await env.AI.run("@cf/meta/m2m100-1.2b", {
|
const out = await env.AI.run("@cf/meta/m2m100-1.2b", {
|
||||||
text: chunk,
|
text: chunk,
|
||||||
@@ -119,7 +119,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Web UI ---
|
// --- Web 界面 ---
|
||||||
if (pathname === "/" || pathname === "/index.html") {
|
if (pathname === "/" || pathname === "/index.html") {
|
||||||
if (request.method === "GET") {
|
if (request.method === "GET") {
|
||||||
return new Response(renderPage({}), {
|
return new Response(renderPage({}), {
|
||||||
@@ -182,7 +182,7 @@ export default {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------- helpers ----------------
|
// ---------------- 辅助函数 ----------------
|
||||||
|
|
||||||
const COMMON_LANGUAGES = [
|
const COMMON_LANGUAGES = [
|
||||||
{ code: "en", name: "English" },
|
{ code: "en", name: "English" },
|
||||||
@@ -208,8 +208,8 @@ const COMMON_LANGUAGES = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
function normalizeLang(lang) {
|
function normalizeLang(lang) {
|
||||||
// Docs say language code like 'en'/'es' etc. :contentReference[oaicite:3]{index=3}
|
// 文档里写的是语言代码,例如 'en'/'es' 等。
|
||||||
// But examples sometimes use english/french; we accept both by passing through.
|
// 但有些示例会使用 english/french,这里也允许原样透传。
|
||||||
return String(lang || "").trim().toLowerCase();
|
return String(lang || "").trim().toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,7 +223,7 @@ function splitText(text, maxChars) {
|
|||||||
const t = String(text || "");
|
const t = String(text || "");
|
||||||
if (t.length <= maxChars) return [t];
|
if (t.length <= maxChars) return [t];
|
||||||
|
|
||||||
// Prefer paragraph-based splitting
|
// 优先按段落拆分
|
||||||
const parts = t.split(/\n{2,}/);
|
const parts = t.split(/\n{2,}/);
|
||||||
const chunks = [];
|
const chunks = [];
|
||||||
let buf = "";
|
let buf = "";
|
||||||
@@ -231,7 +231,7 @@ function splitText(text, maxChars) {
|
|||||||
for (const p of parts) {
|
for (const p of parts) {
|
||||||
const piece = (p + "\n\n");
|
const piece = (p + "\n\n");
|
||||||
if (piece.length > maxChars) {
|
if (piece.length > maxChars) {
|
||||||
// Hard split long paragraph
|
// 对超长段落进行硬切分
|
||||||
if (buf) {
|
if (buf) {
|
||||||
chunks.push(buf);
|
chunks.push(buf);
|
||||||
buf = "";
|
buf = "";
|
||||||
|
|||||||
Reference in New Issue
Block a user