内置服务商与模型选择
本文记录 OneDocs 当前仓库中与“内置服务商与模型选择”相关的可验证实现边界。现有源码能够确认网页层存在 .model-card 模型卡片及其交互动画,但在本次检索到的仓库文件中,未找到服务商列表、模型选择状态、模型配置持久化或实际 AI 请求分发实现。
Purpose and Scope
本页聚焦于仓库中已经可见的模型展示与交互入口,以及它与静态文档站点行为之间的关系。范围包括:
docs/script.js对.model-card元素的滚动入场和鼠标 3D 倾斜处理;- 页面加载、滚动观察和卡片事件绑定的生命周期;
- 当前前端依赖与构建入口中可确认的技术边界。
服务商凭据、模型目录、默认模型、模型切换状态管理、后端代理和请求协议在本次读取的源码中没有实现证据,因此不在本页虚构 API 或配置项。若仓库其他目录存在这些能力,应另建或补充对应的服务商配置/AI 调用页面。
Overview
当前可确认的“模型”相关能力是展示层能力:页面加载后,脚本查找 .model-card 元素,为其添加滚动显现行为,并在鼠标移动时根据指针相对卡片中心的位置计算 rotateX 与 rotateY,从而生成透视倾斜效果。鼠标离开时,脚本清空 transform,恢复卡片的默认样式。
这意味着现有实现更接近“内置模型信息的视觉展示”,而不是运行时的 provider/model resolver。源码没有暴露模型 ID、服务商枚举、选择回调、请求参数或持久化键;因此不能从当前证据推导出用户选择模型后会调用哪个服务商,也不能确认是否存在默认模型或故障转移策略。
Architecture
该图只表示源码中已经验证的浏览器端关系:DOMContentLoaded 回调初始化页面行为;.model-card 同时进入滚动显现目标集合,并注册 mousemove/mouseleave 事件;鼠标事件最终写入卡片的 style.transform。图中没有加入 provider、model registry、HTTP client 或存储层,因为当前检索证据没有证明这些组件存在。
实现 walkthrough
页面初始化
docs/script.js 在 DOMContentLoaded 中完成所有页面交互初始化。模型卡片相关逻辑分为两个阶段:先把模型卡片纳入通用的 reveal 目标,再单独注册 3D 倾斜事件。
1const revealTargets = document.querySelectorAll(
2 '.section-head, .whats-new-card, .feature-inner, .model-card, ' +
3 '.download-card, .ack-card, .showcase-screen, .showcase-tile, .privacy-inner'
4);
5revealTargets.forEach(el => el.classList.add('reveal'));
6
7const revealObserver = new IntersectionObserver(function (entries) {
8 entries.forEach((entry, index) => {
9 if (entry.isIntersecting) {
10 // 错开兄弟元素的延迟
11 const siblings = entry.target.parentElement
12 ? Array.from(entry.target.parentElement.children).filter(c => c.classList.contains('reveal'))
13 : [];
14 const idx = siblings.indexOf(entry.target);
15 const delay = idx > 0 ? Math.min(idx * 60, 240) : 0;
16
17 setTimeout(() => {
18 entry.target.classList.add('visible');
19 }, delay);
20
21 revealObserver.unobserve(entry.target);
22 }
23 });
24}, {
25 threshold: 0.12,
26 rootMargin: '0px 0px -50px 0px'
27});
28
29revealTargets.forEach(el => revealObserver.observe(el));Source: docs/script.js
实现意图是把“是否进入视口”和“卡片自身的视觉变换”解耦:IntersectionObserver 只负责一次性的显现,且通过 unobserve 避免同一元素重复触发;兄弟元素按最多 240ms 的间隔错开显示,使模型卡片不会同时跳入页面。
模型卡片的 3D 交互
鼠标移动处理不依赖模型数据,只依赖卡片几何尺寸和指针位置。指针位于卡片中心时,两个旋转角接近零;越靠近边缘,旋转幅度越大。除以 25 的缩放限制了倾斜幅度,避免交互过于剧烈。
1document.querySelectorAll('.model-card').forEach(card => {
2 card.addEventListener('mousemove', function (e) {
3 const rect = card.getBoundingClientRect();
4 const x = e.clientX - rect.left;
5 const y = e.clientY - rect.top;
6 const centerX = rect.width / 2;
7 const centerY = rect.height / 2;
8 const rotateX = (y - centerY) / 25;
9 const rotateY = (centerX - x) / 25;
10 card.style.transform = `translateY(-4px) perspective(600px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;
11 });
12 card.addEventListener('mouseleave', function () {
13 card.style.transform = '';
14 });
15});Source: docs/script.js
这里没有选择事件、模型 ID 或 provider 参数。mousemove 只改变 CSS transform;因此不能把该交互解释为“切换模型”或“调用服务商”。
Core Flow
Source: docs/script.js
状态与并发行为
源码没有独立的模型选择状态,也没有异步请求、竞态处理或锁。可观察到的状态只有 DOM class/style:
- 初始状态:卡片可能没有
revealclass; - 初始化后:卡片获得
reveal; - 首次进入观察区域:经过兄弟元素延迟后获得
visible,随后停止观察; - 鼠标移动:实时覆盖
style.transform; - 鼠标离开:清空
style.transform。
IntersectionObserver 的回调和鼠标事件都运行在浏览器事件循环中。源码未实现 provider/model 数据更新,所以不存在可从当前代码确认的模型选择并发一致性、请求取消、重试或缓存语义。
Usage Examples
页面侧模型卡片展示行为
页面只需要提供带有 .model-card class 的元素,脚本会自动将其纳入上述交互。当前源码中没有对应 HTML 卡片片段可供本页引用,因此这里只能引用已验证的 JavaScript 绑定逻辑,不能补写未读取到的 HTML 结构。
构建与运行边界
项目使用 Vite 进行开发、构建和预览,并通过 TypeScript 编译检查后执行 Vite build:
1{
2 "scripts": {
3 "dev": "vite",
4 "build": "tsc && vite build",
5 "preview": "vite preview",
6 "tauri": "tauri",
7 "tauri:dev": "tauri dev",
8 "tauri:build": "tauri build"
9 }
10}Source: package.json
Configuration Options
当前检索到的源码没有 provider/model 配置项。可以确认的项目级构建入口如下:
| 项目 | 类型 | 默认/脚本值 | 说明 |
|---|---|---|---|
dev | npm script | vite | 启动 Vite 开发服务器 |
build | npm script | tsc && vite build | 先执行 TypeScript 检查,再构建前端 |
preview | npm script | vite preview | 预览构建结果 |
上述脚本是工程运行配置,不是 AI 服务商或模型配置。服务商 URL、API key、模型名和默认选择在已读取文件中未找到实现细节。
API Reference
本页范围内没有公开的 provider/model API。docs/script.js 中存在的是浏览器事件处理器,而不是可供业务层调用的模型选择接口:
.model-card的mousemovehandler:根据指针位置更新 CSS transform;无返回值,也不接收模型参数。.model-card的mouseleavehandler:清空 CSS transform;无返回值。IntersectionObservercallback:在卡片进入视口后添加visibleclass,并停止观察;无业务返回值。
Failure Modes, Edge Cases & Operational Notes
- 如果页面没有
.model-card元素,querySelectorAll返回空集合,模型卡片交互不会发生;源码没有抛出错误或提供降级提示。 - 如果卡片父元素不存在,reveal 回调中的条件表达式会使用空数组,因此延迟为 0;这是 DOM 结构缺失时的安全分支。
- 鼠标离开卡片会直接清除 inline transform,恢复 CSS 样式;源码没有保存上一次旋转值。
- 3D 倾斜逻辑没有触摸事件或 reduced-motion 分支。移动端和无障碍行为在已读取源码中没有专门实现。
- 未发现网络请求、API key 读取、模型加载、重试、超时、缓存或 provider 故障转移逻辑,因此这些运行时行为不能从本页证据确认。
Extension Points
若后续要把当前展示层扩展为真正的内置服务商与模型选择能力,已有 .model-card 只能作为视觉入口;还需要在源码中明确增加并记录:模型唯一标识、服务商到模型的映射、选择状态存储、请求调用边界以及错误处理。当前仓库证据不足以指定这些新增 API 的签名或配置格式,因此本页不提供虚构的实现示例。