pythonclaw 0.6.3__tar.gz → 0.6.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. {pythonclaw-0.6.3/pythonclaw.egg-info → pythonclaw-0.6.4}/PKG-INFO +1 -1
  2. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pyproject.toml +1 -1
  3. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/channels/telegram_bot.py +18 -69
  4. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/agent.py +2 -2
  5. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/llm/anthropic_client.py +1 -1
  6. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/llm/gemini_client.py +1 -1
  7. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/llm/openai_compatible.py +1 -1
  8. {pythonclaw-0.6.3 → pythonclaw-0.6.4/pythonclaw.egg-info}/PKG-INFO +1 -1
  9. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/LICENSE +0 -0
  10. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/MANIFEST.in +0 -0
  11. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/README.md +0 -0
  12. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/__init__.py +0 -0
  13. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/__main__.py +0 -0
  14. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/channels/discord_bot.py +0 -0
  15. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/channels/whatsapp_bot.py +0 -0
  16. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/config.py +0 -0
  17. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/__init__.py +0 -0
  18. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/compaction.py +0 -0
  19. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/knowledge/rag.py +0 -0
  20. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/llm/base.py +0 -0
  21. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/llm/response.py +0 -0
  22. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/memory/manager.py +0 -0
  23. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/memory/storage.py +0 -0
  24. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/persistent_agent.py +0 -0
  25. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/retrieval/__init__.py +0 -0
  26. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/retrieval/chunker.py +0 -0
  27. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/retrieval/dense.py +0 -0
  28. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/retrieval/fusion.py +0 -0
  29. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/retrieval/reranker.py +0 -0
  30. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/retrieval/retriever.py +0 -0
  31. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/retrieval/sparse.py +0 -0
  32. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/session_store.py +0 -0
  33. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/skill_loader.py +0 -0
  34. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/skillhub.py +0 -0
  35. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/tools.py +0 -0
  36. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/core/utils.py +0 -0
  37. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/daemon.py +0 -0
  38. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/init.py +0 -0
  39. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/main.py +0 -0
  40. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/onboard.py +0 -0
  41. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/scheduler/cron.py +0 -0
  42. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/scheduler/heartbeat.py +0 -0
  43. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/server.py +0 -0
  44. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/session_manager.py +0 -0
  45. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/persona/demo_persona.md +0 -0
  46. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/communication/CATEGORY.md +0 -0
  47. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/communication/email/SKILL.md +0 -0
  48. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/communication/email/send_email.py +0 -0
  49. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/communication/slack/SKILL.md +0 -0
  50. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/communication/slack/slack_api.py +0 -0
  51. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/data/CATEGORY.md +0 -0
  52. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/data/csv_analyzer/SKILL.md +0 -0
  53. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/data/csv_analyzer/analyze.py +0 -0
  54. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/data/finance/SKILL.md +0 -0
  55. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/data/finance/fetch_quote.py +0 -0
  56. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/data/news/SKILL.md +0 -0
  57. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/data/news/search_news.py +0 -0
  58. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/data/pdf_reader/SKILL.md +0 -0
  59. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/data/pdf_reader/read_pdf.py +0 -0
  60. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/data/scraper/SKILL.md +0 -0
  61. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/data/scraper/scrape.py +0 -0
  62. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/data/weather/SKILL.md +0 -0
  63. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/data/weather/weather.py +0 -0
  64. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/data/youtube/SKILL.md +0 -0
  65. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/data/youtube/youtube_info.py +0 -0
  66. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/dev/CATEGORY.md +0 -0
  67. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/dev/code_runner/SKILL.md +0 -0
  68. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/dev/code_runner/run_code.py +0 -0
  69. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/dev/github/SKILL.md +0 -0
  70. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/dev/github/gh.py +0 -0
  71. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/dev/http_request/SKILL.md +0 -0
  72. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/dev/http_request/request.py +0 -0
  73. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/google/CATEGORY.md +0 -0
  74. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/google/workspace/SKILL.md +0 -0
  75. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/google/workspace/check_setup.sh +0 -0
  76. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/media/CATEGORY.md +0 -0
  77. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/media/image_gen/SKILL.md +0 -0
  78. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/media/image_gen/generate.py +0 -0
  79. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/media/spotify/SKILL.md +0 -0
  80. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/media/spotify/spotify_ctl.py +0 -0
  81. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/media/tts/SKILL.md +0 -0
  82. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/media/tts/speak.py +0 -0
  83. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/meta/CATEGORY.md +0 -0
  84. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/meta/skill_creator/SKILL.md +0 -0
  85. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/productivity/CATEGORY.md +0 -0
  86. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/productivity/notion/SKILL.md +0 -0
  87. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/productivity/notion/notion_api.py +0 -0
  88. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/productivity/obsidian/SKILL.md +0 -0
  89. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/productivity/obsidian/obsidian_vault.py +0 -0
  90. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/productivity/trello/SKILL.md +0 -0
  91. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/productivity/trello/trello_api.py +0 -0
  92. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/system/CATEGORY.md +0 -0
  93. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/system/change_persona/SKILL.md +0 -0
  94. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/system/change_setting/SKILL.md +0 -0
  95. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/system/change_setting/update_config.py +0 -0
  96. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/system/change_soul/SKILL.md +0 -0
  97. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/system/model_usage/SKILL.md +0 -0
  98. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/system/model_usage/usage_stats.py +0 -0
  99. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/system/onboarding/SKILL.md +0 -0
  100. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/system/onboarding/write_identity.py +0 -0
  101. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/system/random/SKILL.md +0 -0
  102. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/system/random/random_util.py +0 -0
  103. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/system/session_logs/SKILL.md +0 -0
  104. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/system/session_logs/search_sessions.py +0 -0
  105. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/system/time/SKILL.md +0 -0
  106. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/system/time/time_util.py +0 -0
  107. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/text/CATEGORY.md +0 -0
  108. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/text/translator/SKILL.md +0 -0
  109. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/text/translator/translate.py +0 -0
  110. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/web/CATEGORY.md +0 -0
  111. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/web/summarize/SKILL.md +0 -0
  112. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/web/summarize/summarize_url.py +0 -0
  113. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/skills/web/tavily/SKILL.md +0 -0
  114. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/soul/SOUL.md +0 -0
  115. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/templates/tools/TOOLS.md +0 -0
  116. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/web/__init__.py +0 -0
  117. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/web/app.py +0 -0
  118. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/web/static/favicon.png +0 -0
  119. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/web/static/index.html +0 -0
  120. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw/web/static/logo.png +0 -0
  121. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw.egg-info/SOURCES.txt +0 -0
  122. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw.egg-info/dependency_links.txt +0 -0
  123. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw.egg-info/entry_points.txt +0 -0
  124. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw.egg-info/requires.txt +0 -0
  125. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/pythonclaw.egg-info/top_level.txt +0 -0
  126. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/setup.cfg +0 -0
  127. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/tests/test_compaction.py +0 -0
  128. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/tests/test_persistence.py +0 -0
  129. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/tests/test_rag_hybrid.py +0 -0
  130. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/tests/test_skills.py +0 -0
  131. {pythonclaw-0.6.3 → pythonclaw-0.6.4}/tests/test_soul.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pythonclaw
3
- Version: 0.6.3
3
+ Version: 0.6.4
4
4
  Summary: OpenClaw reimagined in pure Python — autonomous AI agent with memory, RAG, skills, web dashboard, and multi-channel support.
5
5
  Author-email: Eric Wang <wangchen2007915@gmail.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pythonclaw"
7
- version = "0.6.3"
7
+ version = "0.6.4"
8
8
  description = "OpenClaw reimagined in pure Python — autonomous AI agent with memory, RAG, skills, web dashboard, and multi-channel support."
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -244,8 +244,7 @@ class TelegramBot:
244
244
  except Exception:
245
245
  pass
246
246
 
247
- # Max wall-clock time for a single agent invocation (seconds).
248
- _AGENT_TIMEOUT = 180
247
+ _AGENT_TIMEOUT = 600
249
248
 
250
249
  async def _flush_stream(
251
250
  self,
@@ -253,98 +252,47 @@ class TelegramBot:
253
252
  token_queue: "_queue.Queue[str]",
254
253
  future: "asyncio.Future[str]",
255
254
  ) -> None:
256
- """Progressively stream tokens to Telegram via edit-in-place.
255
+ """Collect streamed tokens and deliver as 2-3 large messages.
257
256
 
258
- Uses send-then-edit (like OpenClaw): one live message that gets
259
- updated as tokens arrive (~1.5 s throttle). Tool-call markers
260
- produce a short status line and start a fresh message.
257
+ Strategy: accumulate all tokens silently. Tool-call markers are
258
+ stripped but do NOT trigger new messages. Content is edit-in-place
259
+ updated into a single live message; only when a message hits the
260
+ Telegram 4096 char limit is a new message started.
261
261
 
262
- Safeguards against hangs:
263
- - **Heartbeat**: if no tokens arrive for 15 s, sends a "still
264
- working" notification so the user knows the bot is alive.
265
- - **Overall timeout**: after ``_AGENT_TIMEOUT`` seconds the
266
- future is abandoned and a timeout message is sent.
262
+ No heartbeat / "still working" messages are sent.
267
263
  """
268
264
  buf: list[str] = []
269
265
  live_msg = None
270
266
  live_text = ""
271
267
  sent_any = False
272
- THROTTLE = 1.5
273
- HEARTBEAT_INTERVAL = 15.0
268
+ THROTTLE = 2.0
274
269
  last_edit = time.monotonic()
275
- last_token_time = time.monotonic()
276
270
  start_time = time.monotonic()
277
- heartbeat_sent = False
278
271
  _MARKER = re.compile(r'`\[calling:\s*([^\]]+)\]`')
279
272
 
280
273
  while not future.done():
281
- # ── Overall timeout guard ─────────────────────────────────
282
274
  if (time.monotonic() - start_time) > self._AGENT_TIMEOUT:
283
275
  logger.warning(
284
276
  "[Telegram] Agent timeout after %ds", self._AGENT_TIMEOUT,
285
277
  )
286
- try:
287
- await update.message.reply_text(
288
- "\u23f0 The operation timed out. "
289
- "Please try a simpler request."
290
- )
291
- except Exception:
292
- pass
293
- return
278
+ break
294
279
 
295
- # ── Drain token queue ─────────────────────────────────────
296
280
  drained = False
297
281
  while True:
298
282
  try:
299
283
  buf.append(token_queue.get_nowait())
300
284
  drained = True
301
- last_token_time = time.monotonic()
302
- heartbeat_sent = False
303
285
  except _queue.Empty:
304
286
  break
305
287
 
306
- # ── Heartbeat: notify user during long silences ───────────
307
- if (
308
- not drained
309
- and not heartbeat_sent
310
- and (time.monotonic() - last_token_time) > HEARTBEAT_INTERVAL
311
- ):
312
- try:
313
- await update.message.reply_text(
314
- "\u23f3 Still working\u2026"
315
- )
316
- except Exception:
317
- pass
318
- heartbeat_sent = True
319
-
320
288
  if not drained:
321
- await asyncio.sleep(0.3)
289
+ await asyncio.sleep(0.4)
322
290
  continue
323
291
 
324
- raw = "".join(buf)
292
+ raw = _MARKER.sub("", "".join(buf))
293
+ text = _clean_response(raw)
325
294
  now = time.monotonic()
326
295
 
327
- # ── Tool-call marker → status line + new message ──────────
328
- marker = _MARKER.search(raw)
329
- if marker:
330
- before = _clean_response(raw[:marker.start()])
331
- if before and before != live_text:
332
- try:
333
- if live_msg:
334
- await live_msg.edit_text(before[:4096])
335
- else:
336
- await update.message.reply_text(before[:4096])
337
- sent_any = True
338
- except Exception:
339
- pass
340
- live_msg = None
341
- live_text = ""
342
- buf = [raw[marker.end():].lstrip()]
343
- last_edit = now
344
- continue
345
-
346
- # ── Regular text → edit-in-place ──────────────────────────
347
- text = _clean_response(raw)
348
296
  if text and text != live_text and (now - last_edit) >= THROTTLE:
349
297
  try:
350
298
  if live_msg is None:
@@ -356,26 +304,27 @@ class TelegramBot:
356
304
  await live_msg.edit_text(text)
357
305
  live_text = text
358
306
  else:
359
- await live_msg.edit_text(text[:4096])
307
+ await live_msg.edit_text(live_text)
360
308
  live_msg = None
361
309
  live_text = ""
362
- buf = [text[4096:]]
310
+ buf = [text[len(live_text):] if live_text else text]
363
311
  sent_any = True
364
312
  except Exception:
365
313
  pass
366
314
  last_edit = now
367
315
 
368
- await asyncio.sleep(0.3)
316
+ await asyncio.sleep(0.4)
369
317
 
370
318
  # ── Final drain ───────────────────────────────────────────────
371
- response = future.result()
319
+ response = future.result() if future.done() else "(timed out)"
372
320
  while True:
373
321
  try:
374
322
  buf.append(token_queue.get_nowait())
375
323
  except _queue.Empty:
376
324
  break
377
325
 
378
- remaining = _clean_response("".join(buf).strip())
326
+ raw = _MARKER.sub("", "".join(buf))
327
+ remaining = _clean_response(raw.strip())
379
328
  if remaining and remaining != live_text:
380
329
  try:
381
330
  if live_msg and len(remaining) <= 4096:
@@ -120,9 +120,9 @@ class Agent:
120
120
  cron_manager : CronScheduler instance (enables cron_add/remove/list tools)
121
121
  """
