specsmith 0.3.6.dev175__tar.gz → 0.3.6.dev177__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 (166) hide show
  1. {specsmith-0.3.6.dev175/src/specsmith.egg-info → specsmith-0.3.6.dev177}/PKG-INFO +1 -1
  2. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/pyproject.toml +1 -1
  3. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/agent/runner.py +35 -7
  4. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177/src/specsmith.egg-info}/PKG-INFO +1 -1
  5. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/LICENSE +0 -0
  6. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/README.md +0 -0
  7. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/setup.cfg +0 -0
  8. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/epistemic/__init__.py +0 -0
  9. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/epistemic/belief.py +0 -0
  10. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/epistemic/certainty.py +0 -0
  11. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/epistemic/failure_graph.py +0 -0
  12. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/epistemic/py.typed +0 -0
  13. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/epistemic/recovery.py +0 -0
  14. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/epistemic/session.py +0 -0
  15. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/epistemic/stress_tester.py +0 -0
  16. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/epistemic/trace.py +0 -0
  17. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/__init__.py +0 -0
  18. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/__main__.py +0 -0
  19. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/agent/__init__.py +0 -0
  20. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/agent/core.py +0 -0
  21. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/agent/hooks.py +0 -0
  22. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/agent/optimizer.py +0 -0
  23. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/agent/profiles/epistemic-auditor.md +0 -0
  24. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/agent/profiles/planner.md +0 -0
  25. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/agent/profiles/verifier.md +0 -0
  26. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/agent/providers/__init__.py +0 -0
  27. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/agent/providers/anthropic.py +0 -0
  28. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/agent/providers/gemini.py +0 -0
  29. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/agent/providers/mistral.py +0 -0
  30. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/agent/providers/ollama.py +0 -0
  31. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/agent/providers/openai.py +0 -0
  32. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/agent/skills.py +0 -0
  33. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/agent/tools.py +0 -0
  34. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/architect.py +0 -0
  35. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/auditor.py +0 -0
  36. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/auth.py +0 -0
  37. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/cli.py +0 -0
  38. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/commands/__init__.py +0 -0
  39. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/compressor.py +0 -0
  40. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/config.py +0 -0
  41. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/credit_analyzer.py +0 -0
  42. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/credits.py +0 -0
  43. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/differ.py +0 -0
  44. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/doctor.py +0 -0
  45. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/epistemic/__init__.py +0 -0
  46. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/epistemic/belief.py +0 -0
  47. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/epistemic/certainty.py +0 -0
  48. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/epistemic/failure_graph.py +0 -0
  49. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/epistemic/recovery.py +0 -0
  50. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/epistemic/stress_tester.py +0 -0
  51. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/executor.py +0 -0
  52. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/exporter.py +0 -0
  53. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/gui/__init__.py +0 -0
  54. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/gui/app.py +0 -0
  55. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/gui/main_window.py +0 -0
  56. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/gui/session_tab.py +0 -0
  57. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/gui/theme.py +0 -0
  58. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/gui/widgets/__init__.py +0 -0
  59. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/gui/widgets/chat_view.py +0 -0
  60. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/gui/widgets/input_bar.py +0 -0
  61. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/gui/widgets/provider_bar.py +0 -0
  62. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/gui/widgets/token_meter.py +0 -0
  63. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/gui/widgets/tool_panel.py +0 -0
  64. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/gui/widgets/update_checker.py +0 -0
  65. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/gui/worker.py +0 -0
  66. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/importer.py +0 -0
  67. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/integrations/__init__.py +0 -0
  68. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/integrations/aider.py +0 -0
  69. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/integrations/base.py +0 -0
  70. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/integrations/claude_code.py +0 -0
  71. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/integrations/copilot.py +0 -0
  72. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/integrations/cursor.py +0 -0
  73. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/integrations/gemini.py +0 -0
  74. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/integrations/warp.py +0 -0
  75. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/integrations/windsurf.py +0 -0
  76. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/languages.py +0 -0
  77. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/ledger.py +0 -0
  78. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/ollama_cmds.py +0 -0
  79. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/patent.py +0 -0
  80. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/phase.py +0 -0
  81. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/plugins.py +0 -0
  82. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/profiles.py +0 -0
  83. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/rate_limits.py +0 -0
  84. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/releaser.py +0 -0
  85. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/requirements.py +0 -0
  86. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/retrieval.py +0 -0
  87. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/scaffolder.py +0 -0
  88. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/session.py +0 -0
  89. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/agents.md.j2 +0 -0
  90. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/community/bug_report.md.j2 +0 -0
  91. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/community/code_of_conduct.md.j2 +0 -0
  92. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/community/contributing.md.j2 +0 -0
  93. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/community/feature_request.md.j2 +0 -0
  94. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/community/license-Apache-2.0.j2 +0 -0
  95. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/community/license-MIT.j2 +0 -0
  96. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/community/pull_request_template.md.j2 +0 -0
  97. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/community/security.md.j2 +0 -0
  98. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/docs/architecture.md.j2 +0 -0
  99. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/docs/mkdocs.yml.j2 +0 -0
  100. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/docs/readthedocs.yaml.j2 +0 -0
  101. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/docs/requirements.md.j2 +0 -0
  102. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/docs/test-spec.md.j2 +0 -0
  103. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/docs/workflow.md.j2 +0 -0
  104. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/editorconfig.j2 +0 -0
  105. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/gitattributes.j2 +0 -0
  106. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/gitignore.j2 +0 -0
  107. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/go/go.mod.j2 +0 -0
  108. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/go/main.go.j2 +0 -0
  109. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/governance/belief-registry.md.j2 +0 -0
  110. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/governance/context-budget.md.j2 +0 -0
  111. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/governance/drift-metrics.md.j2 +0 -0
  112. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/governance/epistemic-axioms.md.j2 +0 -0
  113. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/governance/failure-modes.md.j2 +0 -0
  114. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/governance/roles.md.j2 +0 -0
  115. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/governance/rules.md.j2 +0 -0
  116. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/governance/uncertainty-map.md.j2 +0 -0
  117. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/governance/verification.md.j2 +0 -0
  118. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/governance/workflow.md.j2 +0 -0
  119. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/js/package.json.j2 +0 -0
  120. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/ledger.md.j2 +0 -0
  121. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/python/cli.py.j2 +0 -0
  122. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/python/init.py.j2 +0 -0
  123. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/python/pyproject.toml.j2 +0 -0
  124. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/readme.md.j2 +0 -0
  125. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/rust/Cargo.toml.j2 +0 -0
  126. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/rust/main.rs.j2 +0 -0
  127. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/scripts/exec.cmd.j2 +0 -0
  128. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/scripts/exec.sh.j2 +0 -0
  129. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/scripts/run.cmd.j2 +0 -0
  130. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/scripts/run.sh.j2 +0 -0
  131. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/scripts/setup.cmd.j2 +0 -0
  132. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/scripts/setup.sh.j2 +0 -0
  133. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/templates/workflows/release.yml.j2 +0 -0
  134. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/tool_installer.py +0 -0
  135. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/toolrules.py +0 -0
  136. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/tools.py +0 -0
  137. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/trace.py +0 -0
  138. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/updater.py +0 -0
  139. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/upgrader.py +0 -0
  140. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/validator.py +0 -0
  141. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/vcs/__init__.py +0 -0
  142. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/vcs/base.py +0 -0
  143. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/vcs/bitbucket.py +0 -0
  144. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/vcs/github.py +0 -0
  145. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/vcs/gitlab.py +0 -0
  146. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/vcs_commands.py +0 -0
  147. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/wireframes.py +0 -0
  148. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith/workspace.py +0 -0
  149. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith.egg-info/SOURCES.txt +0 -0
  150. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith.egg-info/dependency_links.txt +0 -0
  151. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith.egg-info/entry_points.txt +0 -0
  152. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith.egg-info/requires.txt +0 -0
  153. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/src/specsmith.egg-info/top_level.txt +0 -0
  154. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/tests/test_auditor.py +0 -0
  155. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/tests/test_cli.py +0 -0
  156. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/tests/test_compressor.py +0 -0
  157. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/tests/test_epistemic.py +0 -0
  158. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/tests/test_importer.py +0 -0
  159. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/tests/test_integrations.py +0 -0
  160. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/tests/test_optimizer.py +0 -0
  161. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/tests/test_rate_limits.py +0 -0
  162. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/tests/test_scaffolder.py +0 -0
  163. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/tests/test_smoke.py +0 -0
  164. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/tests/test_tools.py +0 -0
  165. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/tests/test_validator.py +0 -0
  166. {specsmith-0.3.6.dev175 → specsmith-0.3.6.dev177}/tests/test_vcs.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: specsmith
3
- Version: 0.3.6.dev175
3
+ Version: 0.3.6.dev177
4
4
  Summary: Applied Epistemic Engineering toolkit — AEE agent sessions, execution profiles, FPGA/HDL governance, tool installer, 50+ CLI commands.
5
5
  Author: BitConcepts
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "specsmith"
7
- version = "0.3.6.dev175"
7
+ version = "0.3.6.dev177"
8
8
  description = "Applied Epistemic Engineering toolkit — AEE agent sessions, execution profiles, FPGA/HDL governance, tool installer, 50+ CLI commands."
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -480,6 +480,11 @@ class AgentRunner:
480
480
  # Add user message
481
481
  self._state.messages.append(Message(role=Role.USER, content=user_input))
482
482
 
483
+ # In json_events mode we defer the llm_chunk emission so we can run the
484
+ # language check BEFORE the UI sees the text. Without this, a Thai/Chinese
485
+ # response would be displayed even when the correction turn later succeeds.
486
+ _defer_emit = not silent and self._json_events
487
+
483
488
  final_response = ""
484
489
  for _iteration in range(self._max_iterations):
485
490
  messages_with_system = [
@@ -487,7 +492,9 @@ class AgentRunner:
487
492
  ] + self._state.messages
488
493
 
489
494
  try:
490
- response = self._call_provider(messages_with_system, silent=silent)
495
+ response = self._call_provider(
496
+ messages_with_system, silent=silent, defer_emit=_defer_emit
497
+ )
491
498
  except Exception as e: # noqa: BLE001
492
499
  error_msg = f"[Provider error] {e}"
493
500
  if not silent:
@@ -515,9 +522,12 @@ class AgentRunner:
515
522
  final_response = response.content
516
523
 
517
524
  if not response.has_tool_calls:
518
- # Non-English correction: if response appears to be in another language,
519
- # issue a single correction turn rather than showing the wrong-language response.
520
- if response.content and self._has_non_english(response.content) and _iteration == 0:
525
+ # Non-English correction: if the final response is in a non-English
526
+ # language, silently issue a correction turn instead of surfacing the
527
+ # bad text. _defer_emit ensures the UI never sees the Thai/Chinese
528
+ # content — we only emit llm_chunk once we have an English reply.
529
+ # The iteration limit acts as a natural loop-break (max_iterations).
530
+ if response.content and self._has_non_english(response.content):
521
531
  correction = (
522
532
  "[LANG:EN] CRITICAL: Your last response was in a non-English language. "
523
533
  "You MUST respond in English ONLY. Please re-answer in English."
@@ -526,12 +536,22 @@ class AgentRunner:
526
536
  Message(role=Role.ASSISTANT, content=response.content)
527
537
  )
528
538
  self._state.messages.append(Message(role=Role.USER, content=correction))
529
- # Continue the loop to get an English response
539
+ # Continue the loop to get an English response (don't emit bad content)
530
540
  continue
541
+ # Language OK — emit the deferred llm_chunk now
542
+ if _defer_emit and response.content:
543
+ self._emit_event(type="llm_chunk", text=response.content)
531
544
  # Final response — add to history
532
545
  self._state.messages.append(Message(role=Role.ASSISTANT, content=response.content))
533
546
  break
534
547
 
548
+ # Has tool calls — emit any deferred partial text (planning/thinking text
549
+ # that precedes the tool invocation), but only if it is in English.
550
+ # Some Qwen/DeepSeek variants emit Thai/Chinese thinking text before tool
551
+ # calls; silently drop that rather than surfacing it to the UI.
552
+ if _defer_emit and response.content and not self._has_non_english(response.content):
553
+ self._emit_event(type="llm_chunk", text=response.content)
554
+
535
555
  # Process tool calls
536
556
  self._hard_stop = False # reset before each batch
537
557
  tool_results = self._execute_tool_calls(response.tool_calls, silent=silent)
@@ -571,12 +591,20 @@ class AgentRunner:
571
591
 
572
592
  return final_response
573
593
 
574
- def _call_provider(self, messages: list[Message], silent: bool = False) -> CompletionResponse:
594
+ def _call_provider(
595
+ self,
596
+ messages: list[Message],
597
+ silent: bool = False,
598
+ defer_emit: bool = False,
599
+ ) -> CompletionResponse:
575
600
  """Call the LLM provider with optimization engine pre/post hooks.
576
601
 
577
602
  Streaming is disabled when tools are registered (streaming drops tool_call blocks).
578
603
  When an OptimizationEngine is active, pre_call() may return a cache hit
579
604
  or transform messages/model/tools before the actual provider call.
605
+
606
+ ``defer_emit=True`` suppresses the ``llm_chunk`` event so the caller can
607
+ validate the response (e.g. language check) before surfacing it to the UI.
580
608
  """
581
609
  provider: Any = self._provider
582
610
  tools = self._tools
@@ -613,7 +641,7 @@ class AgentRunner:
613
641
  response = CompletionResponse(content=accumulated, model=str(provider.model))
614
642
  else:
615
643
  response = cast(CompletionResponse, provider.complete(messages, tools=tools))
616
- if not silent and response.content:
644
+ if not silent and not defer_emit and response.content:
617
645
  if self._json_events:
618
646
  self._emit_event(type="llm_chunk", text=response.content)
619
647
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: specsmith
3
- Version: 0.3.6.dev175
3
+ Version: 0.3.6.dev177
4
4
  Summary: Applied Epistemic Engineering toolkit — AEE agent sessions, execution profiles, FPGA/HDL governance, tool installer, 50+ CLI commands.
5
5
  Author: BitConcepts
6
6
  License-Expression: MIT