diff --git a/packages/website/src/components/Heading.tsx b/packages/website/src/components/Heading.tsx index 29b0e91..2e15c80 100644 --- a/packages/website/src/components/Heading.tsx +++ b/packages/website/src/components/Heading.tsx @@ -2,7 +2,7 @@ import { ComponentPropsWithoutRef, useEffect, useRef } from 'react' import { cn } from '@/lib/utils' -type Level = 2 | 3 +type Level = 2 | 3 | 4 interface HeadingProps extends Omit, 'children'> { id: string @@ -11,8 +11,9 @@ interface HeadingProps extends Omit, 'children'> } const levelStyles = { - 2: { tag: 'h2', className: 'text-2xl font-semibold mb-4' }, - 3: { tag: 'h3', className: 'text-xl font-semibold mb-3' }, + 2: { tag: 'h2', className: 'text-3xl font-semibold mb-4' }, + 3: { tag: 'h3', className: 'text-[1.375rem] font-semibold mb-3' }, + 4: { tag: 'h4', className: 'text-[1.0625rem] font-medium mb-2' }, } as const export function Heading({ id, level = 2, className, children, ...props }: HeadingProps) { diff --git a/packages/website/src/index.css b/packages/website/src/index.css index 0864360..32503da 100644 --- a/packages/website/src/index.css +++ b/packages/website/src/index.css @@ -95,7 +95,7 @@ body { line-height: 1.6; } -/* 标题使用中等字重(相对细体更重,但比默认 bold 更轻) */ +/* 文档标题层级需要比正文标题更清晰,避免 h2/h3/h4 视觉差异过小。 */ .prose h1, .prose h2, .prose h3, @@ -103,6 +103,33 @@ body { .prose h5, .prose h6 { font-weight: 480; + line-height: 1.25; + letter-spacing: -0.015em; +} + +.prose h2[id] { + margin-bottom: 1rem; + padding-bottom: 0.45rem; + border-bottom: 1px solid rgba(23, 23, 23, 0.12); + font-size: 1.875rem; + font-weight: 650; +} + +.prose h3[id] { + margin-bottom: 0.75rem; + font-size: 1.375rem; + font-weight: 600; +} + +.prose h4[id] { + margin-bottom: 0.5rem; + font-size: 1.0625rem; + font-weight: 560; + letter-spacing: -0.005em; +} + +.dark .prose h2[id] { + border-bottom-color: rgba(255, 255, 255, 0.14); } /* strong/b 也用中等字重 */ diff --git a/packages/website/src/pages/docs/advanced/page-agent-core/page.tsx b/packages/website/src/pages/docs/advanced/page-agent-core/page.tsx index 84b16fa..ef5600f 100644 --- a/packages/website/src/pages/docs/advanced/page-agent-core/page.tsx +++ b/packages/website/src/pages/docs/advanced/page-agent-core/page.tsx @@ -159,9 +159,30 @@ const result = await agent.execute('Fill in the form with test data')`} { name: 'transformRequestBody', type: '(requestBody) => Record | undefined', - description: isZh - ? '在请求发送前转换最终 request body。可用于处理供应商特定的缓存提示或私有参数。' - : 'Transform the final request body before sending it. Useful for provider-specific cache hints or private request parameters.', + description: isZh ? ( + <> + 在请求发送前转换最终 request body。可用于处理供应商特定的缓存提示或私有参数。查看{' '} + + 主动缓存示例 + + 。 + + ) : ( + <> + Transform the final request body before sending it. Useful for provider-specific + cache hints or private request parameters. See{' '} + + prompt caching examples + + . + + ), }, { name: 'disableNamedToolChoice', @@ -181,42 +202,6 @@ const result = await agent.execute('Fill in the form with test data')`} ]} /> -

- {isZh ? 'transformRequestBody 示例' : 'transformRequestBody Example'} -

-

- {isZh - ? '如果某个供应商需要私有字段或缓存提示,可以通过 transformRequestBody 在发送前透传请求体,而不需要把供应商逻辑写进 PageAgent 内部。' - : 'If a provider needs private fields or cache hints, use transformRequestBody to tweak the request body before sending it instead of baking provider-specific logic into PageAgent.'} -

- { - const messages = requestBody.messages - if (!Array.isArray(messages)) return - - const systemMessage = messages.find( - (message) => message && typeof message === 'object' && message.role === 'system' - ) as { role: string; content?: unknown } | undefined - - if (!systemMessage || typeof systemMessage.content !== 'string') return - - systemMessage.content = [ - { - type: 'text', - text: systemMessage.content, - cache_control: { type: 'ephemeral' }, - }, - ] - }, -})`} - /> - {/* Agent Config */}

{isZh ? 'Agent 配置' : 'Agent Config'} diff --git a/packages/website/src/pages/docs/features/models/page.tsx b/packages/website/src/pages/docs/features/models/page.tsx index c1b424f..30ad436 100644 --- a/packages/website/src/pages/docs/features/models/page.tsx +++ b/packages/website/src/pages/docs/features/models/page.tsx @@ -1,4 +1,5 @@ import { Fragment } from 'react' +import { Link } from 'wouter' import CodeEditor from '@/components/CodeEditor' import { Heading } from '@/components/Heading' @@ -126,46 +127,6 @@ const pageAgent = new PageAgent({ /> -
- - {isZh ? '🔐 生产环境鉴权' : '🔐 Production Authentication'} - -

- {isZh - ? '如果你只是将它用作个人助手,可以直接连接你的 LLM 服务。' - : 'If you only use it as a personal assistant, you can connect to your LLM service directly.'} -

-

- {isZh ? ( - <> - 如果你计划将它集成到你的 Web 应用中,建议搭建一个后端代理来转发 LLM 请求,并使用{' '} - customFetch 携带 Cookie 或其他鉴权信息: - - ) : ( - <> - If you plan to integrate it into your web app, it's better to have a backend proxy for - the LLM and use customFetch to authenticate the request with cookies or - other methods: - - )} -

- - fetch(url, { ...init, credentials: 'include' }), -});`} - /> -
-

- {isZh - ? '⚠️ 永远不要把真实的 LLM API Key 提交到前端代码中' - : '⚠️ NEVER commit real LLM API keys to your frontend code'} -

-
-
-
{isZh ? '免费测试接口' : 'Free Testing API'}

@@ -215,7 +176,139 @@ LLM_MODEL_NAME="qwen3.5-plus"`}

- {isZh ? '本地运行时' : 'Local Runtimes'} + + {isZh ? '🔐 生产环境鉴权' : '🔐 Production Authentication'} + +

+ {isZh + ? '如果你只是将它用作个人助手,可以直接连接你的 LLM 服务。' + : 'If you only use it as a personal assistant, you can connect to your LLM service directly.'} +

+

+ {isZh ? ( + <> + 如果你计划将它集成到你的 Web 应用中,建议搭建一个后端代理来转发 LLM 请求,并使用{' '} + customFetch 携带 Cookie 或其他鉴权信息: + + ) : ( + <> + If you plan to integrate it into your web app, it's better to have a backend proxy for + the LLM and use customFetch to authenticate the request with cookies or + other methods: + + )} +

+ + fetch(url, { ...init, credentials: 'include' }), +});`} + /> +
+

+ {isZh + ? '⚠️ 永远不要把真实的 LLM API Key 提交到前端代码中' + : '⚠️ NEVER commit real LLM API keys to your frontend code'} +

+
+
+ +
+ {isZh ? '主动缓存' : 'Prompt Caching'} +

+ {isZh ? ( + <> + 一些 LLM 能从主动缓存中受益很多。由于各个供应商的主动缓存接口不同,推荐使用{' '} + + transformRequestBody + {' '} + 为你的模型供应商配置缓存提示。 + + ) : ( + <> + Some LLMs benefit significantly from prompt caching. Because each provider exposes + caching differently, use{' '} + + transformRequestBody + {' '} + to add provider-specific cache hints. + + )} +

+ +
+
+ + Claude + +

+ {isZh + ? 'Claude 支持全局 Automatic prompt caching。使用兼容 Claude 的代理时,只需要在请求体顶层添加 cache_control。' + : 'Claude supports global Automatic prompt caching. When using a Claude-compatible proxy, add cache_control at the top level of the request body.'} +

+ ({ + ...requestBody, + cache_control: { type: 'ephemeral' }, + }), +});`} + /> +
+
+ + {isZh ? '阿里云百炼 Qwen' : 'Alibaba Cloud Bailian Qwen'} + + { + const [systemMessage, ...restMessages] = requestBody.messages + + if (systemMessage.role !== 'system' || typeof systemMessage.content !== 'string') { + return requestBody + } + + return { + ...requestBody, + messages: [ + { + ...systemMessage, + content: [ + { + type: 'text', + text: systemMessage.content, + cache_control: { type: 'ephemeral' }, + }, + ], + }, + ...restMessages, + ], + } + }, +});`} + /> +
+
+
+ +
+ {isZh ? '本地 LLMs' : 'Local LLMs'}

{isZh ? '通过 Ollama、LM Studio 等本地 OpenAI-compatible 运行时接入 PageAgent,实现离线或局域网部署。'