feat(llm): remove the V4 Flash and V4 Flash Vision Exp defaults
The shipped DeepSeek catalog keeps V41 Flash and V4 Pro only; the removed ids still pass through as text-only routes when configured explicitly. Updates the adapter tests, the Web settings goldens that render the default catalog, and the regenerated config catalog.
This commit is contained in:
1 parent
2bc7697265
commit
f2beb99c3b
16 files changed
+32
-108
No files matched your search
@@ -49,34 +49,14 @@
|
||||
- img
|
||||
- textbox "模型 ID 2":
|
||||
- /placeholder: 模型 ID
|
||||
- text: deepseek-v4-flash
|
||||
- text: deepseek-v4-pro
|
||||
- textbox "显示名称 2":
|
||||
- /placeholder: 显示名称
|
||||
- text: DeepSeek-V4-Flash
|
||||
- text: DeepSeek-V4-Pro
|
||||
- button "模型选项 2":
|
||||
- img
|
||||
- button "删除模型 2":
|
||||
- img
|
||||
- textbox "模型 ID 3":
|
||||
- /placeholder: 模型 ID
|
||||
- text: deepseek-v4-pro
|
||||
- textbox "显示名称 3":
|
||||
- /placeholder: 显示名称
|
||||
- text: DeepSeek-V4-Pro
|
||||
- button "模型选项 3":
|
||||
- img
|
||||
- button "删除模型 3":
|
||||
- img
|
||||
- textbox "模型 ID 4":
|
||||
- /placeholder: 模型 ID
|
||||
- text: deepseek-v4-flash-vision-exp
|
||||
- textbox "显示名称 4":
|
||||
- /placeholder: 显示名称
|
||||
- text: DeepSeek-V4-Flash-Vision-Exp
|
||||
- button "模型选项 4":
|
||||
- img
|
||||
- button "删除模型 4":
|
||||
- img
|
||||
- button "添加模型":
|
||||
- img
|
||||
- text: 添加模型
|
||||
|
||||
@@ -4,6 +4,4 @@
|
||||
- menuitemradio "Messages Flash" [checked]:
|
||||
- text: Messages Flash
|
||||
- img
|
||||
- menuitemradio "DeepSeek-V4-Flash"
|
||||
- menuitemradio "DeepSeek-V4-Pro"
|
||||
- menuitemradio "DeepSeek-V4-Flash-Vision-Exp"
|
||||
@@ -61,34 +61,14 @@
|
||||
- option "不支持"
|
||||
- textbox "模型 ID 2":
|
||||
- /placeholder: 模型 ID
|
||||
- text: deepseek-v4-flash
|
||||
- text: deepseek-v4-pro
|
||||
- textbox "显示名称 2":
|
||||
- /placeholder: 显示名称
|
||||
- text: DeepSeek-V4-Flash
|
||||
- text: DeepSeek-V4-Pro
|
||||
- button "模型选项 2":
|
||||
- img
|
||||
- button "删除模型 2":
|
||||
- img
|
||||
- textbox "模型 ID 3":
|
||||
- /placeholder: 模型 ID
|
||||
- text: deepseek-v4-pro
|
||||
- textbox "显示名称 3":
|
||||
- /placeholder: 显示名称
|
||||
- text: DeepSeek-V4-Pro
|
||||
- button "模型选项 3":
|
||||
- img
|
||||
- button "删除模型 3":
|
||||
- img
|
||||
- textbox "模型 ID 4":
|
||||
- /placeholder: 模型 ID
|
||||
- text: deepseek-v4-flash-vision-exp
|
||||
- textbox "显示名称 4":
|
||||
- /placeholder: 显示名称
|
||||
- text: DeepSeek-V4-Flash-Vision-Exp
|
||||
- button "模型选项 4":
|
||||
- img
|
||||
- button "删除模型 4":
|
||||
- img
|
||||
- button "添加模型":
|
||||
- img
|
||||
- text: 添加模型
|
||||
|
||||
@@ -205,10 +205,8 @@ describe.skipIf(MODE === 'record')('web e2e: first-run DeepSeek credential setup
|
||||
await settings.getByText('自定义设置').click()
|
||||
expect(await settings.getByLabel('模型 ID 1').inputValue()).toBe('deepseek-flash')
|
||||
expect(await settings.getByLabel('显示名称 1').inputValue()).toBe('DeepSeek-V41-Flash')
|
||||
expect(await settings.getByLabel('模型 ID 2').inputValue()).toBe('deepseek-v4-flash')
|
||||
expect(await settings.getByLabel('模型 ID 3').inputValue()).toBe('deepseek-v4-pro')
|
||||
expect(await settings.getByLabel('模型 ID 4').inputValue()).toBe('deepseek-v4-flash-vision-exp')
|
||||
expect(await settings.getByRole('button', { name: /删除模型/ }).count()).toBe(4)
|
||||
expect(await settings.getByLabel('模型 ID 2').inputValue()).toBe('deepseek-v4-pro')
|
||||
expect(await settings.getByRole('button', { name: /删除模型/ }).count()).toBe(2)
|
||||
await settings.getByRole('button', { name: '模型选项 1' }).click()
|
||||
expect(await settings.getByLabel('图片输入 1').inputValue()).toBe('enabled')
|
||||
const defaultModels = await captureStableAria(page, '[role="dialog"]', scaffold.workspaceCwd)
|
||||
@@ -225,12 +223,12 @@ describe.skipIf(MODE === 'record')('web e2e: first-run DeepSeek credential setup
|
||||
await expect(scaffold.ctx.llm.resolveModelInfo('deepseek-official', 'deepseek-flash')).resolves.toMatchObject({
|
||||
name: 'Configured Flash', inputModalities: ['text'], systemPromptUpdate: 'in-history',
|
||||
})
|
||||
await expect(scaffold.ctx.llm.resolveModelInfo('deepseek-official', 'deepseek-v4-flash-vision-exp')).resolves.toMatchObject({
|
||||
inputModalities: ['text', 'image'],
|
||||
await expect(scaffold.ctx.llm.resolveModelInfo('deepseek-official', 'deepseek-v4-pro')).resolves.toMatchObject({
|
||||
name: 'DeepSeek-V4-Pro', inputModalities: ['text'],
|
||||
})
|
||||
await deepSeek.locator('xpath=ancestor::li').getByRole('button', { name: '编辑' }).click()
|
||||
await settings.getByText('自定义设置').click()
|
||||
for (let index = 0; index < 4; index++) {
|
||||
for (let index = 0; index < 2; index++) {
|
||||
await settings.getByRole('button', { name: /删除模型/ }).first().click()
|
||||
}
|
||||
await settings.getByRole('button', { name: '添加模型' }).click()
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/config-catalog.md
|
||||
config-catalog.md: ba691e83e0e81bf608f090c56cca6b797074116b
|
||||
config-catalog.zh.md: 78d39e6e85329d797699b0a6e9e151e13d48fa5e
|
||||
config-catalog.md: 57cb0c6b5db3177dfd4a777448cbd726a8e0957c
|
||||
config-catalog.zh.md: b34da72c2f3496748073171aa0dd3cceefb019bc
|
||||
@@ -1150,7 +1150,7 @@ export interface Config {
|
||||
maxTokens?: number
|
||||
/** Positive context capacity used when the selected model has no exact value (default 1,000,000). */
|
||||
defaultContextWindow?: number
|
||||
/** Advisory models shown by discovery consumers; defaults to V41 Flash, V4 Flash, V4 Pro, and V4 Flash Vision Exp. */
|
||||
/** Advisory models shown by discovery consumers; defaults to V41 Flash and V4 Pro. */
|
||||
models?: DeepSeekCatalogModel[]
|
||||
/** Maximum provider idle time while one stream read is outstanding (default five minutes). */
|
||||
streamIdleTimeoutMs?: number
|
||||
|
||||
@@ -1152,7 +1152,7 @@ export interface Config {
|
||||
maxTokens?: number
|
||||
/** Positive context capacity used when the selected model has no exact value (default 1,000,000). */
|
||||
defaultContextWindow?: number
|
||||
/** Advisory models shown by discovery consumers; defaults to V41 Flash, V4 Flash, V4 Pro, and V4 Flash Vision Exp. */
|
||||
/** Advisory models shown by discovery consumers; defaults to V41 Flash and V4 Pro. */
|
||||
models?: DeepSeekCatalogModel[]
|
||||
/** Maximum provider idle time while one stream read is outstanding (default five minutes). */
|
||||
streamIdleTimeoutMs?: number
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/llm/llm-deepseek/README.md
|
||||
README.md: 6121a19003a628204bfb5f8a3d6b5d969bd19104
|
||||
README.zh.md: 69e5c103e0edd8d16f606ed11a7aaf602ff5944e
|
||||
README.md: f332d59b0fe63e5129e5205fbba1ab1901b34d7f
|
||||
README.zh.md: 26ce84e2497c637cbfe42bbbaf72fc07f27c3e82
|
||||
@@ -45,7 +45,7 @@ Choose this adapter for DeepSeek's official API or a gateway that supports the s
|
||||
filesApiTimeoutMs: 60000
|
||||
```
|
||||
|
||||
A request selects the route with `provider: deepseek-official`; the model id passes through to the wire, so new DeepSeek models need no re-registration. Omitted `models` advertises the text- and image-capable `deepseek-flash` and `deepseek-v4-flash-vision-exp` alongside the text-only `deepseek-v4-flash` and `deepseek-v4-pro`, each with a 1,000,000-token context window. An explicit list replaces those defaults, and unlisted model ids still pass through as text-only routes. Clients, including model discovery tools, can read the advisory entries through `ctx.llm.listModels('deepseek-official')`. Image-capable entries may set `imagePixelBudget` to a positive integer or `low`, and may set `imageMaxBytes`. An entry may declare `systemPromptUpdate: in-history` when its endpoint reads the latest `system` message at any position of `messages` as the complete effective system prompt; the adapter reports the mode on the resolved model and the prepared call, and the agent loop then appends a changed prompt after the cached history instead of rewriting the leading system message ([decision rule](../../core/agent-loop/README.md#understand-the-implementation)). The default `deepseek-flash` entry declares this mode; other models require an explicit `models` declaration, and any value other than `in-history` fails at load with `llm-deepseek: catalog model "<id>" systemPromptUpdate must be "in-history" when present`.
|
||||
A request selects the route with `provider: deepseek-official`; the model id passes through to the wire, so new DeepSeek models need no re-registration. Omitted `models` advertises the text- and image-capable `deepseek-flash` alongside the text-only `deepseek-v4-pro`, each with a 1,000,000-token context window. An explicit list replaces those defaults, and unlisted model ids still pass through as text-only routes. Clients, including model discovery tools, can read the advisory entries through `ctx.llm.listModels('deepseek-official')`. Image-capable entries may set `imagePixelBudget` to a positive integer or `low`, and may set `imageMaxBytes`. An entry may declare `systemPromptUpdate: in-history` when its endpoint reads the latest `system` message at any position of `messages` as the complete effective system prompt; the adapter reports the mode on the resolved model and the prepared call, and the agent loop then appends a changed prompt after the cached history instead of rewriting the leading system message ([decision rule](../../core/agent-loop/README.md#understand-the-implementation)). The default `deepseek-flash` entry declares this mode; other models require an explicit `models` declaration, and any value other than `in-history` fails at load with `llm-deepseek: catalog model "<id>" systemPromptUpdate must be "in-history" when present`.
|
||||
|
||||
| Field | Default | Meaning |
|
||||
|---|---|---|
|
||||
@@ -56,7 +56,7 @@ A request selects the route with `provider: deepseek-official`; the model id pas
|
||||
| `reasoningEffort` | `high` | Default effort: `off`, `low`, `high`, or `max` |
|
||||
| `maxTokens` | `256,000` | Per-request output cap; a model's own cap and explicit request values win |
|
||||
| `defaultContextWindow` | `1,000,000` | Capacity fallback for models without an exact value |
|
||||
| `models` | V41 Flash + V4 Flash + V4 Pro + V4 Flash Vision Exp | Advisory catalog shown by discovery consumers |
|
||||
| `models` | V41 Flash + V4 Pro | Advisory catalog shown by discovery consumers |
|
||||
| `streamIdleTimeoutMs` | `300,000` | Maximum provider idle time per outstanding stream read |
|
||||
| `maxRequestFilesBytes` | `128 MiB` | File-mode request-image byte budget; a request whose retained images exceed it fails with `IMAGE_OFFLOAD_REQUIRED` |
|
||||
| `maxInlineRequestImageBytes` | `20 MiB` | Independent base64 fallback high watermark |
|
||||
|
||||
@@ -45,7 +45,7 @@ kind: "package-reference"
|
||||
filesApiTimeoutMs: 60000
|
||||
```
|
||||
|
||||
请求用 `provider: deepseek-official` 选择路由;模型 id 原样传到协议,因此新增 DeepSeek 模型无需重新注册。省略 `models` 时公布支持文本和图像的 `deepseek-flash` 和 `deepseek-v4-flash-vision-exp`,以及仅支持文本的 `deepseek-v4-flash` 和 `deepseek-v4-pro`,各自的上下文窗口均为 1,000,000 token。显式列表会替换这些默认值,未列出的模型 id 仍作为纯文本路由原样通过。包括模型发现工具在内的客户端可通过 `ctx.llm.listModels('deepseek-official')` 读取这些建议性条目。支持图片的条目可把 `imagePixelBudget` 设置为正整数或 `low`,也可以设置 `imageMaxBytes`。当端点把 `messages` 中任意位置最新的 `system` 消息读作完整的有效系统提示词时,条目可以声明 `systemPromptUpdate: in-history`;适配器会在已解析模型与已准备调用上报告该模式,agent loop(智能体循环)随后把变化后的提示词追加到已缓存历史之后,而不是改写开头的 system 消息([决策规则](../../core/agent-loop/README.zh.md#understand-the-implementation))。默认的 `deepseek-flash` 条目声明该模式;其他模型需通过 `models` 显式声明,`in-history` 以外的任何值都会在加载时以 `llm-deepseek: catalog model "<id>" systemPromptUpdate must be "in-history" when present` 失败。
|
||||
请求用 `provider: deepseek-official` 选择路由;模型 id 原样传到协议,因此新增 DeepSeek 模型无需重新注册。省略 `models` 时公布支持文本和图像的 `deepseek-flash`,以及仅支持文本的 `deepseek-v4-pro`,各自的上下文窗口均为 1,000,000 token。显式列表会替换这些默认值,未列出的模型 id 仍作为纯文本路由原样通过。包括模型发现工具在内的客户端可通过 `ctx.llm.listModels('deepseek-official')` 读取这些建议性条目。支持图片的条目可把 `imagePixelBudget` 设置为正整数或 `low`,也可以设置 `imageMaxBytes`。当端点把 `messages` 中任意位置最新的 `system` 消息读作完整的有效系统提示词时,条目可以声明 `systemPromptUpdate: in-history`;适配器会在已解析模型与已准备调用上报告该模式,agent loop(智能体循环)随后把变化后的提示词追加到已缓存历史之后,而不是改写开头的 system 消息([决策规则](../../core/agent-loop/README.zh.md#understand-the-implementation))。默认的 `deepseek-flash` 条目声明该模式;其他模型需通过 `models` 显式声明,`in-history` 以外的任何值都会在加载时以 `llm-deepseek: catalog model "<id>" systemPromptUpdate must be "in-history" when present` 失败。
|
||||
|
||||
| 字段 | 默认值 | 含义 |
|
||||
|---|---|---|
|
||||
@@ -56,7 +56,7 @@ kind: "package-reference"
|
||||
| `reasoningEffort` | `high` | 默认强度:`off`、`low`、`high` 或 `max` |
|
||||
| `maxTokens` | `256,000` | 单次请求输出上限;模型自身上限与显式请求值优先 |
|
||||
| `defaultContextWindow` | `1,000,000` | 无精确值模型的容量回退 |
|
||||
| `models` | V41 Flash + V4 Flash + V4 Pro + V4 Flash Vision Exp | 供发现消费方查看的建议性目录 |
|
||||
| `models` | V41 Flash + V4 Pro | 供发现消费方查看的建议性目录 |
|
||||
| `streamIdleTimeoutMs` | `300,000` | 单次流读取未完成的最大提供方空闲时间 |
|
||||
| `maxRequestFilesBytes` | `128 MiB` | file 模式请求图片字节预算,保留图片超过时请求以 `IMAGE_OFFLOAD_REQUIRED` 失败 |
|
||||
| `maxInlineRequestImageBytes` | `20 MiB` | 独立的 base64 回退高水位 |
|
||||
|
||||
@@ -11,22 +11,10 @@ export const DEFAULT_MODELS: DeepSeekCatalogModel[] = [
|
||||
inputModalities: ['text', 'image'],
|
||||
systemPromptUpdate: 'in-history',
|
||||
},
|
||||
{
|
||||
id: 'deepseek-v4-flash',
|
||||
name: 'DeepSeek-V4-Flash',
|
||||
description: 'Fast, efficient, and economical; suited to focused, routine, or parallel tasks.',
|
||||
contextWindow: DEFAULT_CONTEXT_WINDOW,
|
||||
},
|
||||
{
|
||||
id: 'deepseek-v4-pro',
|
||||
name: 'DeepSeek-V4-Pro',
|
||||
description: 'Stronger agentic coding, knowledge, and difficult reasoning; suited to complex or quality-critical tasks at higher cost.',
|
||||
contextWindow: DEFAULT_CONTEXT_WINDOW,
|
||||
},
|
||||
{
|
||||
id: 'deepseek-v4-flash-vision-exp',
|
||||
name: 'DeepSeek-V4-Flash-Vision-Exp',
|
||||
contextWindow: DEFAULT_CONTEXT_WINDOW,
|
||||
inputModalities: ['text', 'image'],
|
||||
},
|
||||
]
|
||||
@@ -37,7 +37,7 @@ export interface Config {
|
||||
maxTokens?: number
|
||||
/** Positive context capacity used when the selected model has no exact value (default 1,000,000). */
|
||||
defaultContextWindow?: number
|
||||
/** Advisory models shown by discovery consumers; defaults to V41 Flash, V4 Flash, V4 Pro, and V4 Flash Vision Exp. */
|
||||
/** Advisory models shown by discovery consumers; defaults to V41 Flash and V4 Pro. */
|
||||
models?: DeepSeekCatalogModel[]
|
||||
/** Maximum provider idle time while one stream read is outstanding (default five minutes). */
|
||||
streamIdleTimeoutMs?: number
|
||||
|
||||
@@ -1712,13 +1712,6 @@ describe('plugin registration and config', () => {
|
||||
expect(ctx.llm.listProviders()).toEqual([{ id: 'deepseek-official', name: 'DeepSeek' }])
|
||||
await expect(ctx.llm.listModels('deepseek-official')).resolves.toEqual([
|
||||
{ provider: 'deepseek-official', id: 'deepseek-flash', name: 'DeepSeek-V41-Flash', inputModalities: ['text', 'image'] },
|
||||
{
|
||||
provider: 'deepseek-official',
|
||||
id: 'deepseek-v4-flash',
|
||||
name: 'DeepSeek-V4-Flash',
|
||||
description: 'Fast, efficient, and economical; suited to focused, routine, or parallel tasks.',
|
||||
inputModalities: ['text'],
|
||||
},
|
||||
{
|
||||
provider: 'deepseek-official',
|
||||
id: 'deepseek-v4-pro',
|
||||
@@ -1726,7 +1719,6 @@ describe('plugin registration and config', () => {
|
||||
description: 'Stronger agentic coding, knowledge, and difficult reasoning; suited to complex or quality-critical tasks at higher cost.',
|
||||
inputModalities: ['text'],
|
||||
},
|
||||
{ provider: 'deepseek-official', id: 'deepseek-v4-flash-vision-exp', name: 'DeepSeek-V4-Flash-Vision-Exp', inputModalities: ['text', 'image'] },
|
||||
])
|
||||
await expect(ctx.llm.resolveModelInfo('deepseek-official', 'deepseek-flash'))
|
||||
.resolves.toMatchObject({
|
||||
@@ -1749,18 +1741,14 @@ describe('plugin registration and config', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it.each([
|
||||
{ model: 'deepseek-v4-flash', inputModalities: ['text'] },
|
||||
{ model: 'deepseek-v4-pro', inputModalities: ['text'] },
|
||||
{ model: 'deepseek-v4-flash-vision-exp', inputModalities: ['text', 'image'] },
|
||||
])('keeps $model available with its V4 capabilities', async ({ model, inputModalities }) => {
|
||||
it('keeps deepseek-v4-pro available with its V4 capabilities', async () => {
|
||||
const ctx = new Context()
|
||||
await ctx.plugin(LlmRuntime)
|
||||
await ctx.plugin(LlmDeepSeek, { protocol: 'chat-completions', baseURL: 'http://127.0.0.1:1' })
|
||||
const info = await ctx.llm.resolveModelInfo('deepseek-official', model)
|
||||
const info = await ctx.llm.resolveModelInfo('deepseek-official', 'deepseek-v4-pro')
|
||||
expect(info).toMatchObject({
|
||||
id: model,
|
||||
inputModalities,
|
||||
id: 'deepseek-v4-pro',
|
||||
inputModalities: ['text'],
|
||||
context: { contextWindow: 1_000_000 },
|
||||
defaultMaxTokens: 256_000,
|
||||
})
|
||||
@@ -1854,13 +1842,6 @@ describe('plugin registration and config', () => {
|
||||
LlmDeepSeek.apply(ctx, { baseURL: 'http://127.0.0.1:1' })
|
||||
await expect(ctx.llm.listModels('deepseek-official')).resolves.toEqual([
|
||||
{ provider: 'deepseek-official', id: 'deepseek-flash', name: 'DeepSeek-V41-Flash', inputModalities: ['text', 'image'] },
|
||||
{
|
||||
provider: 'deepseek-official',
|
||||
id: 'deepseek-v4-flash',
|
||||
name: 'DeepSeek-V4-Flash',
|
||||
description: 'Fast, efficient, and economical; suited to focused, routine, or parallel tasks.',
|
||||
inputModalities: ['text'],
|
||||
},
|
||||
{
|
||||
provider: 'deepseek-official',
|
||||
id: 'deepseek-v4-pro',
|
||||
@@ -1868,7 +1849,6 @@ describe('plugin registration and config', () => {
|
||||
description: 'Stronger agentic coding, knowledge, and difficult reasoning; suited to complex or quality-critical tasks at higher cost.',
|
||||
inputModalities: ['text'],
|
||||
},
|
||||
{ provider: 'deepseek-official', id: 'deepseek-v4-flash-vision-exp', name: 'DeepSeek-V4-Flash-Vision-Exp', inputModalities: ['text', 'image'] },
|
||||
])
|
||||
})
|
||||
|
||||
@@ -2193,7 +2173,7 @@ describe('plugin registration and config', () => {
|
||||
// First-boot onboarding: the route registers so models stay discoverable;
|
||||
// only the request itself needs a key.
|
||||
expect(ctx.llm.listProviders()).toEqual([{ id: 'deepseek-official', name: 'DeepSeek' }])
|
||||
await expect(ctx.llm.listModels('deepseek-official')).resolves.toHaveLength(4)
|
||||
await expect(ctx.llm.listModels('deepseek-official')).resolves.toHaveLength(2)
|
||||
const first = await assemble(ctx, { model: 'deepseek-v4-flash', messages: [] })
|
||||
expect(first.finish).toMatchObject({ kind: 'error', failure: { code: 'MISSING_CREDENTIAL' } })
|
||||
// The guidance leads with the managed credential store.
|
||||
@@ -2281,7 +2261,7 @@ describe('plugin registration and config', () => {
|
||||
expect(adapter).toBeInstanceOf(DeepSeekAdapter)
|
||||
// Direct embedding shares the plugin's one resolve step, so it advertises
|
||||
// the same default catalog instead of a divergent empty one.
|
||||
await expect(adapter.listModels('deepseek-official')).resolves.toHaveLength(4)
|
||||
await expect(adapter.listModels('deepseek-official')).resolves.toHaveLength(2)
|
||||
})
|
||||
|
||||
it('resolves connection facts and the credential exactly once per stream call', async () => {
|
||||
|
||||
@@ -191,7 +191,7 @@ describe('request-level dynamic configuration', () => {
|
||||
const dir = await home()
|
||||
const { ctx } = await boot(dir, { baseURL: 'http://127.0.0.1:1' })
|
||||
|
||||
await expect(ctx.llm.listModels('deepseek-official')).resolves.toHaveLength(4)
|
||||
await expect(ctx.llm.listModels('deepseek-official')).resolves.toHaveLength(2)
|
||||
await ctx.settings.update(NS, {
|
||||
models: [{ id: 'settings-model', name: 'From Settings', inputModalities: ['text', 'image'] }],
|
||||
})
|
||||
@@ -276,7 +276,7 @@ describe('request-level dynamic configuration', () => {
|
||||
// Schema-valid but resolver-invalid: duplicate catalog ids pass the array
|
||||
// schema and fail the explicit resolve step.
|
||||
await ctx.settings.update(NS, { models: [{ id: 'dup' }, { id: 'dup' }] })
|
||||
await expect(ctx.llm.listModels('deepseek-official')).resolves.toHaveLength(4)
|
||||
await expect(ctx.llm.listModels('deepseek-official')).resolves.toHaveLength(2)
|
||||
await ctx.settings.update(NS, { models: [{ id: 'recovered' }] })
|
||||
await expect(ctx.llm.listModels('deepseek-official')).resolves.toEqual([
|
||||
{ provider: 'deepseek-official', id: 'recovered', name: 'recovered', inputModalities: ['text'] },
|
||||
|
||||
@@ -82,7 +82,7 @@ describe('direct Messages HTTP', () => {
|
||||
}, body: { thinking: { type: 'enabled' }, output_config: { effort: 'high' } } })
|
||||
expect(llm.providerInfo('deepseek-official')).toEqual({ id: 'deepseek-official', name: 'DeepSeek' })
|
||||
expect((await llm.listModels('deepseek-official')).map(model => model.id)).toEqual([
|
||||
'deepseek-flash', 'deepseek-v4-flash', 'deepseek-v4-pro', 'deepseek-v4-flash-vision-exp',
|
||||
'deepseek-flash', 'deepseek-v4-pro',
|
||||
])
|
||||
expect(await llm.resolveModel('deepseek-official', 'deepseek-flash')).toMatchObject({
|
||||
name: 'DeepSeek-V41-Flash', inputModalities: ['text', 'image'], systemPromptUpdate: 'in-history',
|
||||
@@ -188,7 +188,7 @@ describe('Cordis provider composition', () => {
|
||||
vi.stubEnv('DEEPSEEK_API_KEY', 'test-key')
|
||||
await ctx.plugin(LlmRuntime)
|
||||
await ctx.plugin(Messages, { baseURL: http.url })
|
||||
const model = 'deepseek-v4-flash-vision-exp'
|
||||
const model = 'deepseek-flash'
|
||||
const price = () => ctx.llm.imageRequestPricing('deepseek-official', model)!
|
||||
const dummy = { attachmentId: AttachmentId(`sha256:${'a'.repeat(64)}`), width: 1, height: 1, bytes: 3, mediaType: 'image/png' as const }
|
||||
expect(price().priceImages([{ type: 'image', attachment: dummy }])[0]?.text).toBeDefined()
|
||||
|
||||
@@ -251,11 +251,11 @@ describe('Messages images', () => {
|
||||
const image: ImageBlock = { type: 'image', attachment: ref }
|
||||
const version: RequestImageAttachment = { attachment: ref, variantId: ImageVariantId(`sha256:${'b'.repeat(64)}`), mediaType: 'image/png', bytes: 3, data: Uint8Array.of(1, 2, 3), width: 1, height: 1, depth: 'uchar', space: 'srgb', hasAlpha: false }
|
||||
const access = () => ({ readonlyPath: '/workspace/image.png' })
|
||||
const model = 'deepseek-v4-flash-vision-exp'
|
||||
const model = 'deepseek-flash'
|
||||
// Only the read operation is consumed by image preparation; the transport is mocked, not durable content.
|
||||
const attachments = { readImageRequest: async () => version } as unknown as AttachmentStore
|
||||
const signal = new AbortController().signal
|
||||
it.each(['deepseek-flash', model])('keeps image bytes inside tool results and deduplicates normalization for %s', async (model) => {
|
||||
it('keeps image bytes inside tool results and deduplicates normalization', async () => {
|
||||
const history = [assistant([call()]), result('a', [image, image])]
|
||||
const prepared = await prepareImages(history, connection, model, attachments, access, signal)
|
||||
expect(prepared.versions.size).toBe(1)
|
||||
|
||||
Reference in new issue
Block a user