Skip to content

Commit e119437

Browse files
earayuclaude
andcommitted
test(e2e-http): migrate hurl 11/13/17/19 to v3 ModelSpec shape
The model-system refactor cuts ``ModelSpec.{model, model_service_provider, custom_llm_provider}`` and only keeps ``model_id``. Pydantic silently drops extras, so any hurl file still sending the old triple-shape parses as ``model_id=None`` and the downstream code-path goes silently broken (collection vector index, bot completion). Following the template established by ``10_provider_llm.hurl``, each file that exercises a real provider path (11, 13, 17) now seeds its own ``ModelAccount`` + ``Model`` via the v3 routes and references the captured ``model_id`` in the ``embedding`` / ``completion`` blobs. ``19_retrieval_http.hurl`` is a deterministic 4xx-shape test that must not depend on any provider seed; the optional embedding / completion config is dropped entirely. Closes the second design completeness gap PM flagged for #1697 (msg=8ac3e7d9). Provider keys are still required to actually run these against a live stack — the shape itself is now correct. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent c66513d commit e119437

4 files changed

Lines changed: 153 additions & 31 deletions

File tree

tests/e2e_http/hurl/full/11_document_full.hurl

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,64 @@ Content-Type: application/json
66
}
77
HTTP 200
88

9+
# v3 model-platform setup — every file is run independently, so the
10+
# embedding / completion ``model_id`` references in the collection
11+
# config must be resolved per file. ``ModelSpec`` no longer accepts
12+
# ``model`` / ``model_service_provider`` / ``custom_llm_provider``
13+
# — Pydantic silently drops extras, so any old-shape blob would parse
14+
# as ``model_id=None`` and the indexing pipeline would break silently.
15+
POST {{base_url}}/api/v3/model-accounts
16+
Content-Type: application/json
17+
{
18+
"provider_type": "dashscope",
19+
"name": "alibabacloud-doc-{{run_id}}",
20+
"display_name": "DashScope (E2E doc {{run_id}})",
21+
"base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
22+
"api_key": "{{alibabacloud_api_key}}"
23+
}
24+
HTTP 200
25+
[Captures]
26+
dashscope_account_id: jsonpath "$.id"
27+
28+
POST {{base_url}}/api/v3/model-accounts
29+
Content-Type: application/json
30+
{
31+
"provider_type": "openai_compatible",
32+
"name": "openrouter-doc-{{run_id}}",
33+
"display_name": "OpenRouter (E2E doc {{run_id}})",
34+
"base_url": "https://openrouter.ai/api/v1",
35+
"api_key": "{{openrouter_api_key}}"
36+
}
37+
HTTP 200
38+
[Captures]
39+
openrouter_account_id: jsonpath "$.id"
40+
41+
POST {{base_url}}/api/v3/models
42+
Content-Type: application/json
43+
{
44+
"account_id": "{{dashscope_account_id}}",
45+
"provider_model_id": "text-embedding-v3",
46+
"display_name": "DashScope text-embedding-v3",
47+
"capability": "embedding",
48+
"embedding_dimensions": 1024
49+
}
50+
HTTP 200
51+
[Captures]
52+
embedding_model_id: jsonpath "$.id"
53+
54+
POST {{base_url}}/api/v3/models
55+
Content-Type: application/json
56+
{
57+
"account_id": "{{openrouter_account_id}}",
58+
"provider_model_id": "google/gemini-2.5-flash",
59+
"display_name": "OpenRouter Gemini 2.5 Flash",
60+
"capability": "chat",
61+
"context_window": 8192
62+
}
63+
HTTP 200
64+
[Captures]
65+
completion_model_id: jsonpath "$.id"
66+
967
POST {{base_url}}/api/v2/collections
1068
Content-Type: application/json
1169
{
@@ -20,14 +78,10 @@ Content-Type: application/json
2078
"enable_summary": false,
2179
"enable_vision": false,
2280
"embedding": {
23-
"model": "text-embedding-v3",
24-
"model_service_provider": "alibabacloud",
25-
"custom_llm_provider": "openai"
81+
"model_id": "{{embedding_model_id}}"
2682
},
2783
"completion": {
28-
"model": "google/gemini-2.5-flash",
29-
"model_service_provider": "openrouter",
30-
"custom_llm_provider": "openrouter"
84+
"model_id": "{{completion_model_id}}"
3185
}
3286
}
3387
}

tests/e2e_http/hurl/full/13_chat_http.hurl

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,34 @@ Content-Type: application/json
66
}
77
HTTP 200
88

9+
# v3 model-platform setup — ``ModelSpec`` only accepts ``model_id``
10+
# now, so the bot config below references a freshly-seeded chat model.
11+
POST {{base_url}}/api/v3/model-accounts
12+
Content-Type: application/json
13+
{
14+
"provider_type": "openai_compatible",
15+
"name": "openrouter-chat-{{run_id}}",
16+
"display_name": "OpenRouter (E2E chat {{run_id}})",
17+
"base_url": "https://openrouter.ai/api/v1",
18+
"api_key": "{{openrouter_api_key}}"
19+
}
20+
HTTP 200
21+
[Captures]
22+
openrouter_account_id: jsonpath "$.id"
23+
24+
POST {{base_url}}/api/v3/models
25+
Content-Type: application/json
26+
{
27+
"account_id": "{{openrouter_account_id}}",
28+
"provider_model_id": "google/gemini-2.5-flash",
29+
"display_name": "OpenRouter Gemini 2.5 Flash",
30+
"capability": "chat",
31+
"context_window": 8192
32+
}
33+
HTTP 200
34+
[Captures]
35+
completion_model_id: jsonpath "$.id"
36+
937
POST {{base_url}}/api/v2/bots
1038
Content-Type: application/json
1139
{
@@ -15,9 +43,7 @@ Content-Type: application/json
1543
"config": {
1644
"agent": {
1745
"completion": {
18-
"model_service_provider": "openrouter",
19-
"model": "google/gemini-2.5-flash",
20-
"custom_llm_provider": "openrouter",
46+
"model_id": "{{completion_model_id}}",
2147
"temperature": 0.2
2248
},
2349
"system_prompt_template": "You are Chat Bot {{run_id}}.",
@@ -30,7 +56,7 @@ HTTP 200
3056
bot_id: jsonpath "$.id"
3157
[Asserts]
3258
jsonpath "$.id" == "{{bot_id}}"
33-
jsonpath "$.config.agent.completion.model" == "google/gemini-2.5-flash"
59+
jsonpath "$.config.agent.completion.model_id" == "{{completion_model_id}}"
3460

3561
POST {{base_url}}/api/v2/bots/{{bot_id}}/chats
3662
HTTP 200

tests/e2e_http/hurl/full/17_chat_collection_flow.hurl

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,61 @@ Content-Type: application/json
66
}
77
HTTP 200
88

9+
# v3 model-platform setup — every file is run independently and
10+
# ``ModelSpec`` only accepts ``model_id`` now, so the collection /
11+
# bot configs below reference freshly-seeded models.
12+
POST {{base_url}}/api/v3/model-accounts
13+
Content-Type: application/json
14+
{
15+
"provider_type": "dashscope",
16+
"name": "alibabacloud-flow-{{run_id}}",
17+
"display_name": "DashScope (E2E flow {{run_id}})",
18+
"base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
19+
"api_key": "{{alibabacloud_api_key}}"
20+
}
21+
HTTP 200
22+
[Captures]
23+
dashscope_account_id: jsonpath "$.id"
24+
25+
POST {{base_url}}/api/v3/model-accounts
26+
Content-Type: application/json
27+
{
28+
"provider_type": "openai_compatible",
29+
"name": "openrouter-flow-{{run_id}}",
30+
"display_name": "OpenRouter (E2E flow {{run_id}})",
31+
"base_url": "https://openrouter.ai/api/v1",
32+
"api_key": "{{openrouter_api_key}}"
33+
}
34+
HTTP 200
35+
[Captures]
36+
openrouter_account_id: jsonpath "$.id"
37+
38+
POST {{base_url}}/api/v3/models
39+
Content-Type: application/json
40+
{
41+
"account_id": "{{dashscope_account_id}}",
42+
"provider_model_id": "text-embedding-v3",
43+
"display_name": "DashScope text-embedding-v3",
44+
"capability": "embedding",
45+
"embedding_dimensions": 1024
46+
}
47+
HTTP 200
48+
[Captures]
49+
embedding_model_id: jsonpath "$.id"
50+
51+
POST {{base_url}}/api/v3/models
52+
Content-Type: application/json
53+
{
54+
"account_id": "{{openrouter_account_id}}",
55+
"provider_model_id": "google/gemini-2.5-flash",
56+
"display_name": "OpenRouter Gemini 2.5 Flash",
57+
"capability": "chat",
58+
"context_window": 8192
59+
}
60+
HTTP 200
61+
[Captures]
62+
completion_model_id: jsonpath "$.id"
63+
964
POST {{base_url}}/api/v2/collections
1065
Content-Type: application/json
1166
{
@@ -20,14 +75,10 @@ Content-Type: application/json
2075
"enable_summary": false,
2176
"enable_vision": false,
2277
"embedding": {
23-
"model": "text-embedding-v3",
24-
"model_service_provider": "alibabacloud",
25-
"custom_llm_provider": "openai"
78+
"model_id": "{{embedding_model_id}}"
2679
},
2780
"completion": {
28-
"model": "google/gemini-2.5-flash",
29-
"model_service_provider": "openrouter",
30-
"custom_llm_provider": "openrouter"
81+
"model_id": "{{completion_model_id}}"
3182
}
3283
}
3384
}
@@ -68,9 +119,7 @@ Content-Type: application/json
68119
"config": {
69120
"agent": {
70121
"completion": {
71-
"model_service_provider": "openrouter",
72-
"model": "google/gemini-2.5-flash",
73-
"custom_llm_provider": "openrouter",
122+
"model_id": "{{completion_model_id}}",
74123
"temperature": 0.2
75124
},
76125
"system_prompt_template": "Answer with the collection context when available.",

tests/e2e_http/hurl/full/19_retrieval_http.hurl

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ HTTP 200
1717
# Create a bare collection so the retrieval endpoints have a valid
1818
# target. All indexing is disabled — the search request below is
1919
# expected to fail at the "no strategy enabled" gate before any recall
20-
# backend is touched, which keeps the suite deterministic.
20+
# backend is touched, which keeps the suite deterministic. ``embedding``
21+
# / ``completion`` are intentionally omitted — they are optional, this
22+
# file is a contract / 4xx-shape test and must not depend on any
23+
# external provider availability or seeded ``model_id``.
2124
POST {{base_url}}/api/v2/collections
2225
Content-Type: application/json
2326
{
@@ -30,17 +33,7 @@ Content-Type: application/json
3033
"enable_fulltext": false,
3134
"enable_knowledge_graph": false,
3235
"enable_summary": false,
33-
"enable_vision": false,
34-
"embedding": {
35-
"model": "text-embedding-v3",
36-
"model_service_provider": "alibabacloud",
37-
"custom_llm_provider": "openai"
38-
},
39-
"completion": {
40-
"model": "google/gemini-2.5-flash",
41-
"model_service_provider": "openrouter",
42-
"custom_llm_provider": "openrouter"
43-
}
36+
"enable_vision": false
4437
}
4538
}
4639
HTTP 200

0 commit comments

Comments
 (0)