Files
magpie/site/public/import.html
T
Austie 86a2b8cf47 providers: qianfan personal, team and pay-as-you-go endpoints (#211)
* providers: qianfan personal, team and pay-as-you-go endpoints as its preset regions

* providers: qianfan review fixes — pay-as-you-go fetches /v2/models, enterprise naming, the plans' union models, a zh note

* providers: qianfan plans list nothing, pay as you go does — NoList scoped by region

* providers: qianfan review round two — old id maps to the new preset, the union models, IAM keys and a README section

* providers: qianfan key link follows the region — normalize takes it from the endpoints, the button from the plan picked

* providers: ParseImport takes a region key page
2026-09-29 23:25:56 +08:00

166 lines
9.3 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Add to magpie</title>
<meta name="description" content="Open this link in magpie to add a model provider to every agent you use.">
<meta name="color-scheme" content="light dark">
<meta name="theme-color" content="#fafafa">
<meta name="referrer" content="no-referrer">
<meta name="robots" content="noindex">
<script>
(() => {
let mode = "system";
try { mode = localStorage.getItem("theme") || "system"; } catch {}
const q = matchMedia("(prefers-color-scheme: dark)");
const apply = () => {
const t = mode === "system" ? (q.matches ? "dark" : "light") : mode;
document.documentElement.dataset.theme = t;
document.querySelector('meta[name="theme-color"]').content = t === "dark" ? "#0b0b0c" : "#fafafa";
};
q.addEventListener("change", () => mode === "system" && apply());
apply();
})();
</script>
<link rel="icon" href="/favicon.png" type="image/png">
<link rel="stylesheet" href="/docs.css">
<meta property="og:title" content="Add to magpie">
<meta property="og:description" content="Open this link in magpie to add a model provider to every agent you use.">
<meta property="og:image" content="https://usemagpie.ai/img/og.png">
<meta name="twitter:card" content="summary_large_image">
<style>
body { min-height: 100vh; min-height: 100dvh; display: flex; flex-direction: column; }
.stage { flex: 1; display: grid; place-items: center; padding: 48px 16px 64px; }
.card { width: 100%; max-width: 440px; background: var(--card); border: 1px solid var(--line); border-radius: 20px; box-shadow: var(--shadow); padding: 34px 30px 26px; text-align: center; }
.mark { display: flex; align-items: center; justify-content: center; gap: 14px; margin-bottom: 22px; }
.mark .tile { width: 52px; height: 52px; border-radius: 14px; border: 1px solid var(--line); display: grid; place-items: center; background: var(--bg); font-weight: 650; font-size: 20px; color: var(--ink); overflow: hidden; }
.mark .tile img { width: 30px; height: 30px; }
.mark .plus { color: var(--ink3); font-size: 18px; }
h1 { font-size: 23px; letter-spacing: -.02em; line-height: 1.25; margin: 0 0 8px; font-weight: 660; overflow-wrap: anywhere; }
.sub { color: var(--ink2); font-size: 15px; margin: 0 0 22px; }
dl { text-align: left; margin: 0 0 24px; border-top: 1px solid var(--line); }
dl > div { display: grid; grid-template-columns: 76px minmax(0, 1fr); gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--line); font-size: 14px; }
dt { color: var(--ink3); }
dd { margin: 0; color: var(--ink); overflow-wrap: anywhere; }
dd code { font-size: 13px; }
dd .m { display: inline-block; font-size: 12.5px; border: 1px solid var(--line); border-radius: 999px; padding: 0 8px; margin: 2px 4px 2px 0; color: var(--ink2); }
.actions { display: grid; gap: 10px; }
.actions .btn { width: 100%; height: 44px; }
.fine { color: var(--ink3); font-size: 12.5px; margin: 18px 0 0; line-height: 1.55; }
.fine a { color: var(--ink2); }
.foot { text-align: center; font-size: 13px; color: var(--ink3); padding: 0 16px 28px; }
.foot a { text-decoration: none; color: var(--ink2); }
.foot a:hover { color: var(--ink); }
@media (max-width: 480px) { .card { padding: 28px 20px 22px; border-radius: 16px; } }
</style>
</head>
<body>
<div class="stage">
<div class="card" id="card">
<div class="mark"><div class="tile" id="tile">?</div><span class="plus">→</span><div class="tile"><img class="bird" src="/img/magpie-small.svg" alt="magpie"></div></div>
<h1 id="title">Add to magpie</h1>
<p class="sub" id="sub">Opening magpie…</p>
<dl id="facts"></dl>
<div class="actions" id="actions">
<a class="btn" id="open" href="#"><img class="bird-inv" src="/img/magpie-small.svg" alt="">Open in magpie</a>
<a class="btn ghost" id="dl" href="/#get">Don’t have magpie? Download it</a>
</div>
<p class="fine" id="fine">magpie shows you everything before it adds anything. Needs magpie 0.1.8 or later.</p>
</div>
</div>
<div class="foot"><a href="/">usemagpie.ai</a> · <a href="/docs/import">Add magpie links to your site</a></div>
<script>
(() => {
// The link's parameters are in the fragment, which never reaches a
// server; this page only turns them into magpie://import?… and shows
// what they describe. The key is never displayed.
const raw = location.hash.slice(1);
const q = new URLSearchParams(raw);
const $ = (id) => document.getElementById(id);
const text = (tag, s, cls) => { const e = document.createElement(tag); e.textContent = s; if (cls) e.className = cls; return e; };
// Download for this system.
const ua = navigator.userAgent;
const os = /Windows/.test(ua) ? "windows" : /Linux|X11|CrOS/.test(ua) && !/Android/.test(ua) ? "linux" : /Mac/.test(ua) ? "mac" : "";
if (os === "windows") $("dl").href = "/download/windows";
else if (os === "linux") $("dl").href = "/#get";
else if (os === "mac") $("dl").href = "/download/mac-arm64";
// Presets by their proper names, with the icons the home page has.
const PRESETS = {
anthropic: ["Anthropic", "claude-color.svg"], openai: ["OpenAI", "openai.svg"], google: ["Google Gemini", "gemini-color.svg"],
deepseek: ["DeepSeek", "deepseek-color.svg"], xai: ["xAI", "xai.svg"], moonshot: ["Kimi", "kimi.svg"], "moonshot-cn": ["Kimi (China)", "kimi.svg"],
zhipu: ["Zhipu GLM", "zhipu-color.svg"], zai: ["Z.ai", "zhipu-color.svg"], minimax: ["MiniMax", "minimax-color.svg"],
"minimax-cn": ["MiniMax (China)", "minimax-color.svg"], qwen: ["Qwen", "qwen-color.svg"], "qwen-cn": ["Qwen (China)", "qwen-color.svg"],
"baidu-qianfan": ["Baidu Qianfan", "baiducloud-color.svg"],
"qianfan-token-plan": ["Baidu Qianfan", "baiducloud-color.svg"],
"tencent-token-plan": ["Tencent Cloud Token Plan", "tencentcloud-color.svg"], huaweicloud: ["Huawei Cloud MaaS", "huaweicloud-color.svg"], volcengine: ["Volcengine Ark", "volcengine-color.svg"],
mistral: ["Mistral", "mistral-color.svg"], groq: ["Groq", "groq.svg"], openrouter: ["OpenRouter", "openrouter.svg"],
"opencode-go": ["OpenCode Go", "opencode.svg"], "opencode-zen": ["OpenCode Zen", "opencode.svg"], together: ["Together AI"],
fireworks: ["Fireworks"], siliconflow: ["SiliconFlow"], nvidia: ["NVIDIA NIM", "nvidia-color.svg"], modelscope: ["ModelScope", "modelscope-color.svg"], aihubmix: ["AiHubMix"], "302ai": ["302.AI"], yylx: ["鱼鱼连线"],
"ollama-cloud": ["Ollama Cloud", "ollama.svg"], ollama: ["Ollama", "ollama.svg"], lmstudio: ["LM Studio"],
};
const preset = (q.get("preset") || "").toLowerCase();
const known = PRESETS[preset];
const name = q.get("name") || (known ? known[0] : "");
if (!raw || (!name && !preset)) {
$("title").textContent = "Add to magpie";
$("sub").textContent = "This page opens magpie import links, and this one carries nothing to import.";
$("tile").textContent = "?";
$("open").href = "/docs/import";
$("open").lastChild.textContent = "How import links work";
$("fine").textContent = "";
return;
}
const label = name || preset;
$("title").textContent = "Add " + label + " to magpie";
$("tile").textContent = label.trim().charAt(0).toUpperCase() || "?";
if (known && known[1] && !q.get("name")) {
const img = document.createElement("img");
img.src = "/icons/" + known[1]; img.alt = "";
$("tile").replaceChildren(img);
}
document.title = "Add " + label + " to magpie";
const hosts = [];
for (const k of ["chat", "responses", "anthropic"]) {
try { const h = new URL(q.get(k)).host; if (h && !hosts.includes(h)) hosts.push(h); } catch {}
}
const row = (k, v) => { const d = document.createElement("div"); d.append(text("dt", k)); const dd = document.createElement("dd"); typeof v === "string" ? (dd.textContent = v) : dd.append(...v); d.append(dd); $("facts").append(d); };
if (preset) row("Preset", [text("code", preset)].concat(q.get("region") ? [text("span", " · " + q.get("region"))] : []));
if (hosts.length) row("Sends to", hosts.map((h, i) => text("code", (i ? ", " : "") + h)));
row("API key", q.get("key") ? "Included" : "Not included; you’ll paste one");
const models = (q.get("models") || "").split(",").map((s) => s.trim()).filter(Boolean);
if (models.length) row("Models", models.slice(0, 12).map((m) => text("span", m, "m")).concat(models.length > 12 ? [text("span", "+" + (models.length - 12))] : []));
const link = "magpie://import?" + raw;
$("open").href = link;
$("sub").textContent = "magpie will ask before adding it.";
// magpie runs on computers; on a phone, say where to open this.
if (/iPhone|iPad|iPod|Android/.test(ua)) {
$("sub").textContent = "Open this link on the computer where you use magpie.";
$("actions").remove();
$("fine").innerHTML = "";
$("fine").append("magpie is a desktop app for macOS, Windows and Linux. ", Object.assign(document.createElement("a"), { href: "/", textContent: "Learn more" }));
return;
}
// One attempt on arrival; the button is there when the browser wants a
// click first, or when magpie isn't installed yet.
let left = false;
addEventListener("blur", () => (left = true));
document.addEventListener("visibilitychange", () => document.hidden && (left = true));
setTimeout(() => { location.href = link; }, 350);
setTimeout(() => {
if (!left) $("sub").textContent = "Nothing happened? Open it below, or install magpie first.";
}, 2600);
})();
</script>
</body>
</html>