refactor MixinSession._raw_ask: simplify retry logic, skip yielding first-only error chunk
This commit is contained in:
@@ -91,5 +91,5 @@ def agent_runner_loop(client, system_prompt, user_input, handler, tools_schema,
|
|||||||
next_prompt += f"<tool_result>\n{datastr}\n</tool_result>\n\n"
|
next_prompt += f"<tool_result>\n{datastr}\n</tool_result>\n\n"
|
||||||
next_prompt += outcome.next_prompt
|
next_prompt += outcome.next_prompt
|
||||||
next_prompt = handler.next_prompt_patcher(next_prompt, None, turn+1)
|
next_prompt = handler.next_prompt_patcher(next_prompt, None, turn+1)
|
||||||
messages = [{"role": "user", "content": next_prompt}]
|
messages = [{"role": "user", "content": next_prompt}] # just new message, history is kept in *Session
|
||||||
return {'result': 'MAX_TURNS_EXCEEDED'}
|
return {'result': 'MAX_TURNS_EXCEEDED'}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[
|
[
|
||||||
{"type": "function", "function": {
|
{"type": "function", "function": {
|
||||||
"name": "code_run",
|
"name": "code_run",
|
||||||
"description": "代码执行器。优先python,系统操作用powershell。禁同时调用多个。为免转义问题,代码放正文 ```python/powershell 块中。禁硬编码大量数据",
|
"description": "代码执行器。优先使用python。禁同时调用多个。为免转义问题,代码放正文 ```python/powershell 块中。禁硬编码大量数据",
|
||||||
"parameters": {"type": "object", "properties": {
|
"parameters": {"type": "object", "properties": {
|
||||||
"script": {"type": "string", "description": "[Optional] 要执行的代码。为免转义建议留空,改用正文代码块(与此参数互斥)"},
|
"script": {"type": "string", "description": "[Optional] 要执行的代码。为免转义建议留空,改用正文代码块(与此参数互斥)"},
|
||||||
"type": {"type": "string", "enum": ["python", "powershell"], "description": "代码类型", "default": "python"},
|
"type": {"type": "string", "enum": ["python", "powershell"], "description": "代码类型", "default": "python"},
|
||||||
|
|||||||
30
llmcore.py
30
llmcore.py
@@ -814,26 +814,20 @@ class MixinSession:
|
|||||||
@property
|
@property
|
||||||
def primary(self): return self._sessions[0]
|
def primary(self): return self._sessions[0]
|
||||||
def _raw_ask(self, *args, **kwargs):
|
def _raw_ask(self, *args, **kwargs):
|
||||||
last_err = None
|
|
||||||
for attempt in range(self._retries + 1):
|
for attempt in range(self._retries + 1):
|
||||||
gen = self._orig_raw_asks[attempt % len(self._sessions)](*args, **kwargs)
|
gen = self._orig_raw_asks[attempt % len(self._sessions)](*args, **kwargs)
|
||||||
try: first = next(gen)
|
last_chunk, return_val, yielded = None, [], False
|
||||||
except StopIteration as e: return e.value or []
|
try:
|
||||||
if isinstance(first, str) and first.startswith('Error:'):
|
while True:
|
||||||
last_err = first
|
chunk = next(gen); last_chunk = chunk
|
||||||
for _ in gen: pass # drain
|
if not yielded and isinstance(chunk, str) and chunk.startswith('Error:'): continue
|
||||||
if attempt < self._retries:
|
yield chunk; yielded = True
|
||||||
delay = min(30, self._base_delay * (2 ** attempt))
|
except StopIteration as e: return_val = e.value or []
|
||||||
print(f'[MixinSession] {first[:80]}, retry {attempt+1}/{self._retries} in {delay:.1f}s')
|
if isinstance(last_chunk, str) and last_chunk.startswith('Error:') and attempt < self._retries:
|
||||||
time.sleep(delay); continue
|
delay = min(30, self._base_delay * (2 ** attempt))
|
||||||
else:
|
print(f'[MixinSession] {last_chunk[:80]}, retry {attempt+1}/{self._retries} in {delay:.1f}s')
|
||||||
yield first
|
time.sleep(delay); continue
|
||||||
try:
|
return return_val
|
||||||
while True: yield next(gen)
|
|
||||||
except StopIteration as e: return e.value or []
|
|
||||||
yield last_err or 'Error: all retries exhausted'
|
|
||||||
return [{'type': 'text', 'text': last_err}]
|
|
||||||
|
|
||||||
|
|
||||||
class NativeToolClient:
|
class NativeToolClient:
|
||||||
THINKING_PROMPT = """
|
THINKING_PROMPT = """
|
||||||
|
|||||||
Reference in New Issue
Block a user