Fixing bug tool calling setelah ada perubahan
This commit is contained in:
parent
94c364798f
commit
b12bd9cf2a
@ -104,6 +104,7 @@ class LLMClient:
|
|||||||
|
|
||||||
# Parse delta dari chunk
|
# Parse delta dari chunk
|
||||||
delta = chunk.get('choices', [{}])[0].get('delta', {})
|
delta = chunk.get('choices', [{}])[0].get('delta', {})
|
||||||
|
finish_reason = chunk.get('choices', [{}])[0].get('finish_reason', None)
|
||||||
|
|
||||||
# Stream reasoning content jika ada
|
# Stream reasoning content jika ada
|
||||||
if 'reasoning_content' in delta:
|
if 'reasoning_content' in delta:
|
||||||
@ -147,7 +148,32 @@ class LLMClient:
|
|||||||
message = {'content': full_content}
|
message = {'content': full_content}
|
||||||
|
|
||||||
if full_tool_calls:
|
if full_tool_calls:
|
||||||
message['tool_calls'] = full_tool_calls
|
# Filter tool_calls yang valid (ada name dan arguments)
|
||||||
|
valid_tool_calls = []
|
||||||
|
for tc in full_tool_calls:
|
||||||
|
name = tc.get('function', {}).get('name')
|
||||||
|
args_str = tc.get('function', {}).get('arguments')
|
||||||
|
tc_id = tc.get('id')
|
||||||
|
|
||||||
|
# Pastikan name dan arguments ada
|
||||||
|
if name and args_str and args_str.strip():
|
||||||
|
# Generate ID jika kosong
|
||||||
|
if not tc_id:
|
||||||
|
tc_id = f"call_{len(valid_tool_calls)}"
|
||||||
|
tc['id'] = tc_id
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Validate dan re-encode JSON untuk format yang konsisten
|
||||||
|
parsed_args = json.loads(args_str)
|
||||||
|
tc['function']['arguments'] = json.dumps(parsed_args, ensure_ascii=False)
|
||||||
|
valid_tool_calls.append(tc)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
# Invalid JSON, coba raw string tapi hanya jika tidak kosong
|
||||||
|
tc['function']['arguments'] = args_str
|
||||||
|
valid_tool_calls.append(tc)
|
||||||
|
|
||||||
|
if valid_tool_calls:
|
||||||
|
message['tool_calls'] = valid_tool_calls
|
||||||
|
|
||||||
response = {'choices': [{'message': message}]}
|
response = {'choices': [{'message': message}]}
|
||||||
except urllib.error.HTTPError as e:
|
except urllib.error.HTTPError as e:
|
||||||
|
|||||||
46
tui/agent.py
46
tui/agent.py
@ -87,18 +87,26 @@ def _agent_loop(app):
|
|||||||
log(app, "system", f" step {step + 1} \u2014 Thinking...")
|
log(app, "system", f" step {step + 1} \u2014 Thinking...")
|
||||||
app.scroll = 999999
|
app.scroll = 999999
|
||||||
|
|
||||||
# Streaming response - buat placeholder untuk AI response
|
# Streaming response
|
||||||
stream_idx = len(app.log)
|
|
||||||
log(app, "ai", "...") # Placeholder sambil streaming
|
|
||||||
|
|
||||||
stream_buffer = []
|
stream_buffer = []
|
||||||
|
placeholder_marker = None
|
||||||
|
|
||||||
def on_stream_chunk(chunk):
|
def on_stream_chunk(chunk):
|
||||||
|
nonlocal placeholder_marker
|
||||||
|
# Buat placeholder di chunk pertama saja
|
||||||
|
if placeholder_marker is None:
|
||||||
|
placeholder_marker = f"_stream_placeholder_{step}"
|
||||||
|
log(app, "ai", placeholder_marker)
|
||||||
stream_buffer.append(chunk)
|
stream_buffer.append(chunk)
|
||||||
current_text = ''.join(stream_buffer)
|
current_text = ''.join(stream_buffer)
|
||||||
# Update placeholder secara real-time
|
# Update placeholder secara real-time
|
||||||
if stream_idx < len(app.log):
|
for i in range(len(app.log) - 1, -1, -1):
|
||||||
app.log[stream_idx]['text'] = current_text
|
# Cari placeholder berdasarkan content aslinya (atau apa yang sudah diupdate)
|
||||||
app.scroll = 999999
|
# Karena placeholder text berubah seiring streaming, kita harus teliti
|
||||||
|
if app.log[i].get('role') == 'ai' and (app.log[i].get('text') == placeholder_marker or (i > 0 and app.log[i-1].get('role') == 'system' and 'Thinking' in app.log[i-1].get('text', ''))):
|
||||||
|
app.log[i]['text'] = current_text
|
||||||
|
break
|
||||||
|
app.scroll = 999999
|
||||||
|
|
||||||
response = app.llm.chat(app.messages, tools=app.TOOLS, on_stream_chunk=on_stream_chunk)
|
response = app.llm.chat(app.messages, tools=app.TOOLS, on_stream_chunk=on_stream_chunk)
|
||||||
|
|
||||||
@ -111,11 +119,23 @@ def _agent_loop(app):
|
|||||||
if response.warning:
|
if response.warning:
|
||||||
log(app, "system", f" {response.warning}")
|
log(app, "system", f" {response.warning}")
|
||||||
|
|
||||||
if response.tool_calls:
|
# Cek apakah ada tool_calls
|
||||||
|
has_tool_calls = bool(response.tool_calls)
|
||||||
|
|
||||||
|
if has_tool_calls:
|
||||||
|
# Hapus placeholder jika ada tool_calls (cari semua AI log yang mungkin placeholder)
|
||||||
|
if placeholder_marker is not None:
|
||||||
|
for i in range(len(app.log) - 1, -1, -1):
|
||||||
|
# Jika ini adalah log AI yang muncul tepat setelah "Thinking..." atau contains placeholder marker
|
||||||
|
if app.log[i].get('role') == 'ai':
|
||||||
|
text = app.log[i].get('text', '')
|
||||||
|
# Hapus jika text-nya adalah placeholder atau jika itu adalah entry AI yang baru saja kita buat untuk streaming
|
||||||
|
if placeholder_marker in text or text == "" or text == "...":
|
||||||
|
app.log.pop(i)
|
||||||
|
|
||||||
_add_msg(app, "assistant", response.content, tool_calls=response.tool_calls)
|
_add_msg(app, "assistant", response.content, tool_calls=response.tool_calls)
|
||||||
# Placeholder sudah terupdate via streaming, jangan log lagi
|
|
||||||
if stream_idx < len(app.log) and response.content and response.content.strip():
|
# Log tool_calls dengan label AI
|
||||||
app.log[stream_idx]['text'] = response.content
|
|
||||||
for tc in response.tool_calls:
|
for tc in response.tool_calls:
|
||||||
tname = tc["function"]["name"]
|
tname = tc["function"]["name"]
|
||||||
targs = tc["function"]["arguments"]
|
targs = tc["function"]["arguments"]
|
||||||
@ -125,6 +145,10 @@ def _agent_loop(app):
|
|||||||
}))
|
}))
|
||||||
app.scroll = 999999
|
app.scroll = 999999
|
||||||
execute_tool(app, tc)
|
execute_tool(app, tc)
|
||||||
|
|
||||||
|
# Log content AI setelah tools (jika ada)
|
||||||
|
if response.content and response.content.strip():
|
||||||
|
log(app, "ai", response.content)
|
||||||
else:
|
else:
|
||||||
if response.content:
|
if response.content:
|
||||||
_add_msg(app, "assistant", response.content)
|
_add_msg(app, "assistant", response.content)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user