pythinker-code 0.58.0__py3-none-any.whl → 0.59.0__py3-none-any.whl

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 (101) hide show
  1. pythinker_code/CHANGELOG.md +12 -0
  2. pythinker_code/auth/__init__.py +4 -2
  3. pythinker_code/auth/platforms.py +37 -15
  4. pythinker_code/auth/z_ai.py +251 -187
  5. pythinker_code/background/agent_runner.py +4 -0
  6. pythinker_code/background/manager.py +8 -0
  7. pythinker_code/cli/__init__.py +83 -4
  8. pythinker_code/llm.py +57 -227
  9. pythinker_code/provider_compatibility.py +401 -0
  10. pythinker_code/soul/pythinkersoul.py +37 -31
  11. pythinker_code/soul/tool_execution.py +945 -0
  12. pythinker_code/soul/toolset.py +59 -633
  13. pythinker_code/subagents/core.py +36 -8
  14. pythinker_code/subagents/git_context.py +179 -82
  15. pythinker_code/subagents/review_target.py +715 -0
  16. pythinker_code/subagents/runner.py +13 -0
  17. pythinker_code/tools/agent/__init__.py +83 -3
  18. pythinker_code/tools/agent/description.md +4 -0
  19. pythinker_code/ui/shell/oauth.py +32 -16
  20. pythinker_code/ui/shell/slash.py +14 -2
  21. pythinker_code/ui/shell/usage_adapters/__init__.py +5 -0
  22. pythinker_code/ui/shell/usage_adapters/z_ai.py +33 -0
  23. pythinker_code/utils/trust.py +16 -0
  24. pythinker_code/web/static/assets/architecture-7EHR7CIX-3gv838NK.js +1 -0
  25. pythinker_code/web/static/assets/{architectureDiagram-3BPJPVTR-DNjSUgP8.js → architectureDiagram-3BPJPVTR-DLLFeZrO.js} +1 -1
  26. pythinker_code/web/static/assets/{blockDiagram-GPEHLZMM-Bj6WF362.js → blockDiagram-GPEHLZMM-CkkDeCg3.js} +1 -1
  27. pythinker_code/web/static/assets/{bootstrap-DPOVLodG.js → bootstrap-CYaJoziy.js} +5 -5
  28. pythinker_code/web/static/assets/{c4Diagram-AAUBKEIU-GGQSrWG4.js → c4Diagram-AAUBKEIU-Bp0uYF88.js} +1 -1
  29. pythinker_code/web/static/assets/channel-CkHUjHH1.js +1 -0
  30. pythinker_code/web/static/assets/{chunk-2J33WTMH-OsiI6Shl.js → chunk-2J33WTMH-fp3JfPmd.js} +1 -1
  31. pythinker_code/web/static/assets/{chunk-3OPIFGDE-BT9LH4XF.js → chunk-3OPIFGDE-wcHktjqJ.js} +1 -1
  32. pythinker_code/web/static/assets/{chunk-5ZQYHXKU-BKI-R690.js → chunk-5ZQYHXKU-0AKuUvLh.js} +1 -1
  33. pythinker_code/web/static/assets/{chunk-727SXJPM-zD8K6bZU.js → chunk-727SXJPM-DyxXlkLC.js} +1 -1
  34. pythinker_code/web/static/assets/{chunk-AQP2D5EJ-C8-RqfOY.js → chunk-AQP2D5EJ-BXKoDDbF.js} +1 -1
  35. pythinker_code/web/static/assets/{chunk-CSCIHK7Q-DauLS_KO.js → chunk-CSCIHK7Q-D2HuONst.js} +1 -1
  36. pythinker_code/web/static/assets/{chunk-JAPRZBRM-B3vK8rJr.js → chunk-JAPRZBRM-mrWIOJ3Z.js} +4 -4
  37. pythinker_code/web/static/assets/{chunk-KSCS5N6A-q_c8Otyz.js → chunk-KSCS5N6A-HBBRdKIv.js} +1 -1
  38. pythinker_code/web/static/assets/{chunk-L5ZTLDWV-L38JietD.js → chunk-L5ZTLDWV-DXKFCZsy.js} +1 -1
  39. pythinker_code/web/static/assets/{chunk-LZXEDZCA-JUzQ08Fk.js → chunk-LZXEDZCA-B3ZD-FXA.js} +2 -2
  40. pythinker_code/web/static/assets/{chunk-ND2GUHAM-B7lN__eE.js → chunk-ND2GUHAM-DuP52a96.js} +1 -1
  41. pythinker_code/web/static/assets/{chunk-NZK2D7GU-MT98-VRd.js → chunk-NZK2D7GU-CnbADCJ7.js} +1 -1
  42. pythinker_code/web/static/assets/{chunk-O5CBEL6O-HS6UvO8l.js → chunk-O5CBEL6O-pVVcoftv.js} +1 -1
  43. pythinker_code/web/static/assets/{chunk-WU5MYG2G-2FStZlKC.js → chunk-WU5MYG2G-BAGZBXu1.js} +1 -1
  44. pythinker_code/web/static/assets/classDiagram-4FO5ZUOK-dmKXWwan.js +1 -0
  45. pythinker_code/web/static/assets/classDiagram-v2-Q7XG4LA2-dmKXWwan.js +1 -0
  46. pythinker_code/web/static/assets/{code-block-IT6T5CEO-CSd98pzb.js → code-block-IT6T5CEO-DYAyge1a.js} +1 -1
  47. pythinker_code/web/static/assets/{dagre-BM42HDAG-CRsWJlJl.js → dagre-BM42HDAG-BKxxBFuu.js} +1 -1
  48. pythinker_code/web/static/assets/{diagram-2AECGRRQ-x6OaKKPB.js → diagram-2AECGRRQ-G94XlJaV.js} +1 -1
  49. pythinker_code/web/static/assets/{diagram-5GNKFQAL-DC8c6FnZ.js → diagram-5GNKFQAL-CiSAYUQ6.js} +1 -1
  50. pythinker_code/web/static/assets/{diagram-KO2AKTUF-B7qc5yfP.js → diagram-KO2AKTUF-BbSqB6Ns.js} +1 -1
  51. pythinker_code/web/static/assets/{diagram-LMA3HP47-BFPLlnJr.js → diagram-LMA3HP47-G8Eh-i79.js} +1 -1
  52. pythinker_code/web/static/assets/{diagram-OG6HWLK6-B-WnMmPG.js → diagram-OG6HWLK6-D7IzVrGq.js} +1 -1
  53. pythinker_code/web/static/assets/{dist-Co5o61Cn.js → dist-CZrlFtNU.js} +1 -1
  54. pythinker_code/web/static/assets/{erDiagram-TEJ5UH35-Vt3XXS0U.js → erDiagram-TEJ5UH35-BS2kAHFz.js} +1 -1
  55. pythinker_code/web/static/assets/eventmodeling-FCH6USID-D3DrnYSf.js +1 -0
  56. pythinker_code/web/static/assets/{flowDiagram-I6XJVG4X-BIXHEjYH.js → flowDiagram-I6XJVG4X-C_F9vMtr.js} +1 -1
  57. pythinker_code/web/static/assets/{ganttDiagram-6RSMTGT7--FC4MYE3.js → ganttDiagram-6RSMTGT7-B2jC1UUf.js} +1 -1
  58. pythinker_code/web/static/assets/{gitGraph-WXDBUCRP-IE4jYajm.js → gitGraph-WXDBUCRP-B0vzLEp0.js} +1 -1
  59. pythinker_code/web/static/assets/{gitGraphDiagram-PVQCEYII-n6_B85cu.js → gitGraphDiagram-PVQCEYII-B-wPebOF.js} +1 -1
  60. pythinker_code/web/static/assets/{index-Denir8Jc.js → index-laCurKYw.js} +2 -2
  61. pythinker_code/web/static/assets/{info-J43DQDTF-BL7RBP_1.js → info-J43DQDTF-DUjhI1nz.js} +1 -1
  62. pythinker_code/web/static/assets/{infoDiagram-5YYISTIA-DyvqlJzB.js → infoDiagram-5YYISTIA-Cbwstbdp.js} +1 -1
  63. pythinker_code/web/static/assets/{ishikawaDiagram-YF4QCWOH--AK0oQMB.js → ishikawaDiagram-YF4QCWOH-BkycF4AV.js} +1 -1
  64. pythinker_code/web/static/assets/{journeyDiagram-JHISSGLW-DPt6uw-j.js → journeyDiagram-JHISSGLW-CJ42Wqhp.js} +1 -1
  65. pythinker_code/web/static/assets/{kanban-definition-UN3LZRKU-CMP28iqQ.js → kanban-definition-UN3LZRKU-CwqoUk88.js} +1 -1
  66. pythinker_code/web/static/assets/{line-QV0kz4Kh.js → line-D3Csi8Mz.js} +1 -1
  67. pythinker_code/web/static/assets/mermaid-VLURNSYL-CxqVR2Qj.js +1 -0
  68. pythinker_code/web/static/assets/{mermaid-parser.core-5eX2XKzs.js → mermaid-parser.core-Be6EdzXv.js} +2 -2
  69. pythinker_code/web/static/assets/{mermaid.core-xSjkHKy4.js → mermaid.core-Bry8j9-Y.js} +3 -3
  70. pythinker_code/web/static/assets/{mindmap-definition-RKZ34NQL-SSQGdG4v.js → mindmap-definition-RKZ34NQL-r7fWzBYs.js} +1 -1
  71. pythinker_code/web/static/assets/{packet-YPE3B663-DTfa3Ugh.js → packet-YPE3B663-C9dNvYXo.js} +1 -1
  72. pythinker_code/web/static/assets/{pie-LRSECV5Y-D3jK8uBv.js → pie-LRSECV5Y-BAAPLVkr.js} +1 -1
  73. pythinker_code/web/static/assets/{pieDiagram-4H26LBE5--TRptUQU.js → pieDiagram-4H26LBE5-vWjWwnGH.js} +1 -1
  74. pythinker_code/web/static/assets/{quadrantDiagram-W4KKPZXB-Db9MtYHt.js → quadrantDiagram-W4KKPZXB-B_yvrBi5.js} +1 -1
  75. pythinker_code/web/static/assets/{radar-GUYGQ44K-DFnRNCTk.js → radar-GUYGQ44K-dthF6sP5.js} +1 -1
  76. pythinker_code/web/static/assets/{requirementDiagram-4Y6WPE33-sTa-nhJU.js → requirementDiagram-4Y6WPE33-BdIjnY_y.js} +1 -1
  77. pythinker_code/web/static/assets/{sankeyDiagram-5OEKKPKP-Bd2A0AYR.js → sankeyDiagram-5OEKKPKP-BO-wztnd.js} +1 -1
  78. pythinker_code/web/static/assets/{sequenceDiagram-3UESZ5HK-gsJgyFMR.js → sequenceDiagram-3UESZ5HK-D4OTlb5_.js} +1 -1
  79. pythinker_code/web/static/assets/{stateDiagram-AJRCARHV-D8aBQA8n.js → stateDiagram-AJRCARHV-DbM9zIup.js} +1 -1
  80. pythinker_code/web/static/assets/stateDiagram-v2-BHNVJYJU-Bx9jf2eN.js +1 -0
  81. pythinker_code/web/static/assets/{timeline-definition-PNZ67QCA-DOTZZxx_.js → timeline-definition-PNZ67QCA-Bdnq296j.js} +1 -1
  82. pythinker_code/web/static/assets/{treeView-BLDUP644-DeRg38Vr.js → treeView-BLDUP644-CfSkXca9.js} +1 -1
  83. pythinker_code/web/static/assets/{treemap-LRROVOQU-DWxQ3QgK.js → treemap-LRROVOQU-BfIIMFqt.js} +1 -1
  84. pythinker_code/web/static/assets/{vennDiagram-CIIHVFJN-CYSR8VxH.js → vennDiagram-CIIHVFJN-Bh4a039Q.js} +1 -1
  85. pythinker_code/web/static/assets/{wardley-L42UT6IY-DwndHzRK.js → wardley-L42UT6IY-z1eD6dJ1.js} +1 -1
  86. pythinker_code/web/static/assets/{wardleyDiagram-YWT4CUSO-By2G9X0c.js → wardleyDiagram-YWT4CUSO-C4FzoV-Q.js} +1 -1
  87. pythinker_code/web/static/assets/{xychartDiagram-2RQKCTM6-hEjj-Cb8.js → xychartDiagram-2RQKCTM6-DSrsRKRD.js} +1 -1
  88. pythinker_code/web/static/index.html +1 -1
  89. {pythinker_code-0.58.0.dist-info → pythinker_code-0.59.0.dist-info}/METADATA +38 -23
  90. {pythinker_code-0.58.0.dist-info → pythinker_code-0.59.0.dist-info}/RECORD +94 -90
  91. pythinker_code/web/static/assets/architecture-7EHR7CIX-S-vCW5iB.js +0 -1
  92. pythinker_code/web/static/assets/channel-BF4DnhOY.js +0 -1
  93. pythinker_code/web/static/assets/classDiagram-4FO5ZUOK-bQ8c0gns.js +0 -1
  94. pythinker_code/web/static/assets/classDiagram-v2-Q7XG4LA2-bQ8c0gns.js +0 -1
  95. pythinker_code/web/static/assets/eventmodeling-FCH6USID-BleAriwz.js +0 -1
  96. pythinker_code/web/static/assets/mermaid-VLURNSYL-Cw_TmpwX.js +0 -1
  97. pythinker_code/web/static/assets/stateDiagram-v2-BHNVJYJU-CcaDggV3.js +0 -1
  98. {pythinker_code-0.58.0.dist-info → pythinker_code-0.59.0.dist-info}/WHEEL +0 -0
  99. {pythinker_code-0.58.0.dist-info → pythinker_code-0.59.0.dist-info}/entry_points.txt +0 -0
  100. {pythinker_code-0.58.0.dist-info → pythinker_code-0.59.0.dist-info}/licenses/LICENSE +0 -0
  101. {pythinker_code-0.58.0.dist-info → pythinker_code-0.59.0.dist-info}/licenses/NOTICE +0 -0
@@ -15,6 +15,18 @@ GitHub Releases page; `0.8.0` is the new starting line.
15
15
 
16
16
  ## Unreleased
17
17
 
18
+ ## 0.59.0 (2026-07-17)
19
+
20
+ - **Reviewer subagents now receive deterministic Git scopes.** Structured automatic,
21
+ uncommitted, base, and commit targets resolve to full commit anchors before dispatch, reject
22
+ invalid or empty scopes explicitly, and keep repository metadata isolated from instructions
23
+ across foreground and background runs.
24
+ - **Parallel streamed tool calls are now correlated safely.** Interleaved argument chunks stay attached to their indexed calls, malformed or truncated call streams stop before tool execution, and failed attempts are not retried after output has already been shown.
25
+ - **Provider compatibility and Z.AI routing are now explicit.** Immutable compatibility profiles keep request-format quirks behind the chat-provider boundary, while independent Z.AI Coding Plan and API login routes use separate credentials, endpoints, model identities, catalog refresh, logout, and usage/rate-limit state. Curated GLM requests now apply exact context/output limits, thinking controls, reasoning replay, and tool-stream support without activating for local or unknown models.
26
+ - **Tool execution is now supervised as a terminal batch.** A private execution engine preserves the Toolset registry and legacy per-call API while centralizing ordered results, deduplication, callbacks, and batch summaries; cancellation is bounded, late work stays owned, and new batches fail closed until timed-out cleanup drains.
27
+
28
+ Upgrade with `pythinker update`, `pip install --upgrade pythinker-code==0.59.0`, or use the native installer for your platform from the [Releases page](https://github.com/Pythoughts-labs/pythinker-code/releases/latest).
29
+
18
30
  ## 0.58.0 (2026-07-11)
19
31
 
20
32
  - **Agent-spec loading is more defensive and truthful.** Subagent `path`, `extend`, and
@@ -13,7 +13,8 @@ ANTHROPIC_PLATFORM_ID = "anthropic"
13
13
  OPENROUTER_PLATFORM_ID = "openrouter"
14
14
  LM_STUDIO_PLATFORM_ID = "lm-studio"
15
15
  OLLAMA_PLATFORM_ID = "ollama"
16
- ZAI_PLATFORM_ID = "z-ai"
16
+ ZAI_CODING_PLATFORM_ID = "z-ai-coding"
17
+ ZAI_API_PLATFORM_ID = "z-ai-api"
17
18
 
18
19
  __all__ = [
19
20
  "ALIBABA_PLATFORM_ID",
@@ -29,5 +30,6 @@ __all__ = [
29
30
  "OPENCODE_GO_PLATFORM_ID",
30
31
  "OPENROUTER_PLATFORM_ID",
31
32
  "PYTHINKER_CODE_PLATFORM_ID",
32
- "ZAI_PLATFORM_ID",
33
+ "ZAI_API_PLATFORM_ID",
34
+ "ZAI_CODING_PLATFORM_ID",
33
35
  ]
@@ -250,8 +250,9 @@ async def refresh_managed_models(config: Config) -> bool:
250
250
  refresh_opencode_go_models,
251
251
  )
252
252
  from pythinker_code.auth.z_ai import (
253
- ZAI_PROVIDER_KEY,
254
- ZaiModel,
253
+ ZAI_ROUTES,
254
+ ZaiCatalogResult,
255
+ ZaiRoute,
255
256
  apply_z_ai_models,
256
257
  refresh_z_ai_models,
257
258
  )
@@ -264,16 +265,17 @@ async def refresh_managed_models(config: Config) -> bool:
264
265
 
265
266
  changed = False
266
267
  updates: list[tuple[str, str, list[ModelInfo]]] = []
268
+ z_ai_provider_keys = {route.provider_key for route in ZAI_ROUTES}
267
269
  oauth_manager = None
268
270
  for provider_key, provider in managed_providers.items():
269
271
  # OpenCode Go and MiniMax own provider-specific model discovery. The
270
272
  # generic `managed:<platform>` path can't express OpenCode Go's
271
273
  # two-provider split, and MiniMax's provider key intentionally includes
272
274
  # the wire-shape suffix (`managed:minimax-anthropic`).
273
- if provider_key in OPENCODE_GO_PROVIDER_KEYS or provider_key in (
274
- MINIMAX_ANTHROPIC_PROVIDER_KEY,
275
- ZAI_PROVIDER_KEY,
276
- KIMI_PROVIDER_KEY,
275
+ if (
276
+ provider_key in OPENCODE_GO_PROVIDER_KEYS
277
+ or provider_key in {MINIMAX_ANTHROPIC_PROVIDER_KEY, KIMI_PROVIDER_KEY}
278
+ or provider_key in z_ai_provider_keys
277
279
  ):
278
280
  continue
279
281
  platform_id = parse_managed_provider_key(provider_key)
@@ -430,13 +432,29 @@ async def refresh_managed_models(config: Config) -> bool:
430
432
  if minimax_models is not None and apply_minimax_models(config, minimax_models):
431
433
  changed = True
432
434
 
433
- z_ai_models: tuple[ZaiModel, ...] | None = None
434
- try:
435
- z_ai_models = await refresh_z_ai_models(config)
436
- except (aiohttp.ClientError, TimeoutError, ValueError) as exc:
437
- logger.warning("Failed to refresh Z AI models: {error}", error=exc)
438
- if z_ai_models is not None and apply_z_ai_models(config, z_ai_models):
439
- changed = True
435
+ z_ai_results: dict[ZaiRoute, ZaiCatalogResult] = {}
436
+ for route in ZAI_ROUTES:
437
+ try:
438
+ result = await refresh_z_ai_models(config, route)
439
+ except Exception as exc:
440
+ logger.warning(
441
+ "Unexpected Z.AI catalog refresh failure for {route}: {error_type}",
442
+ route=route.platform_id,
443
+ error_type=type(exc).__name__,
444
+ )
445
+ continue
446
+ z_ai_results[route] = result
447
+ if result.status == "live":
448
+ assert result.models is not None
449
+ if apply_z_ai_models(config, route, result.models):
450
+ changed = True
451
+ elif result.status != "unconfigured":
452
+ logger.warning(
453
+ "Z.AI catalog refresh did not update {route}: status={status}, failure={failure}",
454
+ route=route.platform_id,
455
+ status=result.status,
456
+ failure=result.failure,
457
+ )
440
458
 
441
459
  kimi_models: tuple[KimiModel, ...] | None = None
442
460
  try:
@@ -456,8 +474,12 @@ async def refresh_managed_models(config: Config) -> bool:
456
474
  save_changed = True
457
475
  if minimax_models is not None and apply_minimax_models(config_for_save, minimax_models):
458
476
  save_changed = True
459
- if z_ai_models is not None and apply_z_ai_models(config_for_save, z_ai_models):
460
- save_changed = True
477
+ for route, result in z_ai_results.items():
478
+ if result.status != "live":
479
+ continue
480
+ assert result.models is not None
481
+ if apply_z_ai_models(config_for_save, route, result.models):
482
+ save_changed = True
461
483
  if kimi_models is not None and apply_kimi_models(config_for_save, kimi_models):
462
484
  save_changed = True
463
485
  if save_changed: