fix(confidence-engine): preserve successful chat detection
This commit is contained in:
@@ -92,6 +92,12 @@
|
|||||||
- Provider execution diagnostics now distinguish chat skipped due capability state, chat attempted and failed before generate fallback, and successful chat without fallback. They are deterministically verified through `/api/cases/start`; endpoint selection and fallback behaviour remain unchanged.
|
- Provider execution diagnostics now distinguish chat skipped due capability state, chat attempted and failed before generate fallback, and successful chat without fallback. They are deterministically verified through `/api/cases/start`; endpoint selection and fallback behaviour remain unchanged.
|
||||||
- Next restart point: one observation-only fixed-scenario production call to identify why `/api/generate` is reached.
|
- Next restart point: one observation-only fixed-scenario production call to identify why `/api/generate` is reached.
|
||||||
|
|
||||||
|
## Chat capability body disposal
|
||||||
|
|
||||||
|
- A fresh-process debugger observation proved capability `/api/chat` returned HTTP 200, then invalid `res.body?.consume()` threw and the catch incorrectly cached `_chatSupported = false`.
|
||||||
|
- This skipped schema-constrained reconstruction `/api/chat` and used unconstrained `/api/generate`. Response-body disposal now uses Fetch-compatible consumption without changing capability or fallback semantics.
|
||||||
|
- Next boundary: one fresh-process fixed-scenario production observation.
|
||||||
|
|
||||||
## Current product architecture
|
## Current product architecture
|
||||||
|
|
||||||
Three distinct routes, not a single page:
|
Three distinct routes, not a single page:
|
||||||
|
|||||||
+4
-4
@@ -84,13 +84,13 @@ async function detectChatSupport(baseUrl, modelName) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
await res.body?.consume();
|
await res.text();
|
||||||
_chatSupported = true;
|
_chatSupported = true;
|
||||||
} else if (res.status === 405 || res.status === 501) {
|
} else if (res.status === 405 || res.status === 501) {
|
||||||
await res.body?.consume();
|
await res.text();
|
||||||
_chatSupported = false;
|
_chatSupported = false;
|
||||||
} else {
|
} else {
|
||||||
await res.body?.consume();
|
await res.text();
|
||||||
_chatSupported = false;
|
_chatSupported = false;
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
@@ -160,7 +160,7 @@ class OllamaLlmProvider {
|
|||||||
: JSON.stringify(fullResponseData.message?.content ?? null);
|
: JSON.stringify(fullResponseData.message?.content ?? null);
|
||||||
apiUsed = "/api/chat";
|
apiUsed = "/api/chat";
|
||||||
} else {
|
} else {
|
||||||
await res.body?.consume();
|
await res.text();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!e.message.includes("abort")) { /* non-fatal */ }
|
if (!e.message.includes("abort")) { /* non-fatal */ }
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ describe("OllamaLlmProvider chat capability detection", () => {
|
|||||||
it("uses the configured model for the chat probe and keeps the chat path", async () => {
|
it("uses the configured model for the chat probe and keeps the chat path", async () => {
|
||||||
const originalBaseUrl = process.env.OLLAMA_BASE_URL;
|
const originalBaseUrl = process.env.OLLAMA_BASE_URL;
|
||||||
const fetchSpy = vi.fn()
|
const fetchSpy = vi.fn()
|
||||||
.mockResolvedValueOnce({ ok: true, body: { consume: vi.fn() } })
|
.mockResolvedValueOnce({ ok: true, text: async () => "" })
|
||||||
.mockResolvedValueOnce({
|
.mockResolvedValueOnce({
|
||||||
ok: true,
|
ok: true,
|
||||||
json: async () => ({ message: { content: "{}" } }),
|
json: async () => ({ message: { content: "{}" } }),
|
||||||
@@ -55,7 +55,7 @@ describe("OllamaLlmProvider chat capability detection", () => {
|
|||||||
it("reports chat-skipped generate fallback execution", async () => {
|
it("reports chat-skipped generate fallback execution", async () => {
|
||||||
const originalBaseUrl = process.env.OLLAMA_BASE_URL;
|
const originalBaseUrl = process.env.OLLAMA_BASE_URL;
|
||||||
const fetchSpy = vi.fn()
|
const fetchSpy = vi.fn()
|
||||||
.mockResolvedValueOnce({ ok: false, status: 501, body: { consume: vi.fn() } })
|
.mockResolvedValueOnce({ ok: false, status: 501, text: async () => "" })
|
||||||
.mockResolvedValueOnce({ ok: false, status: 500, text: async () => "failure" });
|
.mockResolvedValueOnce({ ok: false, status: 500, text: async () => "failure" });
|
||||||
vi.stubGlobal("fetch", fetchSpy);
|
vi.stubGlobal("fetch", fetchSpy);
|
||||||
process.env.OLLAMA_BASE_URL = "http://ollama.test";
|
process.env.OLLAMA_BASE_URL = "http://ollama.test";
|
||||||
@@ -84,8 +84,8 @@ describe("OllamaLlmProvider chat capability detection", () => {
|
|||||||
it("reports chat-attempt-failed generate fallback execution", async () => {
|
it("reports chat-attempt-failed generate fallback execution", async () => {
|
||||||
const originalBaseUrl = process.env.OLLAMA_BASE_URL;
|
const originalBaseUrl = process.env.OLLAMA_BASE_URL;
|
||||||
const fetchSpy = vi.fn()
|
const fetchSpy = vi.fn()
|
||||||
.mockResolvedValueOnce({ ok: true, body: { consume: vi.fn() } })
|
.mockResolvedValueOnce({ ok: true, text: async () => "" })
|
||||||
.mockResolvedValueOnce({ ok: false, body: { consume: vi.fn() } })
|
.mockResolvedValueOnce({ ok: false, text: async () => "" })
|
||||||
.mockResolvedValueOnce({ ok: false, status: 500, text: async () => "failure" });
|
.mockResolvedValueOnce({ ok: false, status: 500, text: async () => "failure" });
|
||||||
vi.stubGlobal("fetch", fetchSpy);
|
vi.stubGlobal("fetch", fetchSpy);
|
||||||
process.env.OLLAMA_BASE_URL = "http://ollama.test";
|
process.env.OLLAMA_BASE_URL = "http://ollama.test";
|
||||||
|
|||||||
Reference in New Issue
Block a user