refine: context window, timeout, abort guard, code_run multi-call check, clean logs
This commit is contained in:
@@ -71,8 +71,8 @@ class GeneraticAgent:
|
|||||||
return f"{type(b.backend).__name__}/{b.backend.default_model}"
|
return f"{type(b.backend).__name__}/{b.backend.default_model}"
|
||||||
|
|
||||||
def abort(self):
|
def abort(self):
|
||||||
print('Abort current task...')
|
|
||||||
if not self.is_running: return
|
if not self.is_running: return
|
||||||
|
print('Abort current task...')
|
||||||
self.stop_sig = True
|
self.stop_sig = True
|
||||||
if self.handler is not None: self.handler.code_stop_signal.append(1)
|
if self.handler is not None: self.handler.code_stop_signal.append(1)
|
||||||
|
|
||||||
|
|||||||
6
ga.py
6
ga.py
@@ -275,7 +275,8 @@ class GenericAgentHandler(BaseHandler):
|
|||||||
rsumm = re.search(r"<summary>(.*?)</summary>", response.content, re.DOTALL)
|
rsumm = re.search(r"<summary>(.*?)</summary>", response.content, re.DOTALL)
|
||||||
if rsumm: summary = rsumm.group(1).strip()[:200]
|
if rsumm: summary = rsumm.group(1).strip()[:200]
|
||||||
else:
|
else:
|
||||||
summary = f"调用工具{tool_name}, args: {args}"
|
clean_args = {k: v for k, v in args.items() if not k.startswith('_')}
|
||||||
|
summary = f"调用工具{tool_name}, args: {clean_args}"
|
||||||
if tool_name == 'no_tool': summary = "直接回答了用户问题"
|
if tool_name == 'no_tool': summary = "直接回答了用户问题"
|
||||||
if type(ret.next_prompt) is str:
|
if type(ret.next_prompt) is str:
|
||||||
ret.next_prompt += "\nPROTOCOL_VIOLATION: 上一轮遗漏了<summary>。 已根据物理动作自动补全。请务必在下次回复中记得<summary>协议。"
|
ret.next_prompt += "\nPROTOCOL_VIOLATION: 上一轮遗漏了<summary>。 已根据物理动作自动补全。请务必在下次回复中记得<summary>协议。"
|
||||||
@@ -284,7 +285,8 @@ class GenericAgentHandler(BaseHandler):
|
|||||||
def do_code_run(self, args, response):
|
def do_code_run(self, args, response):
|
||||||
'''执行代码片段,有长度限制,不允许代码中放大量数据,如有需要应当通过文件读取进行。
|
'''执行代码片段,有长度限制,不允许代码中放大量数据,如有需要应当通过文件读取进行。
|
||||||
'''
|
'''
|
||||||
if args.get('_index', 0) > 0: return StepOutcome("[BLANK]", next_prompt="no multi code_run in one round!")
|
if response.tool_calls and sum(1 for tc in response.tool_calls[:args.get('_index', 0)] if tc.function.name == 'code_run') > 0:
|
||||||
|
return StepOutcome("[BLANK]", next_prompt="no multi code_run in one round!")
|
||||||
code_type = args.get("type", "python")
|
code_type = args.get("type", "python")
|
||||||
# 从 response.content 中提取代码块, 匹配 ```python ... ``` 或 ```powershell ... ```
|
# 从 response.content 中提取代码块, 匹配 ```python ... ``` 或 ```powershell ... ```
|
||||||
pattern = rf"```{code_type}\n(.*?)\n```"
|
pattern = rf"```{code_type}\n(.*?)\n```"
|
||||||
|
|||||||
10
llmcore.py
10
llmcore.py
@@ -530,7 +530,7 @@ class NativeOAISession:
|
|||||||
def __init__(self, cfg):
|
def __init__(self, cfg):
|
||||||
self.api_key = cfg['apikey']; self.api_base = cfg['apibase'].rstrip('/')
|
self.api_key = cfg['apikey']; self.api_base = cfg['apibase'].rstrip('/')
|
||||||
self.default_model = cfg.get('model', 'gpt-4o')
|
self.default_model = cfg.get('model', 'gpt-4o')
|
||||||
self.context_win = cfg.get('context_win', 28000)
|
self.context_win = cfg.get('context_win', 24000)
|
||||||
proxy = cfg.get('proxy')
|
proxy = cfg.get('proxy')
|
||||||
self.proxies = {"http": proxy, "https": proxy} if proxy else None
|
self.proxies = {"http": proxy, "https": proxy} if proxy else None
|
||||||
self.history = []; self.system = ''; self.lock = threading.Lock()
|
self.history = []; self.system = ''; self.lock = threading.Lock()
|
||||||
@@ -598,7 +598,7 @@ class NativeClaudeSession:
|
|||||||
def __init__(self, cfg):
|
def __init__(self, cfg):
|
||||||
self.api_key = cfg['apikey']; self.api_base = cfg['apibase'].rstrip('/')
|
self.api_key = cfg['apikey']; self.api_base = cfg['apibase'].rstrip('/')
|
||||||
self.default_model = cfg.get('model', 'claude-opus')
|
self.default_model = cfg.get('model', 'claude-opus')
|
||||||
self.context_win = cfg.get('context_win', 30000)
|
self.context_win = cfg.get('context_win', 24000)
|
||||||
self.history = []; self.system = ''; self.lock = threading.Lock()
|
self.history = []; self.system = ''; self.lock = threading.Lock()
|
||||||
|
|
||||||
def raw_ask(self, messages, tools=None, system=None, model=None, temperature=0.5, max_tokens=6144):
|
def raw_ask(self, messages, tools=None, system=None, model=None, temperature=0.5, max_tokens=6144):
|
||||||
@@ -612,7 +612,7 @@ class NativeClaudeSession:
|
|||||||
messages[-1] = {**messages[-1], "content": list(messages[-1]["content"])}
|
messages[-1] = {**messages[-1], "content": list(messages[-1]["content"])}
|
||||||
messages[-1]["content"][-1] = dict(messages[-1]["content"][-1], cache_control={"type": "ephemeral"})
|
messages[-1]["content"][-1] = dict(messages[-1]["content"][-1], cache_control={"type": "ephemeral"})
|
||||||
try:
|
try:
|
||||||
resp = requests.post(auto_make_url(self.api_base, "messages"), headers=headers, json=payload, stream=True, timeout=120)
|
resp = requests.post(auto_make_url(self.api_base, "messages"), headers=headers, json=payload, stream=True, timeout=60)
|
||||||
if resp.status_code != 200:
|
if resp.status_code != 200:
|
||||||
error_msg = f"Error: HTTP {resp.status_code} {resp.text[:500]}"
|
error_msg = f"Error: HTTP {resp.status_code} {resp.text[:500]}"
|
||||||
yield error_msg
|
yield error_msg
|
||||||
@@ -707,7 +707,6 @@ class ToolClient:
|
|||||||
for chunk in gen:
|
for chunk in gen:
|
||||||
raw_text += chunk
|
raw_text += chunk
|
||||||
if chunk != summarytag: yield chunk
|
if chunk != summarytag: yield chunk
|
||||||
print('Complete response received.')
|
|
||||||
if raw_text.endswith(summarytag):
|
if raw_text.endswith(summarytag):
|
||||||
self.last_tools = ''; raw_text = raw_text[:-len(summarytag)]
|
self.last_tools = ''; raw_text = raw_text[:-len(summarytag)]
|
||||||
_write_llm_log('Response', raw_text)
|
_write_llm_log('Response', raw_text)
|
||||||
@@ -876,6 +875,7 @@ class NativeToolClient:
|
|||||||
每次回复请遵循:
|
每次回复请遵循:
|
||||||
1. 在 <thinking></thinking> 标签中先分析现状和策略
|
1. 在 <thinking></thinking> 标签中先分析现状和策略
|
||||||
2. 在 <summary></summary> 中输出极简单行(<30字)物理快照:上次结果新信息+本次意图。此内容进入长期工作记忆。
|
2. 在 <summary></summary> 中输出极简单行(<30字)物理快照:上次结果新信息+本次意图。此内容进入长期工作记忆。
|
||||||
|
3. 然后才能输出工具调用
|
||||||
""".strip()
|
""".strip()
|
||||||
def __init__(self, backend):
|
def __init__(self, backend):
|
||||||
self.backend = backend
|
self.backend = backend
|
||||||
@@ -884,6 +884,7 @@ class NativeToolClient:
|
|||||||
self._pending_tool_ids = []
|
self._pending_tool_ids = []
|
||||||
def set_system(self, extra_system):
|
def set_system(self, extra_system):
|
||||||
combined = f"{extra_system}\n\n{self.THINKING_PROMPT}" if extra_system else self.THINKING_PROMPT
|
combined = f"{extra_system}\n\n{self.THINKING_PROMPT}" if extra_system else self.THINKING_PROMPT
|
||||||
|
if combined != self.backend.system: print(f"[Debug] Updated system prompt, length {len(combined)} chars.")
|
||||||
self.backend.system = combined
|
self.backend.system = combined
|
||||||
def chat(self, messages, tools=None):
|
def chat(self, messages, tools=None):
|
||||||
if tools: self.tools = openai_tools_to_claude(tools) if isinstance(self.backend, NativeClaudeSession) else tools
|
if tools: self.tools = openai_tools_to_claude(tools) if isinstance(self.backend, NativeClaudeSession) else tools
|
||||||
@@ -905,7 +906,6 @@ class NativeToolClient:
|
|||||||
while True:
|
while True:
|
||||||
chunk = next(gen); yield chunk
|
chunk = next(gen); yield chunk
|
||||||
except StopIteration as e: resp = e.value
|
except StopIteration as e: resp = e.value
|
||||||
print('Complete response received.')
|
|
||||||
if resp:
|
if resp:
|
||||||
_write_llm_log('Response', resp.raw)
|
_write_llm_log('Response', resp.raw)
|
||||||
text = resp.content
|
text = resp.content
|
||||||
|
|||||||
Reference in New Issue
Block a user