快速开始
现在怎么用
用默认数据库、Admin City 和 User City 跑通一条完整调用链。
如果你想先按仓库里的现成产品体验,入口是:
cities/nodecli/city
跑通后,你会得到这个调用链:
Town Client
↓ Admin City 创建 town / 签发 user_token
Downcity City
↓ User City 携带 user_token + town_id 调用 service
Provider → AIService → handler1. 启动 City
import { CityBase, AIService, Provider } from "@downcity/city";
import Database from "better-sqlite3";
import { drizzle } from "drizzle-orm/better-sqlite3";
const sqlite = new Database("./data.sqlite");
sqlite.pragma("journal_mode = WAL");
const db = Object.assign(drizzle(sqlite), {
$client: { exec: (sql: string) => sqlite.exec(sql) },
});
const base = new CityBase({ db, dialect: "sqlite", raw: sqlite });
// 注册一个 echo 模型
const echo = new Provider("echo", {
text: async (ctx) => ({
id: crypto.randomUUID(),
role: "assistant",
parts: [{ type: "text", text: `Echo: ${ctx.input.prompt}` }],
}),
stream: async (ctx) => {
const { createUIMessageStreamResponse } = await import("ai");
return createUIMessageStreamResponse({
execute: async ({ writer }) => {
writer.write({ type: "text-delta", textDelta: `Echo: ${ctx.input.prompt}` });
},
});
},
});
const ai = new AIService();
ai.use(echo.model({ id: "local-echo", name: "Local Echo", default: true }));
base.use(ai);
import { serve } from "@hono/node-server";
await base.health();
serve({ fetch: base.router().fetch, port: 43127, hostname: "127.0.0.1" });2. 创建 town 并签发 token
import { City } from "@downcity/city";
const admin = new City({
role: "admin",
city_url: "http://127.0.0.1:43127",
admin_secret_key: process.env.DOWNCITY_CITY_ADMIN_SECRET_KEY,
});
const town = await admin.towns.create({ name: "Demo Town" });
const token = await admin.towns.tokens.apply({
town_id: town.town_id,
user_id: "user_123",
metadata: { plan: "pro" },
ttl: "7d",
});3. 产品侧调用
import { City } from "@downcity/city";
const client = new City({
role: "user",
city_url: "http://127.0.0.1:43127",
town_id: town.town_id,
user_token: token.user_token,
});
const catalog = await client.ai.listModels();
// SDK 通路
const result = await client.ai.text({
model: catalog.default(),
prompt: "你好 Downcity",
});
// OpenAI 兼容通路(curl)
// POST /v1/ai/chat/completions
// { model: "local-echo", messages: [{ role: "user", content: "hello" }] }4. 你真正复用的是什么
多个产品接入后,复用的是这些东西:
.env中的 provider keyuser_token校验- AIService 的模型路由
- hook 里的套餐、限额、日志和扣费
下一步: