toolang 0.2.2__tar.gz → 0.2.3__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 (205) hide show
  1. {toolang-0.2.2 → toolang-0.2.3}/PKG-INFO +1 -1
  2. {toolang-0.2.2 → toolang-0.2.3}/pyproject.toml +1 -1
  3. toolang-0.2.3/src/toolang/cli/logo.py +95 -0
  4. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/cli/toolang/app.py +0 -1
  5. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/cli/utils.py +8 -40
  6. {toolang-0.2.2 → toolang-0.2.3}/tests/test_cli.py +49 -5
  7. {toolang-0.2.2 → toolang-0.2.3}/uv.lock +1 -1
  8. toolang-0.2.2/src/toolang/cli/logo.py +0 -61
  9. {toolang-0.2.2 → toolang-0.2.3}/.github/workflows/publish-pypi.yml +0 -0
  10. {toolang-0.2.2 → toolang-0.2.3}/.gitignore +0 -0
  11. {toolang-0.2.2 → toolang-0.2.3}/AGENTS.md +0 -0
  12. {toolang-0.2.2 → toolang-0.2.3}/LICENSE +0 -0
  13. {toolang-0.2.2 → toolang-0.2.3}/README.md +0 -0
  14. {toolang-0.2.2 → toolang-0.2.3}/docs/api.md +0 -0
  15. {toolang-0.2.2 → toolang-0.2.3}/docs/caps.md +0 -0
  16. {toolang-0.2.2 → toolang-0.2.3}/docs/chat.md +0 -0
  17. {toolang-0.2.2 → toolang-0.2.3}/docs/concepts.md +0 -0
  18. {toolang-0.2.2 → toolang-0.2.3}/docs/execution.md +0 -0
  19. {toolang-0.2.2 → toolang-0.2.3}/docs/ids.md +0 -0
  20. {toolang-0.2.2 → toolang-0.2.3}/docs/index.md +0 -0
  21. {toolang-0.2.2 → toolang-0.2.3}/docs/layout.md +0 -0
  22. {toolang-0.2.2 → toolang-0.2.3}/docs/models.md +0 -0
  23. {toolang-0.2.2 → toolang-0.2.3}/docs/plugins.md +0 -0
  24. {toolang-0.2.2 → toolang-0.2.3}/docs/prepared-lock.md +0 -0
  25. {toolang-0.2.2 → toolang-0.2.3}/docs/program.md +0 -0
  26. {toolang-0.2.2 → toolang-0.2.3}/docs/selectors.md +0 -0
  27. {toolang-0.2.2 → toolang-0.2.3}/docs/tasks.md +0 -0
  28. {toolang-0.2.2 → toolang-0.2.3}/docs/tools.md +0 -0
  29. {toolang-0.2.2 → toolang-0.2.3}/docs/webui-jobs.md +0 -0
  30. {toolang-0.2.2 → toolang-0.2.3}/examples/alice.too +0 -0
  31. {toolang-0.2.2 → toolang-0.2.3}/examples/invoke-playground.too +0 -0
  32. {toolang-0.2.2 → toolang-0.2.3}/examples/invoke.fixed-model.too +0 -0
  33. {toolang-0.2.2 → toolang-0.2.3}/examples/invoke.openrouter-smoke.too +0 -0
  34. {toolang-0.2.2 → toolang-0.2.3}/examples/invoke.priority.too +0 -0
  35. {toolang-0.2.2 → toolang-0.2.3}/examples/invoke.simulated-history.memory.too +0 -0
  36. {toolang-0.2.2 → toolang-0.2.3}/examples/invoke.simulated-history.none.too +0 -0
  37. {toolang-0.2.2 → toolang-0.2.3}/reference/README.md +0 -0
  38. {toolang-0.2.2 → toolang-0.2.3}/reference/build.py +0 -0
  39. {toolang-0.2.2 → toolang-0.2.3}/reference/config.toml +0 -0
  40. {toolang-0.2.2 → toolang-0.2.3}/reference/templates/index.html.jinja2 +0 -0
  41. {toolang-0.2.2 → toolang-0.2.3}/reference/templates/module.html.jinja2 +0 -0
  42. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/__init__.py +0 -0
  43. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/agents.py +0 -0
  44. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/__init__.py +0 -0
  45. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/error.py +0 -0
  46. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/examples/__init__.py +0 -0
  47. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/examples/tools.py +0 -0
  48. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/protocols/__init__.py +0 -0
  49. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/protocols/channel.py +0 -0
  50. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/protocols/loop.py +0 -0
  51. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/protocols/model.py +0 -0
  52. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/protocols/sandbox.py +0 -0
  53. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/protocols/tool.py +0 -0
  54. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/types/__init__.py +0 -0
  55. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/types/channel.py +0 -0
  56. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/types/message.py +0 -0
  57. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/types/model.py +0 -0
  58. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/types/run.py +0 -0
  59. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/types/sandbox.py +0 -0
  60. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/types/tool.py +0 -0
  61. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/utils/__init__.py +0 -0
  62. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/utils/channels.py +0 -0
  63. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/utils/function_tools.py +0 -0
  64. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/utils/tools.py +0 -0
  65. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/base/utils/typer_tools.py +0 -0
  66. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/caps.py +0 -0
  67. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/channels/__init__.py +0 -0
  68. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/channels/telegram.py +0 -0
  69. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/cli/__init__.py +0 -0
  70. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/cli/__main__.py +0 -0
  71. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/cli/caps/__init__.py +0 -0
  72. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/cli/caps/__main__.py +0 -0
  73. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/cli/caps/app.py +0 -0
  74. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/cli/caps/commands.py +0 -0
  75. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/cli/invoke.py +0 -0
  76. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/cli/progress.py +0 -0
  77. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/cli/toolang/__init__.py +0 -0
  78. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/cli/toolang/__main__.py +0 -0
  79. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/cli/toolang/caps.py +0 -0
  80. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/cli/toolang/fmt.py +0 -0
  81. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/common/__init__.py +0 -0
  82. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/common/ids.py +0 -0
  83. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/common/progress.py +0 -0
  84. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/common/template.py +0 -0
  85. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/components/__init__.py +0 -0
  86. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/components/registry.py +0 -0
  87. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/components/router/__init__.py +0 -0
  88. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/components/router/_streaming.py +0 -0
  89. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/components/router/chat.py +0 -0
  90. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/components/router/inspect/__init__.py +0 -0
  91. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/components/router/inspect/_shared.py +0 -0
  92. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/components/router/inspect/agent.py +0 -0
  93. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/components/router/inspect/caps.py +0 -0
  94. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/components/router/inspect/execution.py +0 -0
  95. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/components/router/inspect/jobs.py +0 -0
  96. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/components/router/inspect/router.py +0 -0
  97. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/components/router/manage/__init__.py +0 -0
  98. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/components/router/manage/caps.py +0 -0
  99. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/components/router/manage/jobs.py +0 -0
  100. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/components/router/manage/router.py +0 -0
  101. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/components/runner/__init__.py +0 -0
  102. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/components/trigger/__init__.py +0 -0
  103. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/components/trigger/poll.py +0 -0
  104. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/components/trigger/pulse.py +0 -0
  105. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/components/trigger/watch.py +0 -0
  106. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/config/__init__.py +0 -0
  107. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/config/env.py +0 -0
  108. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/config/log.py +0 -0
  109. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/config/log_spec.py +0 -0
  110. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/config/plugins.py +0 -0
  111. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/config/web.py +0 -0
  112. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/execution/__init__.py +0 -0
  113. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/execution/assembly.py +0 -0
  114. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/execution/binding.py +0 -0
  115. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/execution/context.py +0 -0
  116. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/execution/db.py +0 -0
  117. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/execution/detail.py +0 -0
  118. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/execution/effective.py +0 -0
  119. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/execution/events.py +0 -0
  120. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/execution/execute.py +0 -0
  121. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/execution/input.py +0 -0
  122. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/execution/model.py +0 -0
  123. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/execution/model_call.py +0 -0
  124. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/execution/prompts/__init__.py +0 -0
  125. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/execution/prompts/context.default.md +0 -0
  126. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/execution/prompts/instruct.default.md +0 -0
  127. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/execution/records.py +0 -0
  128. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/execution/response.py +0 -0
  129. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/execution/runner.py +0 -0
  130. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/execution/stream.py +0 -0
  131. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/loops/__init__.py +0 -0
  132. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/loops/basic.py +0 -0
  133. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/models/__init__.py +0 -0
  134. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/models/adapters/__init__.py +0 -0
  135. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/models/adapters/chat_completions.py +0 -0
  136. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/models/adapters/responses.py +0 -0
  137. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/models/config.py +0 -0
  138. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/models/discovery.py +0 -0
  139. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/models/errors.py +0 -0
  140. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/models/providers/__init__.py +0 -0
  141. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/models/providers/custom.py +0 -0
  142. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/models/providers/deepseek.py +0 -0
  143. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/models/providers/google.py +0 -0
  144. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/models/providers/ollama.py +0 -0
  145. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/models/providers/openai.py +0 -0
  146. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/models/providers/openrouter.py +0 -0
  147. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/models/resolution.py +0 -0
  148. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/models/views.py +0 -0
  149. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/plugin.py +0 -0
  150. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/program.py +0 -0
  151. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/program_format.py +0 -0
  152. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/sandboxes/__init__.py +0 -0
  153. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/sandboxes/docker.py +0 -0
  154. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/sandboxes/none.py +0 -0
  155. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/selectors.py +0 -0
  156. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/state/__init__.py +0 -0
  157. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/state/durable.py +0 -0
  158. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/state/live.py +0 -0
  159. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/state/prepared.py +0 -0
  160. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/state/program.py +0 -0
  161. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/state/pulse.py +0 -0
  162. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/templates/__init__.py +0 -0
  163. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/templates/agent.default.too +0 -0
  164. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/templates/chore.default.md +0 -0
  165. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/templates/prompt.default.md +0 -0
  166. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/templates/psyche.default.md +0 -0
  167. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/templates/service.default.md +0 -0
  168. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/templates/service.stdio.md +0 -0
  169. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/templates/skill.default.md +0 -0
  170. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/templates/task.default.md +0 -0
  171. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/tools/__init__.py +0 -0
  172. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/tools/agent_chat.py +0 -0
  173. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/tools/agent_state.py +0 -0
  174. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/tools/filesystem.py +0 -0
  175. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/tools/registry.py +0 -0
  176. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/tools/service_use.py +0 -0
  177. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/tools/shell.py +0 -0
  178. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/tools/views.py +0 -0
  179. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/tools/web_search.py +0 -0
  180. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/up.py +0 -0
  181. {toolang-0.2.2 → toolang-0.2.3}/src/toolang/work.py +0 -0
  182. {toolang-0.2.2 → toolang-0.2.3}/syntax.too +0 -0
  183. {toolang-0.2.2 → toolang-0.2.3}/tests/fixtures/remote-prompt/rewrite.md +0 -0
  184. {toolang-0.2.2 → toolang-0.2.3}/tests/fixtures/remote-psyche/reviewer.md +0 -0
  185. {toolang-0.2.2 → toolang-0.2.3}/tests/fixtures/remote-service/github.md +0 -0
  186. {toolang-0.2.2 → toolang-0.2.3}/tests/fixtures/remote-skill/pdf-processing/SKILL.md +0 -0
  187. {toolang-0.2.2 → toolang-0.2.3}/tests/fixtures/remote-skill/pdf-processing/assets/template.md +0 -0
  188. {toolang-0.2.2 → toolang-0.2.3}/tests/fixtures/sample.too +0 -0
  189. {toolang-0.2.2 → toolang-0.2.3}/tests/fixtures/source_only.too +0 -0
  190. {toolang-0.2.2 → toolang-0.2.3}/tests/test_agent_state_tool.py +0 -0
  191. {toolang-0.2.2 → toolang-0.2.3}/tests/test_channels.py +0 -0
  192. {toolang-0.2.2 → toolang-0.2.3}/tests/test_execution_template.py +0 -0
  193. {toolang-0.2.2 → toolang-0.2.3}/tests/test_ids.py +0 -0
  194. {toolang-0.2.2 → toolang-0.2.3}/tests/test_log_config.py +0 -0
  195. {toolang-0.2.2 → toolang-0.2.3}/tests/test_models.py +0 -0
  196. {toolang-0.2.2 → toolang-0.2.3}/tests/test_plugin_tools.py +0 -0
  197. {toolang-0.2.2 → toolang-0.2.3}/tests/test_prepared.py +0 -0
  198. {toolang-0.2.2 → toolang-0.2.3}/tests/test_program.py +0 -0
  199. {toolang-0.2.2 → toolang-0.2.3}/tests/test_program_format.py +0 -0
  200. {toolang-0.2.2 → toolang-0.2.3}/tests/test_run_queue_runner.py +0 -0
  201. {toolang-0.2.2 → toolang-0.2.3}/tests/test_sandboxes.py +0 -0
  202. {toolang-0.2.2 → toolang-0.2.3}/tests/test_selectors.py +0 -0
  203. {toolang-0.2.2 → toolang-0.2.3}/tests/test_tools.py +0 -0
  204. {toolang-0.2.2 → toolang-0.2.3}/tests/test_typer_tools.py +0 -0
  205. {toolang-0.2.2 → toolang-0.2.3}/tests/test_work.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: toolang
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: A programming language and runtime for agents
5
5
  Project-URL: Homepage, https://toolang.ai/
