@wwkit/freetoken 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +96 -0
  3. package/cli/helpers/args.js +48 -0
  4. package/cli/index.js +374 -0
  5. package/cli/pid-manager.js +87 -0
  6. package/client/index.html +25 -0
  7. package/client/public/favicon.svg +1 -0
  8. package/client/public/icons.svg +24 -0
  9. package/client/src/App.vue +136 -0
  10. package/client/src/assets/vite.svg +1 -0
  11. package/client/src/assets/vue.svg +1 -0
  12. package/client/src/components/ChatBox.vue +320 -0
  13. package/client/src/components/CheckList.vue +52 -0
  14. package/client/src/components/CodeBlock.vue +99 -0
  15. package/client/src/components/DetailBlock.vue +47 -0
  16. package/client/src/components/HelloWorld.vue +95 -0
  17. package/client/src/components/LangSwitch.vue +32 -0
  18. package/client/src/components/LinkList.vue +32 -0
  19. package/client/src/components/OsSwitch.vue +42 -0
  20. package/client/src/components/OsToggle.vue +15 -0
  21. package/client/src/components/PageHeader.vue +31 -0
  22. package/client/src/components/StepList.vue +92 -0
  23. package/client/src/composables/useClipboard.js +26 -0
  24. package/client/src/composables/useOs.js +22 -0
  25. package/client/src/data/docs/agent.js +1002 -0
  26. package/client/src/data/docs/auth.js +631 -0
  27. package/client/src/data/docs/builtin-tools.js +322 -0
  28. package/client/src/data/docs/chat.js +181 -0
  29. package/client/src/data/docs/index.js +9 -0
  30. package/client/src/data/docs/skills.js +396 -0
  31. package/client/src/data/docs/spec-conversion.js +1042 -0
  32. package/client/src/data/freeModels/bluesliu.js +97 -0
  33. package/client/src/data/freeModels/index.js +11 -0
  34. package/client/src/data/freeModels/nvidia.js +126 -0
  35. package/client/src/data/freeModels/openrouter.js +116 -0
  36. package/client/src/data/harness/claude.js +89 -0
  37. package/client/src/data/harness/codex.js +66 -0
  38. package/client/src/data/harness/dsh.js +86 -0
  39. package/client/src/data/harness/hermes.js +56 -0
  40. package/client/src/data/harness/index.js +22 -0
  41. package/client/src/data/harness/opencode.js +77 -0
  42. package/client/src/data/proxy/api-relay.js +53 -0
  43. package/client/src/data/proxy/builtin-proxy.js +54 -0
  44. package/client/src/data/proxy/cf-workers.js +67 -0
  45. package/client/src/data/proxy/ecs-forward.js +75 -0
  46. package/client/src/data/proxy/ecs-reverse.js +89 -0
  47. package/client/src/data/proxy/index.js +15 -0
  48. package/client/src/docs/claudecode.md +44 -0
  49. package/client/src/docs/codex.md +90 -0
  50. package/client/src/docs/hermesagent.md +42 -0
  51. package/client/src/docs/opencode.md +103 -0
  52. package/client/src/locales/en.js +436 -0
  53. package/client/src/locales/index.js +31 -0
  54. package/client/src/locales/zh-CN.js +461 -0
  55. package/client/src/main.js +16 -0
  56. package/client/src/router/index.js +76 -0
  57. package/client/src/style.css +15 -0
  58. package/client/src/views/AdminModelsView.vue +214 -0
  59. package/client/src/views/DocsView.vue +1604 -0
  60. package/client/src/views/FreeModelsView.vue +518 -0
  61. package/client/src/views/HarnessView.vue +314 -0
  62. package/client/src/views/HomeView.vue +147 -0
  63. package/client/src/views/ProxyView.vue +112 -0
  64. package/client/src/views/TokenMarketView.vue +26 -0
  65. package/client/vite.config.js +41 -0
  66. package/package.json +85 -0
  67. package/scripts/build-zip.sh +61 -0
  68. package/scripts/postinstall.js +7 -0
  69. package/server/src/config/targets.json +1 -0
  70. package/server/src/index.js +52 -0
  71. package/server/src/lib/coding-test.js +215 -0
  72. package/server/src/lib/database.js +353 -0
  73. package/server/src/lib/run-test.js +15 -0
  74. package/server/src/lib/scheduler.js +21 -0
  75. package/server/src/lib/tester.js +310 -0
  76. package/server/src/routes/admin.js +48 -0
  77. package/server/src/routes/proxy.js +64 -0
  78. package/server/src/routes/speed.js +87 -0
  79. package/src/config.js +45 -0
  80. package/src/config.json5 +27 -0
  81. package/src/index.js +10 -0
