Skip to content

Commit ef52710

Browse files
satraclaude
andcommitted
fix(041): chat snake_case→camelCase for GraphQL, Ollama api_base on follow-up
- Convert field names (ontology_annotations → ontologyAnnotations) when applying proposed changes via GraphQL mutation - Pass api_base to litellm follow-up call (was only on initial call) - Add think:false and num_predict for Ollama qwen3.5 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 757e4c9 commit ef52710

2 files changed

Lines changed: 31 additions & 15 deletions

File tree

backend/src/services/chat_service.py

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212

1313
def _get_model() -> str:
1414
"""Get the LLM model to use. Supports OLLAMA_HOST for local dev."""
15+
if os.environ.get("UNDATA_LLM_MODEL"):
16+
return os.environ["UNDATA_LLM_MODEL"]
1517
if os.environ.get("OLLAMA_HOST"):
16-
return os.environ.get("UNDATA_LLM_MODEL", "ollama_chat/qwen3")
17-
return os.environ.get("UNDATA_LLM_MODEL", "gpt-4.1-mini")
18+
return "ollama_chat/qwen3.5"
19+
return "gpt-4.1-mini"
1820

1921

2022
TOOL_DEFINITIONS = [
@@ -167,13 +169,21 @@ async def chat_completion(
167169

168170
# Call LLM with tools
169171
try:
170-
response = await litellm.acompletion(
171-
model=_get_model(),
172-
messages=full_messages,
173-
tools=TOOL_DEFINITIONS,
174-
tool_choice="auto",
175-
stream=False,
176-
)
172+
model = _get_model()
173+
kwargs: dict = {
174+
"model": model,
175+
"messages": full_messages,
176+
"tools": TOOL_DEFINITIONS,
177+
"tool_choice": "auto",
178+
"stream": False,
179+
}
180+
# Ollama config: explicit API base + disable thinking mode
181+
if "ollama" in model:
182+
if os.environ.get("OLLAMA_HOST"):
183+
kwargs["api_base"] = os.environ["OLLAMA_HOST"]
184+
kwargs["extra_body"] = {"options": {"num_predict": 2048}, "think": False}
185+
litellm.drop_params = True
186+
response = await litellm.acompletion(**kwargs)
177187
except Exception as e:
178188
yield {"type": "text", "content": f"Error calling LLM: {e}"}
179189
return
@@ -205,11 +215,15 @@ async def chat_completion(
205215

206216
# Get final response after tool execution
207217
try:
208-
follow_up = await litellm.acompletion(
209-
model=_get_model(),
210-
messages=full_messages,
211-
stream=False,
212-
)
218+
follow_kwargs: dict = {
219+
"model": model,
220+
"messages": full_messages,
221+
"stream": False,
222+
}
223+
if "ollama" in model and os.environ.get("OLLAMA_HOST"):
224+
follow_kwargs["api_base"] = os.environ["OLLAMA_HOST"]
225+
follow_kwargs["extra_body"] = {"options": {"num_predict": 2048}, "think": False}
226+
follow_up = await litellm.acompletion(**follow_kwargs)
213227
yield {"type": "text", "content": follow_up.choices[0].message.content or ""}
214228
except Exception as e:
215229
yield {"type": "text", "content": f"Error in follow-up: {e}"}

frontend/app/curation/chat/page.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,12 @@ function CurationChatContent() {
8585
const handleApply = async (diff: DiffEntry) => {
8686
if (!entitySha) return;
8787
try {
88+
// Convert snake_case field names to camelCase for GraphQL
89+
const camelField = diff.field.replace(/_([a-z])/g, (_: string, c: string) => c.toUpperCase());
8890
await updateElement({
8991
variables: {
9092
sha256: entitySha,
91-
input: { [diff.field]: diff.new_value, reason: `Changed ${diff.field}` },
93+
input: { [camelField]: diff.new_value, reason: `Changed ${diff.field}` },
9294
},
9395
});
9496
setPendingDiffs((prev) => prev.filter((d) => d !== diff));

0 commit comments

Comments
 (0)