6
6
  Project-URL: Documentation, https://toolang.ai/docs
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "toolang"
7
- version = "0.2.2"
7
+ version = "0.2.3"
8
8
  description = "A programming language and runtime for agents"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -0,0 +1,95 @@
1
+ """CLI logo and color palette constants."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from rich.text import Text
6
+
7
+ INFO_AVATAR_TEXT = """
8
+ ██████████ ████
9
+ ▀▀▀████▀▀▀ ████
10
+ ████ ▄▄▄▄ ▄▄▄▄ ████
11
+ ████ ████ ████ ████
12
+ ████ ▀▀▀▀ ▀▀▀▀ ████
13
+ ████ ▄▄▄▄████
14
+ ████ ████████
15
+ """.strip("\n")
16
+
17
+ INFO_AVATAR_MARGIN = " "
18
+
19
+ INFO_PALETTE_COLORS = (
20
+ (
21
+ "63c74d",
22
+ "9edb49",
23
+ "f4d35e",
24
+ "f39c12",
25
+ "f45b69",
26
+ "ff66c4",
27
+ "c77dff",
28
+ "8e7dff",
29
+ "5b8cff",
30
+ "4cc9f0",
31
+ "43d9bd",
32
+ ),
33
+ (
34
+ "4fb03d",
35
+ "89c93b",
36
+ "e6c24f",
37
+ "de8a0d",
38
+ "de4a58",
39
+ "f055b5",
40
+ "b56aed",
41
+ "7b6cf0",
42
+ "4b79ee",
43
+ "3cb7de",
44
+ "36c4aa",
45
+ ),
46
+ )
47
+
48
+
49
+ def info_avatar() -> Text:
50
+ """Return the styled CLI info avatar art."""
51
+
52
+ return _rainbow_text(info_avatar_text())
53
+
54
+
55
+ def info_avatar_text() -> str:
56
+ """Return the plain CLI info avatar art."""
57
+
58
+ return _with_line_margin(INFO_AVATAR_TEXT, margin=INFO_AVATAR_MARGIN)
59
+
60
+
61
+ def info_palette() -> Text:
62
+ """Return the styled two-row CLI info palette."""
63
+
64
+ top, bottom = INFO_PALETTE_COLORS
65
+ palette = Text()
66
+ for style in _color_row_styles(top):
67
+ palette.append("██", style=style)
68
+ palette.append("\n")
69
+ for style in _color_row_styles(bottom):
70
+ palette.append("██", style=style)
71
+ return palette
72
+
73
+
74
+ def _rainbow_text(text: str) -> Text:
75
+ rainbow_styles = _color_row_styles(INFO_PALETTE_COLORS[0])
76
+ styled = Text()
77
+ for row, line in enumerate(text.splitlines()):
78
+ for column, char in enumerate(line):
79
+ if char == " ":
80
+ styled.append(char)
81
+ continue
82
+ style_index = (column + (row * 2)) % len(rainbow_styles)
83
+ styled.append(char, style=rainbow_styles[style_index])
84
+ styled.append("\n")
85
+ if styled.plain.endswith("\n"):
86
+ styled = styled[:-1]
87
+ return styled
88
+
89
+
90
+ def _with_line_margin(text: str, *, margin: str) -> str:
91
+ return "\n".join(f"{margin}{line}{margin}" for line in text.splitlines())
92
+
93
+
94
+ def _color_row_styles(colors: tuple[str, ...]) -> tuple[str, ...]:
95
+ return tuple(f"bold #{color}" for color in colors)
@@ -420,7 +420,6 @@ def info_agent(
420
420
  rows.append(("WebUI", status.webui_url))
421
421
  if status.status == "running" and started_at != "-":
422
422
  rows.append(("Started", started_at))
423
- rows.append(("Created", created_at))
424
423
  if status.status != "running" and updated_at != "-":
425
424
  rows.append(("Updated", updated_at))
426
425
  if status.status != "running" and message != "-":
@@ -21,7 +21,7 @@ from typer.core import TyperArgument, TyperCommand, TyperGroup
21
21
 
22
22
  from .. import agents
23
23
  from ..base.error import ToolangError
24
- from .logo import info_avatar, info_palette_styles
24
+ from .logo import info_avatar, info_palette
25
25
 
26
26
  if TYPE_CHECKING:
27
27
  from ..execution.records import UpdateKind
@@ -32,24 +32,16 @@ setattr(typer_rich_utils, "STYLE_HELPTEXT", "")
32
32
  _TABLE_CONSOLE = Console(highlight=False, width=4096)
33
33
  _INFO_CONSOLE = Console(highlight=False)
34
34
  TableJustify = Literal["default", "left", "center", "right", "full"]
35
- _AGENT_AVATAR_CACHE: str | None = None
36
- _PALETTE_STYLES_CACHE: tuple[tuple[str, ...], tuple[str, ...]] | None = None
35
+ _AGENT_AVATAR_CACHE: Text | None = None
37
36
 
38
37
 
39
- def _agent_avatar() -> str:
38
+ def _agent_avatar() -> Text:
40
39
  global _AGENT_AVATAR_CACHE
41
40
  if _AGENT_AVATAR_CACHE is None:
42
41
  _AGENT_AVATAR_CACHE = info_avatar()
43
42
  return _AGENT_AVATAR_CACHE
44
43
 
45
44
 
46
- def _palette_styles() -> tuple[tuple[str, ...], tuple[str, ...]]:
47
- global _PALETTE_STYLES_CACHE
48
- if _PALETTE_STYLES_CACHE is None:
49
- _PALETTE_STYLES_CACHE = info_palette_styles()
50
- return _PALETTE_STYLES_CACHE
51
-
52
-
53
45
  class _PrefixAgentCommand(TyperCommand):
54
46
  """Render one virtual prefix-agent argument in help output."""
55
47
 
@@ -401,7 +393,7 @@ def _echo_table(
401
393
  def _echo_pairs_table(
402
394
  rows: Sequence[tuple[str, str]],
403
395
  *,
404
- avatar: str | None = None,
396
+ avatar: Text | str | None = None,
405
397
  title: str | None = None,
406
398
  ) -> None:
407
399
  table = Table(
@@ -424,9 +416,10 @@ def _echo_pairs_table(
424
416
  _INFO_CONSOLE.print(_info_title_block(title))
425
417
  _INFO_CONSOLE.print(table)
426
418
  else:
427
- avatar_text = _rainbow_avatar_text(avatar)
419
+ avatar_text = avatar if isinstance(avatar, Text) else Text(avatar)
428
420
  if _INFO_CONSOLE.width < 100:
429
421
  _INFO_CONSOLE.print(avatar_text)
422
+ _INFO_CONSOLE.print(Text(""))
430
423
  if title is not None:
431
424
  _INFO_CONSOLE.print(_info_title_block(title))
432
425
  _INFO_CONSOLE.print(table)
@@ -439,8 +432,7 @@ def _echo_pairs_table(
439
432
  right = Table.grid(padding=(0, 0))
440
433
  right.add_column(no_wrap=False)
441
434
  if title is not None:
442
- right.add_row(_info_title_block(title))
443
- avatar_text = _rainbow_avatar_text("\n" + avatar)
435
+ layout.add_row(Text(""), _info_title_block(title))
444
436
  right.add_row(table)
445
437
  right.add_row(Text(""))
446
438
  right.add_row(_palette_block())
@@ -454,23 +446,6 @@ def _styled_info_value(key: str, value: str) -> Text:
454
446
  return Text(value)
455
447
 
456
448
 
457
- def _rainbow_avatar_text(avatar: str) -> Text:
458
- rainbow_styles = _palette_styles()[0]
459
- lines = avatar.splitlines()
460
- text = Text()
461
- for row, line in enumerate(lines):
462
- for column, char in enumerate(line):
463
- if char == " ":
464
- text.append(char)
465
- continue
466
- style_index = (column + (row * 2)) % len(rainbow_styles)
467
- text.append(char, style=rainbow_styles[style_index])
468
- text.append("\n")
469
- if text.plain.endswith("\n"):
470
- text = text[:-1]
471
- return text
472
-
473
-
474
449
  def _info_title_block(title: str) -> Table:
475
450
  block = Table.grid(padding=(0, 0))
476
451
  block.add_column(no_wrap=False)
@@ -480,14 +455,7 @@ def _info_title_block(title: str) -> Table:
480
455
 
481
456
 
482
457
  def _palette_block() -> Text:
483
- top_styles, bottom_styles = _palette_styles()
484
- palette = Text()
485
- for style in top_styles:
486
- palette.append("██", style=style)
487
- palette.append("\n")
488
- for style in bottom_styles:
489
- palette.append("██", style=style)
490
- return palette
458
+ return info_palette()
491
459
 
492
460
 
493
461
  def _runtime_value(value: object) -> str:
@@ -20,6 +20,7 @@ from toolang.base.types.tool import ToolContext, ToolDefinition
20
20
  import toolang.cli.toolang.app as cli
21
21
  import toolang.cli.caps.app as caps_cli
22
22
  import toolang.cli.caps.commands as caps_commands
23
+ import toolang.cli.logo as cli_logo
23
24
  import toolang.cli.utils as cli_utils
24
25
  from toolang.cli.progress import CliProgress
25
26
  from toolang.components.trigger import watch
@@ -2725,11 +2726,12 @@ def test_cli_info_shows_agent_details(tmp_path: Path, monkeypatch) -> None:
2725
2726
  )
2726
2727
 
2727
2728
  assert result.exit_code == 0
2728
- assert "▄▄▄▄▄▄▄▄▄" in result.stdout
2729
+ assert "██████████" in result.stdout
2730
+ assert "████" in result.stdout
2729
2731
  assert "alice" in result.stdout
2730
2732
  assert "-----" in result.stdout
2731
2733
  assert "Home" in result.stdout
2732
- assert result.stdout.index("▄▄▄▄▄▄▄▄▄") < result.stdout.index("ALICE") < result.stdout.index("Home")
2734
+ assert result.stdout.index("██████████") < result.stdout.index("ALICE") < result.stdout.index("Home")
2733
2735
  assert str(toolang_root / "agents" / "alice") in "".join(result.stdout.split())
2734
2736
  assert "ROOM" not in result.stdout
2735
2737
  assert "PROGRAM" not in result.stdout
@@ -2759,7 +2761,7 @@ def test_cli_info_shows_agent_details(tmp_path: Path, monkeypatch) -> None:
2759
2761
  assert str(os.getpid()) in result.stdout
2760
2762
  assert "Started" in result.stdout
2761
2763
  assert "2026-04-07T11:00:00Z" in result.stdout
2762
- assert "Created" in result.stdout
2764
+ assert "Created" not in result.stdout
2763
2765
  assert "ONLINE" not in result.stdout
2764
2766
  assert "ENDPOINT" not in result.stdout
2765
2767
  assert "API" in result.stdout
@@ -2770,7 +2772,6 @@ def test_cli_info_shows_agent_details(tmp_path: Path, monkeypatch) -> None:
2770
2772
  assert "Updated" not in result.stdout
2771
2773
  assert result.stdout.index("PID") < result.stdout.index("API")
2772
2774
  assert result.stdout.index("WebUI") < result.stdout.index("Started")
2773
- assert result.stdout.index("Started") < result.stdout.index("Created")
2774
2775
 
2775
2776
 
2776
2777
  def test_cli_info_console_uses_terminal_width(monkeypatch) -> None:
@@ -2779,6 +2780,49 @@ def test_cli_info_console_uses_terminal_width(monkeypatch) -> None:
2779
2780
  assert cli_utils._INFO_CONSOLE.width == 72
2780
2781
 
2781
2782
 
2783
+ def test_cli_info_narrow_layout_separates_avatar_from_table(monkeypatch) -> None:
2784
+ output = io.StringIO()
2785
+ console = cli_utils.Console(file=output, width=80, highlight=False, color_system=None)
2786
+ monkeypatch.setattr(cli_utils, "_INFO_CONSOLE", console)
2787
+
2788
+ cli_utils._echo_pairs_table([("Home", "x")], avatar="AA\nBB", title="DEV")
2789
+
2790
+ assert output.getvalue().startswith("AA\nBB\n\nDEV\n---\nHome x")
2791
+
2792
+
2793
+ def test_cli_info_wide_layout_aligns_avatar_with_table(monkeypatch) -> None:
2794
+ output = io.StringIO()
2795
+ console = cli_utils.Console(file=output, width=120, highlight=False, color_system=None)
2796
+ monkeypatch.setattr(cli_utils, "_INFO_CONSOLE", console)
2797
+
2798
+ cli_utils._echo_pairs_table([("Home", "x"), ("Caps", "y")], avatar="AA\nBB", title="DEV")
2799
+
2800
+ assert "AA Home x" in output.getvalue()
2801
+
2802
+
2803
+ def test_cli_info_avatar_uses_rainbow_style() -> None:
2804
+ avatar = cli_logo._rainbow_text(" A\nB ")
2805
+
2806
+ assert avatar.plain == " A\nB "
2807
+ assert avatar.style == ""
2808
+ assert [(span.start, span.end, span.style) for span in avatar.spans] == [
2809
+ (1, 2, "bold #9edb49"),
2810
+ (3, 4, "bold #f4d35e"),
2811
+ ]
2812
+
2813
+
2814
+ def test_cli_info_avatar_matches_logo_proportions() -> None:
2815
+ avatar = cli_utils._agent_avatar().plain
2816
+ lines = avatar.splitlines()
2817
+
2818
+ assert len(lines) == 7
2819
+ assert {len(line) for line in lines} == {36}
2820
+ assert lines[0].startswith(" ██████████")
2821
+ assert lines[0].endswith("████ ")
2822
+ assert "▄▄▄▄ ▄▄▄▄" in avatar
2823
+ assert "▄▄▄▄████" in avatar
2824
+
2825
+
2782
2826
  def test_cli_info_reads_cap_counts_from_prepared_locks(tmp_path: Path, monkeypatch) -> None:
2783
2827
  from toolang.state.prepared import write_prepared_lock
2784
2828
 
@@ -2886,7 +2930,7 @@ def test_cli_info_for_stopped_agent_shows_created_only(tmp_path: Path) -> None:
2886
2930
  )
2887
2931
 
2888
2932
  assert result.exit_code == 0
2889
- assert "▄▄▄▄▄▄▄▄▄" in result.stdout
2933
+ assert "██████████" in result.stdout
2890
2934
  assert "Status" in result.stdout
2891
2935
  assert "AGENT" not in result.stdout
2892
2936
  assert "stopped" in result.stdout
@@ -1729,7 +1729,7 @@ wheels = [
1729
1729
 
1730
1730
  [[package]]
1731
1731
  name = "toolang"
1732
- version = "0.2.2"
1732
+ version = "0.2.3"
1733
1733
  source = { editable = "." }
1734
1734
  dependencies = [
1735
1735
  { name = "dataclasses-json" },
@@ -1,61 +0,0 @@
1
- """CLI logo and color palette constants."""
2
-
3
- from __future__ import annotations
4
-
5
- INFO_AVATAR_LINES = (
6
- " ",
7
- " ▄▄▄▄▄▄▄▄▄ ▄▄▄ ",
8
- " ▀▀▀███▀▀▀ ███ ",
9
- " ███ ███ ",
10
- " ███ ███ ███ ███ ",
11
- " ███ ▀▀▀ ▀▀▀ ███ ",
12
- " ███ ▄▄▄▄▄███ ",
13
- " ▀▀▀ ▀▀▀▀▀▀▀▀ ",
14
- " ",
15
- )
16
-
17
- INFO_PALETTE_HEX_ROWS = (
18
- (
19
- "63c74d",
20
- "9edb49",
21
- "f4d35e",
22
- "f39c12",
23
- "f45b69",
24
- "ff66c4",
25
- "c77dff",
26
- "8e7dff",
27
- "5b8cff",
28
- "4cc9f0",
29
- "43d9bd",
30
- ),
31
- (
32
- "4fb03d",
33
- "89c93b",
34
- "e6c24f",
35
- "de8a0d",
36
- "de4a58",
37
- "f055b5",
38
- "b56aed",
39
- "7b6cf0",
40
- "4b79ee",
41
- "3cb7de",
42
- "36c4aa",
43
- ),
44
- )
45
-
46
-
47
- def info_avatar() -> str:
48
- """Return the CLI info avatar art."""
49
-
50
- return "\n".join(INFO_AVATAR_LINES)
51
-
52
-
53
- def info_palette_styles() -> tuple[tuple[str, ...], tuple[str, ...]]:
54
- """Return the two-row CLI info palette as Rich styles."""
55
-
56
- top, bottom = INFO_PALETTE_HEX_ROWS
57
- return _palette_style_row(top), _palette_style_row(bottom)
58
-
59
-
60
- def _palette_style_row(row: tuple[str, ...]) -> tuple[str, ...]:
61
- return tuple(f"bold #{token}" for token in row)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes