feat(plugins): raise AI output request ceiling to 32768

This commit is contained in:
tianma-if committed 2026-09-25 00:03:38 +08:00
1 parent b004d57263
commit 41d827e58a
4 files changed
+15 -3

No files matched your search

@@ -68,6 +68,18 @@ test('generic AI validates ordinary prompts, returns text, and redacts provider
const response = await failed('ai/generate', { system: '', prompt: 'hello' }); expect(response.status).toBe(502); expect(await response.text()).not.toContain('dummy-provider-secret');
});
test('generic AI accepts the larger output ceiling and rejects requests above it', async () => {
const call = fixture({
generate: async input => ({ text: String(input.maxOutputTokens) }),
loadCredentials: async () => ({ provider: 'openai-compatible', baseUrl: 'https://api.example/v1', apiKey: 'plugin-key', modelId: 'model-a' }),
});
const input = { system: '', prompt: 'hello', maxOutputTokens: 32768 };
expect(await (await call('ai/generate', input)).json()).toEqual({ text: '32768' });
expect((await call('ai/generate/prepare', input)).status).toBe(200);
expect((await call('ai/generate', { ...input, maxOutputTokens: 32769 })).status).toBe(400);
expect((await call('ai/generate/prepare', { ...input, maxOutputTokens: 32769 })).status).toBe(400);
});
test('concurrent requests are bounded and released after completion', async () => {
let started = 0; let release; const gate = new Promise(resolve => { release = resolve; });
const call = fixture({ fetch: async () => { started++; await gate; return new Response('ok'); } });
+1 -1
View File
@@ -598,7 +598,7 @@ const result = await context.ai.generate({
});
```
`system` is limited to 8,000 characters, `prompt` to 90,000, output to 5,000 tokens, and generation to 120 seconds. The backend requires an interactive user session, disables AI in public demo mode, and redacts provider errors. AI calls have a four-request per-workspace guard in each backend instance; this is not a distributed quota. Model charges follow the configured provider. Plugin deactivation aborts outstanding calls.
`system` is limited to 8,000 characters, `prompt` to 90,000, and requested output to 32,768 tokens; omitted `maxOutputTokens` defaults to 3,000. Generation is limited to 120 seconds. The model or provider may impose a lower limit or reject a request based on available credits. The backend requires an interactive user session, disables AI in public demo mode, and redacts provider errors. AI calls have a four-request per-workspace guard in each backend instance; this is not a distributed quota. Model charges follow the configured provider. Plugin deactivation aborts outstanding calls.
The default `network.fetch(url, init)` transport is a trusted browser request. It accepts arbitrary HTTP/HTTPS destinations, methods, bodies, request headers such as `Authorization`, and the requested browser credential mode. It remains subject to the runtime browser's CORS and cookie policy. `networkHosts` is legacy descriptive metadata and is not a security boundary. To read a cross-origin public feed or API without credentials, explicitly select `transport: "public"`; listing `network` and `network:public` remains useful disclosure but is optional.
+1 -1
View File
@@ -598,7 +598,7 @@ const result = await context.ai.generate({
});
```
`system` 最多 8,000 字符,`prompt` 最多 90,000 字符,输出最多 5,000 token,生成最长 120 秒。后端要求交互式用户会话,公开演示模式禁用 AI,供应商错误脱敏。每个后端实例对每工作区的 AI 调用设置四路并发保护,不是分布式配额。模型费用沿用已配置供应商的计费;停用插件会中止其调用。
`system` 最多 8,000 字符,`prompt` 最多 90,000 字符,请求的输出上限最多 32,768 token;省略 `maxOutputTokens` 时默认 3,000。生成最长 120 秒。模型或供应商可能有更低的限制,也可能因可用额度不足拒绝请求。后端要求交互式用户会话,公开演示模式禁用 AI,供应商错误脱敏。每个后端实例对每工作区的 AI 调用设置四路并发保护,不是分布式配额。模型费用沿用已配置供应商的计费;停用插件会中止其调用。
默认的 `network.fetch(url, init)` 是受信任的浏览器请求,可以访问任意 HTTP/HTTPS 地址,使用任意方法、正文、`Authorization` 等请求头以及调用方指定的浏览器凭据模式;它仍受所在运行时的 CORS 与 Cookie 策略约束。`networkHosts` 仅为兼容旧版保留,不是安全边界。需要无凭据读取跨域公开订阅或 API 时,显式选择 `transport: "public"` 即可;列出 `network` 和 `network:public` 仍有助于披露用途,但不是必需条件:
+1 -1
View File
@@ -3,7 +3,7 @@ import { z } from 'zod';
export const PluginAiGenerateSchema = z.object({
system: z.string().max(8000),
prompt: z.string().min(1).max(90000),
maxOutputTokens: z.number().int().min(1).max(5000).optional(),
maxOutputTokens: z.number().int().min(1).max(32768).optional(),
}).strict();
export type PluginAiGenerateRequest = z.infer<typeof PluginAiGenerateSchema>;
export interface PluginAiStatus { configured: boolean; modelName?: string }