122
122
 
123
- MAX_TOOL_ROUNDS = 8
123
+ MAX_TOOL_ROUNDS = 12
124
124
  MAX_PARALLEL_SKILLS = 5
125
- TOOL_TIMEOUT = 90
125
+ TOOL_TIMEOUT = 300
126
126
 
127
127
  def __init__(
128
128
  self,
@@ -29,7 +29,7 @@ class AnthropicProvider(LLMProvider):
29
29
  def __init__(self, api_key: str, model_name: str = "claude-sonnet-4-20250514"):
30
30
  self.client = anthropic.Anthropic(
31
31
  api_key=api_key,
32
- timeout=120.0,
32
+ timeout=300.0,
33
33
  )
34
34
  self.model_name = model_name
35
35
  self._auth_type = (
@@ -104,7 +104,7 @@ class GeminiProvider(LLMProvider):
104
104
  response = self.model.generate_content(
105
105
  contents=gemini_history,
106
106
  tools=gemini_tools,
107
- request_options={"timeout": 120},
107
+ request_options={"timeout": 300},
108
108
  )
109
109
 
110
110
  # Convert to OpenAI-compatible format
@@ -22,7 +22,7 @@ class OpenAICompatibleProvider(LLMProvider):
22
22
  self.client = OpenAI(
23
23
  api_key=api_key,
24
24
  base_url=base_url,
25
- timeout=120.0,
25
+ timeout=300.0,
26
26
  )
27
27
  self.model_name = model_name
28
28
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pythonclaw
3
- Version: 0.6.3
3
+ Version: 0.6.4
4
4
  Summary: OpenClaw reimagined in pure Python — autonomous AI agent with memory, RAG, skills, web dashboard, and multi-channel support.
5
5
  Author-email: Eric Wang <wangchen2007915@gmail.com>
6
6
  License: MIT
File without changes
File without changes
File without changes
File without changes