@@ -0,0 +1,322 @@
1
+ // opencode 内置工具的完整真实描述(直接取自 opencode 系统提示词)
2
+ // 这些 description 是模型选择工具和构造参数的核心依据
3
+
4
+ export const builtinTools = [
5
+ {
6
+ name: 'bash',
7
+ summary: '终端命令执行',
8
+ description: `Executes a given bash command in a persistent shell session with optional timeout, ensuring proper handling and security measures.
9
+
10
+ Be aware: OS: linux, Shell: bash
11
+
12
+ All commands run in the current working directory by default. Use the \`workdir\` parameter if you need to run a command in a different directory. AVOID using \`cd <directory> && <command>\` patterns - use \`workdir\` instead.
13
+
14
+ Use \`/tmp/opencode\` for temporary work outside the workspace. This directory has already been created, already exists, and is pre-approved for external directory access.
15
+
16
+ IMPORTANT: This tool is for terminal operations like git, npm, docker, etc. DO NOT use it for file operations (reading, writing, editing, searching, finding files) - use the specialized tools for this instead:
17
+ - File search: Use Glob (NOT find or ls)
18
+ - Content search: Use Grep (NOT grep or rg)
19
+ - Read files: Use Read (NOT cat/head/tail)
20
+ - Edit files: Use Edit (NOT sed/awk)
21
+ - Write files: Use Write (NOT echo >/cat <<EOF)
22
+ - Communication: Output text directly (NOT echo/printf)
23
+
24
+ When issuing multiple commands:
25
+ - If the commands are independent and can run in parallel, make multiple bash tool calls in a single message. For example, if you need to run "git status" and "git diff", send a single message with two bash tool calls in parallel.
26
+ - If the commands depend on each other and must run sequentially, use a single Bash call with '&&' to chain them together (e.g., \`git add . && git commit -m "message" && git push\`). For instance, if one operation must complete before another starts (like mkdir before cp, Write before Bash for git operations, or git add before git commit), run these operations sequentially instead.
27
+ - Use ';' only when you need to run commands sequentially but don't care if earlier commands fail
28
+ - DO NOT use newlines to separate commands (newlines are ok in quoted strings)
29
+ - AVOID using \`cd <directory> && <command>\`. Use the \`workdir\` parameter to change directories instead.
30
+
31
+ # Git and GitHub
32
+ - Only commit, amend, push, or create PRs when explicitly requested.
33
+ - Before committing, inspect \`git status\`, \`git diff\`, and \`git log --oneline -10\`; stage only intended files and never commit secrets.
34
+ - Write a concise commit message that matches the repo style.
35
+ - Do not update git config, skip hooks, use interactive \`-i\`, force-push, or create empty commits unless explicitly requested.
36
+ - If a commit fails or hooks reject it, fix the issue and create a new commit; do not amend the failed commit.
37
+ - Before creating a PR, inspect status, diff, remote tracking, recent commits, and the diff from the base branch.
38
+ - Review all commits included in the PR, not just the latest commit.
39
+ - Use \`gh\` for GitHub tasks, including PRs, issues, checks, and releases; return the PR URL when done.`,
40
+ parameters: {
41
+ type: 'object',
42
+ properties: {
43
+ command: { type: 'string', description: 'The command to execute' },
44
+ workdir: { type: 'string', description: 'The working directory to run the command in. Defaults to the current directory. Use this instead of `cd <directory> && <command>` patterns.' },
45
+ timeout: { type: 'integer', description: 'Optional timeout in milliseconds. If not specified, commands will time out after 120000ms.' },
46
+ },
47
+ required: ['command'],
48
+ },
49
+ },
50
+
51
+ {
52
+ name: 'read',
53
+ summary: '读取文件或目录',
54
+ description: `Read a file or directory from the local filesystem. If the path does not exist, an error is returned.
55
+
56
+ Usage:
57
+ - The \`filePath\` parameter should be an absolute path.
58
+ - By default, this tool returns up to 2000 lines from the start of the file.
59
+ - The \`offset\` parameter is the line number to start reading from (1-indexed).
60
+ - To read later sections, call this tool again with a larger offset.
61
+ - Use the grep tool to find specific content in large files or files with long lines.
62
+ - If you are unsure of the correct file path, use the glob tool to look up filenames by glob pattern.
63
+ - Contents are returned with each line prefixed by its line number as \`<line>: <content>\`. For example, if a file has contents "foo\\n", you will receive "1: foo\\n". For directories, entries are returned one per line (without line numbers) with a trailing \`/\` for subdirectories.
64
+ - Any line longer than 2000 characters is truncated.
65
+ - Call this tool in parallel when you know there are multiple files you want to read.
66
+ - Avoid tiny repeated slices (30 line chunks). If you need more context, read a larger window.
67
+ - This tool can read image files and PDFs and return them as file attachments.`,
68
+ parameters: {
69
+ type: 'object',
70
+ properties: {
71
+ filePath: { type: 'string', description: 'The absolute path to the file to read' },
72
+ offset: { type: 'integer', description: 'The line number to start reading from (1-indexed). To read later sections, call this tool again with a larger offset.' },
73
+ limit: { type: 'integer', description: 'The maximum number of lines to read (defaults to 2000)' },
74
+ },
75
+ required: ['filePath'],
76
+ },
77
+ },
78
+
79
+ {
80
+ name: 'write',
81
+ summary: '写入文件',
82
+ description: `Writes a file to the local filesystem.
83
+
84
+ Usage:
85
+ - This tool will overwrite the existing file if there is one at the provided path.
86
+ - If this is an existing file, you MUST use the Read tool first to read the file's contents. This tool will fail if you did not read the file first.
87
+ - ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.
88
+ - NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.
89
+ - Only use emojis if the user explicitly requests it. Avoid writing emojis to files unless asked.`,
90
+ parameters: {
91
+ type: 'object',
92
+ properties: {
93
+ filePath: { type: 'string', description: 'The absolute path to the file to write (must be absolute, not relative)' },
94
+ content: { type: 'string', description: 'The content to write to the file' },
95
+ },
96
+ required: ['filePath', 'content'],
97
+ },
98
+ },
99
+
100
+ {
101
+ name: 'edit',
102
+ summary: '精确字符串替换编辑',
103
+ description: `Performs exact string replacements in files.
104
+
105
+ Usage:
106
+ - You must use your \`Read\` tool at least once in the conversation before editing. This tool will error if you attempt an edit without reading the file.
107
+ - When editing text from Read tool output, ensure you preserve the exact indentation (tabs/spaces) as it appears AFTER the line number prefix. The line number prefix format is: line number + colon + space (e.g., \`1: \`). Everything after that space is the actual file content to match. Never include any part of the line number prefix in the oldString or newString.
108
+ - ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.
109
+ - Only use emojis if the user explicitly requests it. Avoid adding emojis to files unless asked.
110
+ - The edit will FAIL if \`oldString\` is not found in the file with an error "oldString not found in content".
111
+ - The edit will FAIL if \`oldString\` is found multiple times in the file with an error "Found multiple matches for oldString. Provide more surrounding lines in oldString to identify the correct match." Either provide a larger string with more surrounding context to make it unique or use \`replaceAll\` to change every instance of oldString.
112
+ - Use \`replaceAll\` for replacing and renaming strings across the file. This parameter is useful if you want to rename a variable for instance.`,
113
+ parameters: {
114
+ type: 'object',
115
+ properties: {
116
+ filePath: { type: 'string', description: 'The absolute path to the file to modify' },
117
+ oldString: { type: 'string', description: 'The text to replace (must be different from newString)' },
118
+ newString: { type: 'string', description: 'The text to replace it with (must be different from oldString)' },
119
+ replaceAll: { type: 'boolean', description: 'Replace all occurrences of oldString (default false)' },
120
+ },
121
+ required: ['filePath', 'oldString', 'newString'],
122
+ },
123
+ },
124
+
125
+ {
126
+ name: 'glob',
127
+ summary: '文件名模式匹配',
128
+ description: `- Fast file pattern matching tool that works with any codebase size
129
+ - Supports glob patterns like "**/*.js" or "src/**/*.ts"
130
+ - Returns matching file paths
131
+ - Use this tool when you need to find files by name patterns
132
+ - When you are doing an open-ended search that may require multiple rounds of globbing and grepping, use the Task tool instead
133
+ - You have the capability to call multiple tools in a single response. It is always better to speculatively perform multiple searches as a batch that are potentially useful.`,
134
+ parameters: {
135
+ type: 'object',
136
+ properties: {
137
+ pattern: { type: 'string', description: 'The glob pattern to match files against' },
138
+ path: { type: 'string', description: 'The directory to search in. If not specified, the current working directory will be used. IMPORTANT: Omit this field to use the default behavior. DO NOT enter "undefined" or "null" - simply omit it for the default behavior. Must be a valid directory path if provided.' },
139
+ },
140
+ required: ['pattern'],
141
+ },
142
+ },
143
+
144
+ {
145
+ name: 'grep',
146
+ summary: '文件内容正则搜索',
147
+ description: `- Fast content search tool that works with any codebase size
148
+ - Searches file contents using regular expressions
149
+ - Supports full regex syntax (eg. "log.*Error", "function\\s+\\w+", etc.)
150
+ - Filter files by pattern with the include parameter (eg. "*.js", "*.{ts,tsx}")
151
+ - Returns file paths and line numbers with matching lines
152
+ - Use this tool when you need to find files containing specific patterns
153
+ - If you need to identify/count the number of matches within files, use the Bash tool with \`rg\` (ripgrep) directly. Do NOT use \`grep\`
154
+ - When you are doing an open-ended search that may require multiple rounds of globbing and grepping, use the Task tool instead`,
155
+ parameters: {
156
+ type: 'object',
157
+ properties: {
158
+ pattern: { type: 'string', description: 'The regex pattern to search for in file contents' },
159
+ path: { type: 'string', description: 'The directory to search in. Defaults to the current directory.' },
160
+ include: { type: 'string', description: 'File pattern to include in the search (e.g., "*.js", "*.{ts,tsx}")' },
161
+ },
162
+ required: ['pattern'],
163
+ },
164
+ },
165
+
166
+ {
167
+ name: 'lsp',
168
+ summary: '语言服务器协议交互',
169
+ description: `Interact with Language Server Protocol (LSP) servers to get code intelligence features.
170
+
171
+ Supported operations:
172
+ - goToDefinition: Find where a symbol is defined
173
+ - findReferences: Find all references to a symbol
174
+ - hover: Get hover information (documentation, type info) for a symbol
175
+ - documentSymbol: Get all symbols (functions, classes, variables) in a document
176
+ - workspaceSymbol: List project-wide symbols matching a query string
177
+ - goToImplementation: Find implementations of an interface or abstract method
178
+ - prepareCallHierarchy: Get call hierarchy item at a position (functions/methods)
179
+ - incomingCalls: Find all functions/methods that call the function at a position
180
+ - outgoingCalls: Find all functions/methods called by the function at a position
181
+
182
+ All operations require:
183
+ - filePath: The file to operate on
184
+ - line: The line number (1-based, as shown in editors)
185
+ - character: The character offset (1-based, as shown in editors)
186
+
187
+ workspaceSymbol also accepts:
188
+ - query: A query string to filter symbols by. Empty string requests all symbols.
189
+
190
+ For workspaceSymbol, filePath is not sent in the LSP workspace/symbol request. It is used by opencode to select and start the matching LSP server.
191
+
192
+ Note: LSP servers must be configured for the file type. If no server is available, an error will be returned.`,
193
+ parameters: {
194
+ type: 'object',
195
+ properties: {
196
+ operation: { type: 'string', description: 'The LSP operation to perform', enum: ['goToDefinition', 'findReferences', 'hover', 'documentSymbol', 'workspaceSymbol', 'goToImplementation', 'prepareCallHierarchy', 'incomingCalls', 'outgoingCalls'] },
197
+ filePath: { type: 'string', description: 'The absolute or relative path to the file' },
198
+ line: { type: 'integer', description: 'The line number (1-based, as shown in editors)' },
199
+ character: { type: 'integer', description: 'The character offset (1-based, as shown in editors)' },
200
+ query: { type: 'string', description: 'Search query for workspaceSymbol. Empty string requests all symbols.' },
201
+ },
202
+ required: ['operation', 'filePath', 'line', 'character'],
203
+ },
204
+ },
205
+
206
+ {
207
+ name: 'todowrite',
208
+ summary: '任务清单管理',
209
+ description: `Create and maintain a structured task list for the current coding session. Tracks progress, organizes multi-step work, and surfaces status to the user.
210
+
211
+ ## When to use
212
+ Use proactively when:
213
+ - The task requires 3+ distinct steps or actions (not just 3 tool calls for a single conceptual step)
214
+ - The work is non-trivial and benefits from planning
215
+ - The user provides multiple tasks (numbered or comma-separated) or explicitly asks for a todo list
216
+ - New instructions arrive - capture them as todos
217
+ - You start a task - mark it \`in_progress\` (only one at a time) before working
218
+ - You finish a task - mark it \`completed\` and add any follow-ups discovered during the work
219
+
220
+ ## When NOT to use
221
+ Skip when:
222
+ - The work is a single, straightforward task (or <3 trivial steps)
223
+ - The request is purely informational or conversational
224
+ - Tracking adds no organizational value
225
+
226
+ ## States
227
+ - \`pending\` - not started
228
+ - \`in_progress\` - actively working (exactly ONE at a time)
229
+ - \`completed\` - finished successfully
230
+ - \`cancelled\` - no longer needed
231
+
232
+ ## Rules
233
+ - Update status in real time; don't batch completions
234
+ - Mark \`completed\` only after the required work is actually done, including any required verification. Never based on intent.
235
+ - Keep exactly one \`in_progress\` while work remains
236
+ - If blocked or partial, keep it \`in_progress\` and add a follow-up todo describing the blocker
237
+ - Preserve user-provided commands verbatim (flags, args, order)
238
+ - Items should be specific and actionable; break large work into smaller steps`,
239
+ parameters: {
240
+ type: 'object',
241
+ properties: {
242
+ todos: {
243
+ type: 'array',
244
+ description: 'The updated todo list',
245
+ items: {
246
+ type: 'object',
247
+ properties: {
248
+ content: { type: 'string', description: 'Brief description of the task' },
249
+ status: { type: 'string', enum: ['pending', 'in_progress', 'completed', 'cancelled'], description: 'Current status of the task' },
250
+ priority: { type: 'string', enum: ['high', 'medium', 'low'], description: 'Priority level of the task' },
251
+ },
252
+ required: ['content', 'status', 'priority'],
253
+ },
254
+ },
255
+ },
256
+ required: ['todos'],
257
+ },
258
+ },
259
+
260
+ {
261
+ name: 'task',
262
+ summary: '启动子 Agent',
263
+ description: `Launch a new agent to handle complex, multistep tasks autonomously.
264
+
265
+ When using the Task tool, you must specify a subagent_type parameter to select which agent type to use.
266
+
267
+ When NOT to use the Task tool:
268
+ - If you want to read a specific file path, use the Read or Glob tool instead of the Task tool, to find the match more quickly
269
+ - If you are searching for a specific class definition like "class Foo", use the Grep tool instead, to find the match more quickly
270
+ - If you are searching for code within a specific file or set of 2-3 files, use the Read tool instead of the Task tool, to find the match more quickly
271
+ - If no available agent is a good fit for the task, use other tools directly
272
+
273
+ Usage notes:
274
+ 1. Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses
275
+ 2. Once you have delegated work to an agent, do not duplicate that work yourself. Continue with non-overlapping tasks, or wait for the result.
276
+ 3. When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.
277
+ 4. Each agent invocation starts with a fresh context unless you provide task_id to resume the same subagent session.
278
+ 5. The agent's outputs should generally be trusted
279
+ 6. Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent. Tell it how to verify its work if possible.`,
280
+ parameters: {
281
+ type: 'object',
282
+ properties: {
283
+ description: { type: 'string', description: 'A short (3-5 words) description of the task' },
284
+ prompt: { type: 'string', description: 'The task for the agent to perform' },
285
+ subagent_type: { type: 'string', description: 'The type of specialized agent to use for this task' },
286
+ task_id: { type: 'string', description: 'This should only be set if you mean to resume a previous task' },
287
+ command: { type: 'string', description: 'The command that triggered this task' },
288
+ },
289
+ required: ['description', 'prompt', 'subagent_type'],
290
+ },
291
+ },
292
+
293
+ {
294
+ name: 'webfetch',
295
+ summary: '网页内容抓取',
296
+ description: `Fetches content from a specified URL
297
+
298
+ - Takes a URL and optional format as input
299
+ - Fetches the URL content, converts to requested format (markdown by default)
300
+ - Returns the content in the specified format
301
+ - Use this tool when you need to retrieve and analyze web content
302
+
303
+ Usage notes:
304
+ - IMPORTANT: if another tool is present that offers better web fetching capabilities, is more targeted to the task, or has fewer restrictions, prefer using that tool instead of this one.
305
+ - The URL must be a fully-formed valid URL
306
+ - HTTP URLs will be automatically upgraded to HTTPS
307
+ - Format options: "markdown" (default), "text", or "html"
308
+ - This tool is read-only and does not modify any files
309
+ - Results may be summarized if the content is very large`,
310
+ parameters: {
311
+ type: 'object',
312
+ properties: {
313
+ url: { type: 'string', description: 'The URL to fetch content from' },
314
+ format: { type: 'string', enum: ['text', 'markdown', 'html'], description: 'The format to return the content in (defaults to markdown)' },
315
+ timeout: { type: 'number', description: 'Optional timeout in seconds (max 120)' },
316
+ },
317
+ required: ['url'],
318
+ },
319
+ },
320
+ ]
321
+
322
+ export default builtinTools
@@ -0,0 +1,181 @@
1
+ // Chat 子模块:LLM Chat Completions 接口详解
2
+ export default {
3
+ id: 'chat',
4
+ name: 'Chat',
5
+ badge: 'LLM 接口',
6
+ tagline: '大语言模型 Chat Completions 接口详解',
7
+ description:
8
+ 'OpenAI 兼容的 Chat Completions 接口是大语言模型最核心的 API。本节展示非流式和流式两种调用方式的完整请求与响应格式,以及核心参数说明。',
9
+
10
+ sections: [
11
+ // ── 非流式 ──
12
+ {
13
+ id: 'non-streaming',
14
+ title: '非流式请求',
15
+ description:
16
+ '一次性发送完整请求,等待模型生成完毕后返回完整响应。适合后台批处理、不需要实时展示生成过程的场景。',
17
+ request: `POST /v1/chat/completions
18
+ Content-Type: application/json
19
+ Authorization: Bearer sk-xxx
20
+
21
+ {
22
+ "model": "maas-glm-5.1-zhipu",
23
+ "messages": [
24
+ {
25
+ "role": "system",
26
+ "content": "你是一个专业的编程助手。"
27
+ },
28
+ {
29
+ "role": "user",
30
+ "content": "用 JavaScript 写一个冒泡排序函数。"
31
+ }
32
+ ],
33
+ "temperature": 0.7,
34
+ "max_tokens": 1024
35
+ }`,
36
+ response: `{
37
+ "id": "chatcmpl-9b8c2a3f4e5d6a7b8c9d0e1f2",
38
+ "object": "chat.completion",
39
+ "created": 1716900000,
40
+ "model": "maas-glm-5.1-zhipu",
41
+ "choices": [
42
+ {
43
+ "index": 0,
44
+ "message": {
45
+ "role": "assistant",
46
+ "content": "function bubbleSort(arr) {\\n const n = arr.length;\\n for (let i = 0; i < n - 1; i++) {\\n for (let j = 0; j < n - 1 - i; j++) {\\n if (arr[j] > arr[j + 1]) {\\n [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];\\n }\\n }\\n }\\n return arr;\\n}"
47
+ },
48
+ "finish_reason": "stop"
49
+ }
50
+ ],
51
+ "usage": {
52
+ "prompt_tokens": 28,
53
+ "completion_tokens": 112,
54
+ "total_tokens": 140
55
+ }
56
+ }`,
57
+ notes: [
58
+ '响应是完整的 JSON 对象,choices[0].message.content 包含完整生成内容',
59
+ 'finish_reason 为 "stop" 表示模型自然结束,"length" 表示达到 max_tokens 截断',
60
+ 'usage 字段包含本次调用的 token 统计,用于成本核算',
61
+ ],
62
+ },
63
+
64
+ // ── 流式 ──
65
+ {
66
+ id: 'streaming',
67
+ title: '流式请求',
68
+ description:
69
+ '设置 stream: true 后,服务器以 Server-Sent Events (SSE) 方式逐块返回内容。前端可实时渲染打字机效果,大幅提升用户体验。',
70
+ request: `POST /v1/chat/completions
71
+ Content-Type: application/json
72
+ Authorization: Bearer sk-xxx
73
+
74
+ {
75
+ "model": "maas-glm-5.1-zhipu",
76
+ "messages": [
77
+ {
78
+ "role": "system",
79
+ "content": "你是一个专业的编程助手。"
80
+ },
81
+ {
82
+ "role": "user",
83
+ "content": "用 JavaScript 写一个冒泡排序函数。"
84
+ }
85
+ ],
86
+ "temperature": 0.7,
87
+ "max_tokens": 1024,
88
+ "stream": true
89
+ }`,
90
+ response: `data: {"id":"chatcmpl-9b8c2a3f","object":"chat.completion.chunk","created":1716900000,"model":"maas-glm-5.1-zhipu","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}
91
+
92
+ data: {"id":"chatcmpl-9b8c2a3f","object":"chat.completion.chunk","created":1716900000,"model":"maas-glm-5.1-zhipu","choices":[{"index":0,"delta":{"content":"function"},"finish_reason":null}]}
93
+
94
+ data: {"id":"chatcmpl-9b8c2a3f","object":"chat.completion.chunk","created":1716900000,"model":"maas-glm-5.1-zhipu","choices":[{"index":0,"delta":{"content":" bubbleSort"},"finish_reason":null}]}
95
+
96
+ data: {"id":"chatcmpl-9b8c2a3f","object":"chat.completion.chunk","created":1716900000,"model":"maas-glm-5.1-zhipu","choices":[{"index":0,"delta":{"content":"(arr) {\\n"},"finish_reason":null}]}
97
+
98
+ data: {"id":"chatcmpl-9b8c2a3f","object":"chat.completion.chunk","created":1716900000,"model":"maas-glm-5.1-zhipu","choices":[{"index":0,"delta":{"content":" const n = arr.length;\\n"},"finish_reason":null}]}
99
+
100
+ data: {"id":"chatcmpl-9b8c2a3f","object":"chat.completion.chunk","created":1716900000,"model":"maas-glm-5.1-zhipu","choices":[{"index":0,"delta":{"content":" // ... 后续内容逐块返回"},"finish_reason":null}]}
101
+
102
+ data: {"id":"chatcmpl-9b8c2a3f","object":"chat.completion.chunk","created":1716900000,"model":"maas-glm-5.1-zhipu","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
103
+
104
+ data: {"id":"chatcmpl-9b8c2a3f","object":"chat.completion.chunk","created":1716900000,"model":"maas-glm-5.1-zhipu","choices":[],"usage":{"prompt_tokens":28,"completion_tokens":112,"total_tokens":140}}
105
+
106
+ data: [DONE]`,
107
+ notes: [
108
+ '每个 chunk 的 choices[0].delta.content 是增量文本片段,需在前端拼接',
109
+ '首个 chunk 的 delta 含 role 字段,后续 chunk 只有 content',
110
+ 'finish_reason 出现在最后一个有内容的 chunk 上,值为 "stop"',
111
+ '最后一行 data: [DONE] 标记流结束,客户端应关闭连接',
112
+ 'stream 模式下 usage 通常在最后一个 chunk(choices 为空数组时)返回',
113
+ ],
114
+ },
115
+
116
+ // ── 核心参数 ──
117
+ {
118
+ id: 'parameters',
119
+ title: '核心参数',
120
+ description: 'Chat Completions 接口的关键请求参数说明。',
121
+ params: [
122
+ {
123
+ name: 'model',
124
+ type: 'string',
125
+ required: true,
126
+ description: '模型 ID,如 maas-glm-5.1-zhipu、gpt-4o、claude-3-sonnet',
127
+ },
128
+ {
129
+ name: 'messages',
130
+ type: 'array',
131
+ required: true,
132
+ description:
133
+ '对话消息数组,每个元素含 role(system/user/assistant/tool)和 content',
134
+ },
135
+ {
136
+ name: 'temperature',
137
+ type: 'number',
138
+ required: false,
139
+ description: '采样温度 0~2,值越高输出越随机多样,0 最确定。默认 1',
140
+ },
141
+ {
142
+ name: 'max_tokens',
143
+ type: 'integer',
144
+ required: false,
145
+ description: '生成最大 token 数,控制响应长度上限。默认模型上限',
146
+ },
147
+ {
148
+ name: 'stream',
149
+ type: 'boolean',
150
+ required: false,
151
+ description: '是否流式返回。true 时以 SSE 逐块返回,false 一次性返回。默认 false',
152
+ },
153
+ {
154
+ name: 'tools',
155
+ type: 'array',
156
+ required: false,
157
+ description: '工具定义数组,启用 Function Calling / Agent 模式。详见 Agent 子模块',
158
+ },
159
+ {
160
+ name: 'tool_choice',
161
+ type: 'string',
162
+ required: false,
163
+ description:
164
+ '工具选择策略:"auto"(模型自主决定)、"none"(不调用)、"required"(必须调用)、指定工具名',
165
+ },
166
+ {
167
+ name: 'top_p',
168
+ type: 'number',
169
+ required: false,
170
+ description: '核采样概率 0~1,只从累积概率达 top_p 的 token 中采样。默认 1',
171
+ },
172
+ {
173
+ name: 'stop',
174
+ type: 'string/array',
175
+ required: false,
176
+ description: '停止序列,生成中出现这些字符串时立即停止',
177
+ },
178
+ ],
179
+ },
180
+ ],
181
+ }
@@ -0,0 +1,9 @@
1
+ import chat from './chat.js'
2
+ import agent from './agent.js'
3
+ import specConversion from './spec-conversion.js'
4
+ import auth from './auth.js'
5
+ import skills from './skills.js'
6
+
7
+ export const docsModules = [chat, agent, specConversion, auth, skills]
8
+
9
+ export default docsModules